aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe/aoecmd.c
diff options
context:
space:
mode:
authorEd L. Cashin <ecashin@coraid.com>2008-02-08 07:20:00 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 12:22:31 -0500
commit68e0d42f39d85b334d3867a4e5fc2e0e775c1a6c (patch)
treef4cdb47157de4dace5b99e69fc39ea017495922e /drivers/block/aoe/aoecmd.c
parent8911ef4dc97f77797f297318010a7424300d2d50 (diff)
aoe: handle multiple network paths to AoE device
A remote AoE device is something can process ATA commands and is identified by an AoE shelf number and an AoE slot number. Such a device might have more than one network interface, and it might be reachable by more than one local network interface. This patch tracks the available network paths available to each AoE device, allowing them to be used more efficiently. Andrew Morton asked about the call to msleep_interruptible in the revalidate function. Yes, if a signal is pending, then msleep_interruptible will not return 0. That means we will not loop but will call aoenet_xmit with a NULL skb, which is a noop. If the system is too low on memory or the aoe driver is too low on frames, then the user can hit control-C to interrupt the attempt to do a revalidate. I have added a comment to the code summarizing that. Andrew Morton asked whether the allocation performed inside addtgt could use a more relaxed allocation like GFP_KERNEL, but addtgt is called when the aoedev lock has been locked with spin_lock_irqsave. It would be nice to allocate the memory under fewer restrictions, but targets are only added when the device is being discovered, and if the target can't be added right now, we can try again in a minute when then next AoE config query broadcast goes out. Andrew Morton pointed out that the "too many targets" message could be printed for failing GFP_ATOMIC allocations. The last patch in this series makes the messages more specific. Signed-off-by: Ed L. Cashin <ecashin@coraid.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block/aoe/aoecmd.c')
-rw-r--r--drivers/block/aoe/aoecmd.c675
1 files changed, 460 insertions, 215 deletions
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 4d59d5057734..5e7daa1ff6f6 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -9,19 +9,16 @@
9#include <linux/skbuff.h> 9#include <linux/skbuff.h>
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/genhd.h> 11#include <linux/genhd.h>
12#include <linux/moduleparam.h>
12#include <net/net_namespace.h> 13#include <net/net_namespace.h>
13#include <asm/unaligned.h> 14#include <asm/unaligned.h>
14#include "aoe.h" 15#include "aoe.h"
15 16
16#define TIMERTICK (HZ / 10)
17#define MINTIMER (2 * TIMERTICK)
18#define MAXTIMER (HZ << 1)
19
20static int aoe_deadsecs = 60 * 3; 17static int aoe_deadsecs = 60 * 3;
21module_param(aoe_deadsecs, int, 0644); 18module_param(aoe_deadsecs, int, 0644);
22MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev."); 19MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
23 20
24struct sk_buff * 21static struct sk_buff *
25new_skb(ulong len) 22new_skb(ulong len)
26{ 23{
27 struct sk_buff *skb; 24 struct sk_buff *skb;
@@ -43,12 +40,12 @@ new_skb(ulong len)
43} 40}
44 41
45static struct frame * 42static struct frame *
46getframe(struct aoedev *d, int tag) 43getframe(struct aoetgt *t, int tag)
47{ 44{
48 struct frame *f, *e; 45 struct frame *f, *e;
49 46
50 f = d->frames; 47 f = t->frames;
51 e = f + d->nframes; 48 e = f + t->nframes;
52 for (; f<e; f++) 49 for (; f<e; f++)
53 if (f->tag == tag) 50 if (f->tag == tag)
54 return f; 51 return f;
@@ -61,21 +58,21 @@ getframe(struct aoedev *d, int tag)
61 * This driver reserves tag -1 to mean "unused frame." 58 * This driver reserves tag -1 to mean "unused frame."
62 */ 59 */
63static int 60static int
64newtag(struct aoedev *d) 61newtag(struct aoetgt *t)
65{ 62{
66 register ulong n; 63 register ulong n;
67 64
68 n = jiffies & 0xffff; 65 n = jiffies & 0xffff;
69 return n |= (++d->lasttag & 0x7fff) << 16; 66 return n |= (++t->lasttag & 0x7fff) << 16;
70} 67}
71 68
72static int 69static int
73aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h) 70aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
74{ 71{
75 u32 host_tag = newtag(d); 72 u32 host_tag = newtag(t);
76 73
77 memcpy(h->src, d->ifp->dev_addr, sizeof h->src); 74 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
78 memcpy(h->dst, d->addr, sizeof h->dst); 75 memcpy(h->dst, t->addr, sizeof h->dst);
79 h->type = __constant_cpu_to_be16(ETH_P_AOE); 76 h->type = __constant_cpu_to_be16(ETH_P_AOE);
80 h->verfl = AOE_HVER; 77 h->verfl = AOE_HVER;
81 h->major = cpu_to_be16(d->aoemajor); 78 h->major = cpu_to_be16(d->aoemajor);
@@ -98,42 +95,103 @@ put_lba(struct aoe_atahdr *ah, sector_t lba)
98} 95}
99 96
100static void 97static void
101aoecmd_ata_rw(struct aoedev *d, struct frame *f) 98ifrotate(struct aoetgt *t)
99{
100 t->ifp++;
101 if (t->ifp >= &t->ifs[NAOEIFS] || t->ifp->nd == NULL)
102 t->ifp = t->ifs;
103 if (t->ifp->nd == NULL) {
104 printk(KERN_INFO "aoe: no interface to rotate to\n");
105 BUG();
106 }
107}
108
109static struct frame *
110freeframe(struct aoedev *d)
102{ 111{
112 struct frame *f, *e;
113 struct aoetgt **t;
114 ulong n;
115
116 if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */
117 printk(KERN_ERR "aoe: NULL TARGETS!\n");
118 return NULL;
119 }
120 t = d->targets;
121 do {
122 if (t != d->htgt
123 && (*t)->ifp->nd
124 && (*t)->nout < (*t)->maxout) {
125 n = (*t)->nframes;
126 f = (*t)->frames;
127 e = f + n;
128 for (; f < e; f++) {
129 if (f->tag != FREETAG)
130 continue;
131 if (atomic_read(&skb_shinfo(f->skb)->dataref)
132 != 1) {
133 n--;
134 continue;
135 }
136 skb_shinfo(f->skb)->nr_frags = 0;
137 f->skb->data_len = 0;
138 skb_trim(f->skb, 0);
139 d->tgt = t;
140 ifrotate(*t);
141 return f;
142 }
143 if (n == 0) /* slow polling network card */
144 d->flags |= DEVFL_KICKME;
145 }
146 t++;
147 } while (t < &d->targets[NTARGETS] && *t);
148 return NULL;
149}
150
151static int
152aoecmd_ata_rw(struct aoedev *d)
153{
154 struct frame *f;
103 struct aoe_hdr *h; 155 struct aoe_hdr *h;
104 struct aoe_atahdr *ah; 156 struct aoe_atahdr *ah;
105 struct buf *buf; 157 struct buf *buf;
158 struct bio_vec *bv;
159 struct aoetgt *t;
106 struct sk_buff *skb; 160 struct sk_buff *skb;
107 ulong bcnt; 161 ulong bcnt;
108 register sector_t sector;
109 char writebit, extbit; 162 char writebit, extbit;
110 163
111 writebit = 0x10; 164 writebit = 0x10;
112 extbit = 0x4; 165 extbit = 0x4;
113 166
167 f = freeframe(d);
168 if (f == NULL)
169 return 0;
170 t = *d->tgt;
114 buf = d->inprocess; 171 buf = d->inprocess;
115 172 bv = buf->bv;
116 sector = buf->sector; 173 bcnt = t->ifp->maxbcnt;
117 bcnt = buf->bv_resid; 174 if (bcnt == 0)
118 if (bcnt > d->maxbcnt) 175 bcnt = DEFAULTBCNT;
119 bcnt = d->maxbcnt; 176 if (bcnt > buf->bv_resid)
120 177 bcnt = buf->bv_resid;
121 /* initialize the headers & frame */ 178 /* initialize the headers & frame */
122 skb = f->skb; 179 skb = f->skb;
123 h = (struct aoe_hdr *) skb_mac_header(skb); 180 h = (struct aoe_hdr *) skb_mac_header(skb);
124 ah = (struct aoe_atahdr *) (h+1); 181 ah = (struct aoe_atahdr *) (h+1);
125 skb_put(skb, sizeof *h + sizeof *ah); 182 skb_put(skb, sizeof *h + sizeof *ah);
126 memset(h, 0, skb->len); 183 memset(h, 0, skb->len);
127 f->tag = aoehdr_atainit(d, h); 184 f->tag = aoehdr_atainit(d, t, h);
185 t->nout++;
128 f->waited = 0; 186 f->waited = 0;
129 f->buf = buf; 187 f->buf = buf;
130 f->bufaddr = buf->bufaddr; 188 f->bufaddr = page_address(bv->bv_page) + buf->bv_off;
131 f->bcnt = bcnt; 189 f->bcnt = bcnt;
132 f->lba = sector; 190 f->lba = buf->sector;
133 191
134 /* set up ata header */ 192 /* set up ata header */
135 ah->scnt = bcnt >> 9; 193 ah->scnt = bcnt >> 9;
136 put_lba(ah, sector); 194 put_lba(ah, buf->sector);
137 if (d->flags & DEVFL_EXT) { 195 if (d->flags & DEVFL_EXT) {
138 ah->aflags |= AOEAFL_EXT; 196 ah->aflags |= AOEAFL_EXT;
139 } else { 197 } else {
@@ -141,14 +199,14 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
141 ah->lba3 &= 0x0f; 199 ah->lba3 &= 0x0f;
142 ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */ 200 ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */
143 } 201 }
144
145 if (bio_data_dir(buf->bio) == WRITE) { 202 if (bio_data_dir(buf->bio) == WRITE) {
146 skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), 203 skb_fill_page_desc(skb, 0, bv->bv_page, buf->bv_off, bcnt);
147 offset_in_page(f->bufaddr), bcnt);
148 ah->aflags |= AOEAFL_WRITE; 204 ah->aflags |= AOEAFL_WRITE;
149 skb->len += bcnt; 205 skb->len += bcnt;
150 skb->data_len = bcnt; 206 skb->data_len = bcnt;
207 t->wpkts++;
151 } else { 208 } else {
209 t->rpkts++;
152 writebit = 0; 210 writebit = 0;
153 } 211 }
154 212
@@ -156,29 +214,29 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
156 214
157 /* mark all tracking fields and load out */ 215 /* mark all tracking fields and load out */
158 buf->nframesout += 1; 216 buf->nframesout += 1;
159 buf->bufaddr += bcnt; 217 buf->bv_off += bcnt;
160 buf->bv_resid -= bcnt; 218 buf->bv_resid -= bcnt;
161/* printk(KERN_DEBUG "aoe: bv_resid=%ld\n", buf->bv_resid); */
162 buf->resid -= bcnt; 219 buf->resid -= bcnt;
163 buf->sector += bcnt >> 9; 220 buf->sector += bcnt >> 9;
164 if (buf->resid == 0) { 221 if (buf->resid == 0) {
165 d->inprocess = NULL; 222 d->inprocess = NULL;
166 } else if (buf->bv_resid == 0) { 223 } else if (buf->bv_resid == 0) {
167 buf->bv++; 224 buf->bv = ++bv;
168 WARN_ON(buf->bv->bv_len == 0); 225 buf->bv_resid = bv->bv_len;
169 buf->bv_resid = buf->bv->bv_len; 226 WARN_ON(buf->bv_resid == 0);
170 buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; 227 buf->bv_off = bv->bv_offset;
171 } 228 }
172 229
173 skb->dev = d->ifp; 230 skb->dev = t->ifp->nd;
174 skb = skb_clone(skb, GFP_ATOMIC); 231 skb = skb_clone(skb, GFP_ATOMIC);
175 if (skb == NULL) 232 if (skb) {
176 return; 233 if (d->sendq_hd)
177 if (d->sendq_hd) 234 d->sendq_tl->next = skb;
178 d->sendq_tl->next = skb; 235 else
179 else 236 d->sendq_hd = skb;
180 d->sendq_hd = skb; 237 d->sendq_tl = skb;
181 d->sendq_tl = skb; 238 }
239 return 1;
182} 240}
183 241
184/* some callers cannot sleep, and they can call this function, 242/* some callers cannot sleep, and they can call this function,
@@ -232,62 +290,8 @@ cont:
232 return sl; 290 return sl;
233} 291}
234 292
235static struct frame *
236freeframe(struct aoedev *d)
237{
238 struct frame *f, *e;
239 int n = 0;
240
241 f = d->frames;
242 e = f + d->nframes;
243 for (; f<e; f++) {
244 if (f->tag != FREETAG)
245 continue;
246 if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
247 skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
248 skb_trim(f->skb, 0);
249 return f;
250 }
251 n++;
252 }
253 if (n == d->nframes) /* wait for network layer */
254 d->flags |= DEVFL_KICKME;
255
256 return NULL;
257}
258
259/* enters with d->lock held */
260void
261aoecmd_work(struct aoedev *d)
262{
263 struct frame *f;
264 struct buf *buf;
265
266 if (d->flags & DEVFL_PAUSE) {
267 if (!aoedev_isbusy(d))
268 d->sendq_hd = aoecmd_cfg_pkts(d->aoemajor,
269 d->aoeminor, &d->sendq_tl);
270 return;
271 }
272
273loop:
274 f = freeframe(d);
275 if (f == NULL)
276 return;
277 if (d->inprocess == NULL) {
278 if (list_empty(&d->bufq))
279 return;
280 buf = container_of(d->bufq.next, struct buf, bufs);
281 list_del(d->bufq.next);
282/*printk(KERN_DEBUG "aoe: bi_size=%ld\n", buf->bio->bi_size); */
283 d->inprocess = buf;
284 }
285 aoecmd_ata_rw(d, f);
286 goto loop;
287}
288
289static void 293static void
290rexmit(struct aoedev *d, struct frame *f) 294resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
291{ 295{
292 struct sk_buff *skb; 296 struct sk_buff *skb;
293 struct aoe_hdr *h; 297 struct aoe_hdr *h;
@@ -295,41 +299,45 @@ rexmit(struct aoedev *d, struct frame *f)
295 char buf[128]; 299 char buf[128];
296 u32 n; 300 u32 n;
297 301
298 n = newtag(d); 302 ifrotate(t);
303 n = newtag(t);
304 skb = f->skb;
305 h = (struct aoe_hdr *) skb_mac_header(skb);
306 ah = (struct aoe_atahdr *) (h+1);
299 307
300 snprintf(buf, sizeof buf, 308 snprintf(buf, sizeof buf,
301 "%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08x\n", 309 "%15s e%ld.%d oldtag=%08x@%08lx newtag=%08x "
302 "retransmit", 310 "s=%012llx d=%012llx nout=%d\n",
303 d->aoemajor, d->aoeminor, f->tag, jiffies, n); 311 "retransmit", d->aoemajor, d->aoeminor, f->tag, jiffies, n,
312 mac_addr(h->src), mac_addr(h->dst), t->nout);
304 aoechr_error(buf); 313 aoechr_error(buf);
305 314
306 skb = f->skb;
307 h = (struct aoe_hdr *) skb_mac_header(skb);
308 ah = (struct aoe_atahdr *) (h+1);
309 f->tag = n; 315 f->tag = n;
310 h->tag = cpu_to_be32(n); 316 h->tag = cpu_to_be32(n);
311 memcpy(h->dst, d->addr, sizeof h->dst); 317 memcpy(h->dst, t->addr, sizeof h->dst);
312 memcpy(h->src, d->ifp->dev_addr, sizeof h->src); 318 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
313 319
314 n = DEFAULTBCNT / 512; 320 switch (ah->cmdstat) {
315 if (ah->scnt > n) { 321 default:
316 ah->scnt = n; 322 break;
323 case WIN_READ:
324 case WIN_READ_EXT:
325 case WIN_WRITE:
326 case WIN_WRITE_EXT:
327 put_lba(ah, f->lba);
328
329 n = f->bcnt;
330 if (n > DEFAULTBCNT)
331 n = DEFAULTBCNT;
332 ah->scnt = n >> 9;
317 if (ah->aflags & AOEAFL_WRITE) { 333 if (ah->aflags & AOEAFL_WRITE) {
318 skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), 334 skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
319 offset_in_page(f->bufaddr), DEFAULTBCNT); 335 offset_in_page(f->bufaddr), n);
320 skb->len = sizeof *h + sizeof *ah + DEFAULTBCNT; 336 skb->len = sizeof *h + sizeof *ah + n;
321 skb->data_len = DEFAULTBCNT; 337 skb->data_len = n;
322 }
323 if (++d->lostjumbo > (d->nframes << 1))
324 if (d->maxbcnt != DEFAULTBCNT) {
325 printk(KERN_INFO "aoe: e%ld.%ld: too many lost jumbo on %s - using 1KB frames.\n",
326 d->aoemajor, d->aoeminor, d->ifp->name);
327 d->maxbcnt = DEFAULTBCNT;
328 d->flags |= DEVFL_MAXBCNT;
329 } 338 }
330 } 339 }
331 340 skb->dev = t->ifp->nd;
332 skb->dev = d->ifp;
333 skb = skb_clone(skb, GFP_ATOMIC); 341 skb = skb_clone(skb, GFP_ATOMIC);
334 if (skb == NULL) 342 if (skb == NULL)
335 return; 343 return;
@@ -352,10 +360,92 @@ tsince(int tag)
352 return n; 360 return n;
353} 361}
354 362
363static struct aoeif *
364getif(struct aoetgt *t, struct net_device *nd)
365{
366 struct aoeif *p, *e;
367
368 p = t->ifs;
369 e = p + NAOEIFS;
370 for (; p < e; p++)
371 if (p->nd == nd)
372 return p;
373 return NULL;
374}
375
376static struct aoeif *
377addif(struct aoetgt *t, struct net_device *nd)
378{
379 struct aoeif *p;
380
381 p = getif(t, NULL);
382 if (!p)
383 return NULL;
384 p->nd = nd;
385 p->maxbcnt = DEFAULTBCNT;
386 p->lost = 0;
387 p->lostjumbo = 0;
388 return p;
389}
390
391static void
392ejectif(struct aoetgt *t, struct aoeif *ifp)
393{
394 struct aoeif *e;
395 ulong n;
396
397 e = t->ifs + NAOEIFS - 1;
398 n = (e - ifp) * sizeof *ifp;
399 memmove(ifp, ifp+1, n);
400 e->nd = NULL;
401}
402
403static int
404sthtith(struct aoedev *d)
405{
406 struct frame *f, *e, *nf;
407 struct sk_buff *skb;
408 struct aoetgt *ht = *d->htgt;
409
410 f = ht->frames;
411 e = f + ht->nframes;
412 for (; f < e; f++) {
413 if (f->tag == FREETAG)
414 continue;
415 nf = freeframe(d);
416 if (!nf)
417 return 0;
418 skb = nf->skb;
419 *nf = *f;
420 f->skb = skb;
421 f->tag = FREETAG;
422 nf->waited = 0;
423 ht->nout--;
424 (*d->tgt)->nout++;
425 resend(d, *d->tgt, nf);
426 }
427 /* he's clean, he's useless. take away his interfaces */
428 memset(ht->ifs, 0, sizeof ht->ifs);
429 d->htgt = NULL;
430 return 1;
431}
432
433static inline unsigned char
434ata_scnt(unsigned char *packet) {
435 struct aoe_hdr *h;
436 struct aoe_atahdr *ah;
437
438 h = (struct aoe_hdr *) packet;
439 ah = (struct aoe_atahdr *) (h+1);
440 return ah->scnt;
441}
442
355static void 443static void
356rexmit_timer(ulong vp) 444rexmit_timer(ulong vp)
357{ 445{
358 struct aoedev *d; 446 struct aoedev *d;
447 struct aoetgt *t, **tt, **te;
448 struct aoeif *ifp;
359 struct frame *f, *e; 449 struct frame *f, *e;
360 struct sk_buff *sl; 450 struct sk_buff *sl;
361 register long timeout; 451 register long timeout;
@@ -374,31 +464,79 @@ rexmit_timer(ulong vp)
374 spin_unlock_irqrestore(&d->lock, flags); 464 spin_unlock_irqrestore(&d->lock, flags);
375 return; 465 return;
376 } 466 }
377 f = d->frames; 467 tt = d->targets;
378 e = f + d->nframes; 468 te = tt + NTARGETS;
379 for (; f<e; f++) { 469 for (; tt < te && *tt; tt++) {
380 if (f->tag != FREETAG && tsince(f->tag) >= timeout) { 470 t = *tt;
471 f = t->frames;
472 e = f + t->nframes;
473 for (; f < e; f++) {
474 if (f->tag == FREETAG
475 || tsince(f->tag) < timeout)
476 continue;
381 n = f->waited += timeout; 477 n = f->waited += timeout;
382 n /= HZ; 478 n /= HZ;
383 if (n > aoe_deadsecs) { /* waited too long for response */ 479 if (n > aoe_deadsecs) {
480 /* waited too long. device failure. */
384 aoedev_downdev(d); 481 aoedev_downdev(d);
385 break; 482 break;
386 } 483 }
387 rexmit(d, f); 484
485 if (n > HELPWAIT /* see if another target can help */
486 && (tt != d->targets || d->targets[1]))
487 d->htgt = tt;
488
489 if (t->nout == t->maxout) {
490 if (t->maxout > 1)
491 t->maxout--;
492 t->lastwadj = jiffies;
493 }
494
495 ifp = getif(t, f->skb->dev);
496 if (ifp && ++ifp->lost > (t->nframes << 1)
497 && (ifp != t->ifs || t->ifs[1].nd)) {
498 ejectif(t, ifp);
499 ifp = NULL;
500 }
501
502 if (ata_scnt(skb_mac_header(f->skb)) > DEFAULTBCNT / 512
503 && ifp && ++ifp->lostjumbo > (t->nframes << 1)
504 && ifp->maxbcnt != DEFAULTBCNT) {
505 printk(KERN_INFO
506 "aoe: e%ld.%d: "
507 "too many lost jumbo on "
508 "%s:%012llx - "
509 "falling back to %d frames.\n",
510 d->aoemajor, d->aoeminor,
511 ifp->nd->name, mac_addr(t->addr),
512 DEFAULTBCNT);
513 ifp->maxbcnt = 0;
514 }
515 resend(d, t, f);
516 }
517
518 /* window check */
519 if (t->nout == t->maxout
520 && t->maxout < t->nframes
521 && (jiffies - t->lastwadj)/HZ > 10) {
522 t->maxout++;
523 t->lastwadj = jiffies;
388 } 524 }
389 } 525 }
390 if (d->flags & DEVFL_KICKME) { 526
527 if (d->sendq_hd) {
528 n = d->rttavg <<= 1;
529 if (n > MAXTIMER)
530 d->rttavg = MAXTIMER;
531 }
532
533 if (d->flags & DEVFL_KICKME || d->htgt) {
391 d->flags &= ~DEVFL_KICKME; 534 d->flags &= ~DEVFL_KICKME;
392 aoecmd_work(d); 535 aoecmd_work(d);
393 } 536 }
394 537
395 sl = d->sendq_hd; 538 sl = d->sendq_hd;
396 d->sendq_hd = d->sendq_tl = NULL; 539 d->sendq_hd = d->sendq_tl = NULL;
397 if (sl) {
398 n = d->rttavg <<= 1;
399 if (n > MAXTIMER)
400 d->rttavg = MAXTIMER;
401 }
402 540
403 d->timer.expires = jiffies + TIMERTICK; 541 d->timer.expires = jiffies + TIMERTICK;
404 add_timer(&d->timer); 542 add_timer(&d->timer);
@@ -408,6 +546,25 @@ rexmit_timer(ulong vp)
408 aoenet_xmit(sl); 546 aoenet_xmit(sl);
409} 547}
410 548
549/* enters with d->lock held */
550void
551aoecmd_work(struct aoedev *d)
552{
553 struct buf *buf;
554loop:
555 if (d->htgt && !sthtith(d))
556 return;
557 if (d->inprocess == NULL) {
558 if (list_empty(&d->bufq))
559 return;
560 buf = container_of(d->bufq.next, struct buf, bufs);
561 list_del(d->bufq.next);
562 d->inprocess = buf;
563 }
564 if (aoecmd_ata_rw(d))
565 goto loop;
566}
567
411/* this function performs work that has been deferred until sleeping is OK 568/* this function performs work that has been deferred until sleeping is OK
412 */ 569 */
413void 570void
@@ -440,7 +597,7 @@ aoecmd_sleepwork(struct work_struct *work)
440} 597}
441 598
442static void 599static void
443ataid_complete(struct aoedev *d, unsigned char *id) 600ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
444{ 601{
445 u64 ssize; 602 u64 ssize;
446 u16 n; 603 u16 n;
@@ -476,7 +633,7 @@ ataid_complete(struct aoedev *d, unsigned char *id)
476 633
477 if (d->ssize != ssize) 634 if (d->ssize != ssize)
478 printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n", 635 printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n",
479 (unsigned long long)mac_addr(d->addr), 636 (unsigned long long)mac_addr(t->addr),
480 d->aoemajor, d->aoeminor, 637 d->aoemajor, d->aoeminor,
481 d->fw_ver, (long long)ssize); 638 d->fw_ver, (long long)ssize);
482 d->ssize = ssize; 639 d->ssize = ssize;
@@ -484,15 +641,8 @@ ataid_complete(struct aoedev *d, unsigned char *id)
484 if (d->gd != NULL) { 641 if (d->gd != NULL) {
485 d->gd->capacity = ssize; 642 d->gd->capacity = ssize;
486 d->flags |= DEVFL_NEWSIZE; 643 d->flags |= DEVFL_NEWSIZE;
487 } else { 644 } else
488 if (d->flags & DEVFL_GDALLOC) {
489 printk(KERN_ERR "aoe: can't schedule work for e%lu.%lu, %s\n",
490 d->aoemajor, d->aoeminor,
491 "it's already on! This shouldn't happen.\n");
492 return;
493 }
494 d->flags |= DEVFL_GDALLOC; 645 d->flags |= DEVFL_GDALLOC;
495 }
496 schedule_work(&d->work); 646 schedule_work(&d->work);
497} 647}
498 648
@@ -519,6 +669,31 @@ calc_rttavg(struct aoedev *d, int rtt)
519 d->rttavg += n >> 2; 669 d->rttavg += n >> 2;
520} 670}
521 671
672static struct aoetgt *
673gettgt(struct aoedev *d, char *addr)
674{
675 struct aoetgt **t, **e;
676
677 t = d->targets;
678 e = t + NTARGETS;
679 for (; t < e && *t; t++)
680 if (memcmp((*t)->addr, addr, sizeof((*t)->addr)) == 0)
681 return *t;
682 return NULL;
683}
684
685static inline void
686diskstats(struct gendisk *disk, struct bio *bio, ulong duration)
687{
688 unsigned long n_sect = bio->bi_size >> 9;
689 const int rw = bio_data_dir(bio);
690
691 disk_stat_inc(disk, ios[rw]);
692 disk_stat_add(disk, ticks[rw], duration);
693 disk_stat_add(disk, sectors[rw], n_sect);
694 disk_stat_add(disk, io_ticks, duration);
695}
696
522void 697void
523aoecmd_ata_rsp(struct sk_buff *skb) 698aoecmd_ata_rsp(struct sk_buff *skb)
524{ 699{
@@ -528,6 +703,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
528 struct frame *f; 703 struct frame *f;
529 struct buf *buf; 704 struct buf *buf;
530 struct sk_buff *sl; 705 struct sk_buff *sl;
706 struct aoetgt *t;
707 struct aoeif *ifp;
531 register long n; 708 register long n;
532 ulong flags; 709 ulong flags;
533 char ebuf[128]; 710 char ebuf[128];
@@ -547,7 +724,15 @@ aoecmd_ata_rsp(struct sk_buff *skb)
547 spin_lock_irqsave(&d->lock, flags); 724 spin_lock_irqsave(&d->lock, flags);
548 725
549 n = be32_to_cpu(get_unaligned(&hin->tag)); 726 n = be32_to_cpu(get_unaligned(&hin->tag));
550 f = getframe(d, n); 727 t = gettgt(d, hin->src);
728 if (t == NULL) {
729 printk(KERN_INFO "aoe: can't find target e%ld.%d:%012llx\n",
730 d->aoemajor, d->aoeminor,
731 (unsigned long long) mac_addr(hin->src));
732 spin_unlock_irqrestore(&d->lock, flags);
733 return;
734 }
735 f = getframe(t, n);
551 if (f == NULL) { 736 if (f == NULL) {
552 calc_rttavg(d, -tsince(n)); 737 calc_rttavg(d, -tsince(n));
553 spin_unlock_irqrestore(&d->lock, flags); 738 spin_unlock_irqrestore(&d->lock, flags);
@@ -569,8 +754,6 @@ aoecmd_ata_rsp(struct sk_buff *skb)
569 ahout = (struct aoe_atahdr *) (hout+1); 754 ahout = (struct aoe_atahdr *) (hout+1);
570 buf = f->buf; 755 buf = f->buf;
571 756
572 if (ahout->cmdstat == WIN_IDENTIFY)
573 d->flags &= ~DEVFL_PAUSE;
574 if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */ 757 if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
575 printk(KERN_ERR 758 printk(KERN_ERR
576 "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n", 759 "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n",
@@ -579,14 +762,16 @@ aoecmd_ata_rsp(struct sk_buff *skb)
579 if (buf) 762 if (buf)
580 buf->flags |= BUFFL_FAIL; 763 buf->flags |= BUFFL_FAIL;
581 } else { 764 } else {
765 if (d->htgt && t == *d->htgt) /* I'll help myself, thank you. */
766 d->htgt = NULL;
582 n = ahout->scnt << 9; 767 n = ahout->scnt << 9;
583 switch (ahout->cmdstat) { 768 switch (ahout->cmdstat) {
584 case WIN_READ: 769 case WIN_READ:
585 case WIN_READ_EXT: 770 case WIN_READ_EXT:
586 if (skb->len - sizeof *hin - sizeof *ahin < n) { 771 if (skb->len - sizeof *hin - sizeof *ahin < n) {
587 printk(KERN_ERR 772 printk(KERN_ERR
588 "aoe: runt data size in read. skb->len=%d\n", 773 "aoe: %s. skb->len=%d need=%ld\n",
589 skb->len); 774 "runt data size in read", skb->len, n);
590 /* fail frame f? just returning will rexmit. */ 775 /* fail frame f? just returning will rexmit. */
591 spin_unlock_irqrestore(&d->lock, flags); 776 spin_unlock_irqrestore(&d->lock, flags);
592 return; 777 return;
@@ -594,32 +779,18 @@ aoecmd_ata_rsp(struct sk_buff *skb)
594 memcpy(f->bufaddr, ahin+1, n); 779 memcpy(f->bufaddr, ahin+1, n);
595 case WIN_WRITE: 780 case WIN_WRITE:
596 case WIN_WRITE_EXT: 781 case WIN_WRITE_EXT:
782 ifp = getif(t, skb->dev);
783 if (ifp) {
784 ifp->lost = 0;
785 if (n > DEFAULTBCNT)
786 ifp->lostjumbo = 0;
787 }
597 if (f->bcnt -= n) { 788 if (f->bcnt -= n) {
598 skb = f->skb; 789 f->lba += n >> 9;
599 f->bufaddr += n; 790 f->bufaddr += n;
600 put_lba(ahout, f->lba += ahout->scnt); 791 resend(d, t, f);
601 n = f->bcnt; 792 goto xmit;
602 if (n > DEFAULTBCNT)
603 n = DEFAULTBCNT;
604 ahout->scnt = n >> 9;
605 if (ahout->aflags & AOEAFL_WRITE) {
606 skb_fill_page_desc(skb, 0,
607 virt_to_page(f->bufaddr),
608 offset_in_page(f->bufaddr), n);
609 skb->len = sizeof *hout + sizeof *ahout + n;
610 skb->data_len = n;
611 }
612 f->tag = newtag(d);
613 hout->tag = cpu_to_be32(f->tag);
614 skb->dev = d->ifp;
615 skb = skb_clone(skb, GFP_ATOMIC);
616 spin_unlock_irqrestore(&d->lock, flags);
617 if (skb)
618 aoenet_xmit(skb);
619 return;
620 } 793 }
621 if (n > DEFAULTBCNT)
622 d->lostjumbo = 0;
623 break; 794 break;
624 case WIN_IDENTIFY: 795 case WIN_IDENTIFY:
625 if (skb->len - sizeof *hin - sizeof *ahin < 512) { 796 if (skb->len - sizeof *hin - sizeof *ahin < 512) {
@@ -629,7 +800,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
629 spin_unlock_irqrestore(&d->lock, flags); 800 spin_unlock_irqrestore(&d->lock, flags);
630 return; 801 return;
631 } 802 }
632 ataid_complete(d, (char *) (ahin+1)); 803 ataid_complete(d, t, (char *) (ahin+1));
633 break; 804 break;
634 default: 805 default:
635 printk(KERN_INFO 806 printk(KERN_INFO
@@ -640,28 +811,19 @@ aoecmd_ata_rsp(struct sk_buff *skb)
640 } 811 }
641 } 812 }
642 813
643 if (buf) { 814 if (buf && --buf->nframesout == 0 && buf->resid == 0) {
644 buf->nframesout -= 1; 815 diskstats(d->gd, buf->bio, jiffies - buf->stime);
645 if (buf->nframesout == 0 && buf->resid == 0) { 816 n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
646 unsigned long duration = jiffies - buf->start_time; 817 bio_endio(buf->bio, n);
647 unsigned long n_sect = buf->bio->bi_size >> 9; 818 mempool_free(buf, d->bufpool);
648 struct gendisk *disk = d->gd;
649 const int rw = bio_data_dir(buf->bio);
650
651 disk_stat_inc(disk, ios[rw]);
652 disk_stat_add(disk, ticks[rw], duration);
653 disk_stat_add(disk, sectors[rw], n_sect);
654 disk_stat_add(disk, io_ticks, duration);
655 n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
656 bio_endio(buf->bio, n);
657 mempool_free(buf, d->bufpool);
658 }
659 } 819 }
660 820
661 f->buf = NULL; 821 f->buf = NULL;
662 f->tag = FREETAG; 822 f->tag = FREETAG;
823 t->nout--;
663 824
664 aoecmd_work(d); 825 aoecmd_work(d);
826xmit:
665 sl = d->sendq_hd; 827 sl = d->sendq_hd;
666 d->sendq_hd = d->sendq_tl = NULL; 828 d->sendq_hd = d->sendq_tl = NULL;
667 829
@@ -679,23 +841,20 @@ aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
679 aoenet_xmit(sl); 841 aoenet_xmit(sl);
680} 842}
681 843
682/* 844struct sk_buff *
683 * Since we only call this in one place (and it only prepares one frame)
684 * we just return the skb. Usually we'd chain it up to the aoedev sendq.
685 */
686static struct sk_buff *
687aoecmd_ata_id(struct aoedev *d) 845aoecmd_ata_id(struct aoedev *d)
688{ 846{
689 struct aoe_hdr *h; 847 struct aoe_hdr *h;
690 struct aoe_atahdr *ah; 848 struct aoe_atahdr *ah;
691 struct frame *f; 849 struct frame *f;
692 struct sk_buff *skb; 850 struct sk_buff *skb;
851 struct aoetgt *t;
693 852
694 f = freeframe(d); 853 f = freeframe(d);
695 if (f == NULL) { 854 if (f == NULL)
696 printk(KERN_ERR "aoe: can't get a frame. This shouldn't happen.\n");
697 return NULL; 855 return NULL;
698 } 856
857 t = *d->tgt;
699 858
700 /* initialize the headers & frame */ 859 /* initialize the headers & frame */
701 skb = f->skb; 860 skb = f->skb;
@@ -703,7 +862,8 @@ aoecmd_ata_id(struct aoedev *d)
703 ah = (struct aoe_atahdr *) (h+1); 862 ah = (struct aoe_atahdr *) (h+1);
704 skb_put(skb, sizeof *h + sizeof *ah); 863 skb_put(skb, sizeof *h + sizeof *ah);
705 memset(h, 0, skb->len); 864 memset(h, 0, skb->len);
706 f->tag = aoehdr_atainit(d, h); 865 f->tag = aoehdr_atainit(d, t, h);
866 t->nout++;
707 f->waited = 0; 867 f->waited = 0;
708 868
709 /* set up ata header */ 869 /* set up ata header */
@@ -711,7 +871,7 @@ aoecmd_ata_id(struct aoedev *d)
711 ah->cmdstat = WIN_IDENTIFY; 871 ah->cmdstat = WIN_IDENTIFY;
712 ah->lba3 = 0xa0; 872 ah->lba3 = 0xa0;
713 873
714 skb->dev = d->ifp; 874 skb->dev = t->ifp->nd;
715 875
716 d->rttavg = MAXTIMER; 876 d->rttavg = MAXTIMER;
717 d->timer.function = rexmit_timer; 877 d->timer.function = rexmit_timer;
@@ -719,12 +879,58 @@ aoecmd_ata_id(struct aoedev *d)
719 return skb_clone(skb, GFP_ATOMIC); 879 return skb_clone(skb, GFP_ATOMIC);
720} 880}
721 881
882static struct aoetgt *
883addtgt(struct aoedev *d, char *addr, ulong nframes)
884{
885 struct aoetgt *t, **tt, **te;
886 struct frame *f, *e;
887
888 tt = d->targets;
889 te = tt + NTARGETS;
890 for (; tt < te && *tt; tt++)
891 ;
892
893 if (tt == te)
894 return NULL;
895
896 t = kcalloc(1, sizeof *t, GFP_ATOMIC);
897 f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
898 if (!t || !f)
899 goto bail;
900 t->nframes = nframes;
901 t->frames = f;
902 e = f + nframes;
903 for (; f < e; f++) {
904 f->tag = FREETAG;
905 f->skb = new_skb(ETH_ZLEN);
906 if (!f->skb)
907 break;
908 }
909 if (f != e) {
910 while (f > t->frames) {
911 f--;
912 dev_kfree_skb(f->skb);
913 }
914 goto bail;
915 }
916 memcpy(t->addr, addr, sizeof t->addr);
917 t->ifp = t->ifs;
918 t->maxout = t->nframes;
919 return *tt = t;
920bail:
921 kfree(t);
922 kfree(f);
923 return NULL;
924}
925
722void 926void
723aoecmd_cfg_rsp(struct sk_buff *skb) 927aoecmd_cfg_rsp(struct sk_buff *skb)
724{ 928{
725 struct aoedev *d; 929 struct aoedev *d;
726 struct aoe_hdr *h; 930 struct aoe_hdr *h;
727 struct aoe_cfghdr *ch; 931 struct aoe_cfghdr *ch;
932 struct aoetgt *t;
933 struct aoeif *ifp;
728 ulong flags, sysminor, aoemajor; 934 ulong flags, sysminor, aoemajor;
729 struct sk_buff *sl; 935 struct sk_buff *sl;
730 enum { MAXFRAMES = 16 }; 936 enum { MAXFRAMES = 16 };
@@ -755,7 +961,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
755 if (n > MAXFRAMES) /* keep it reasonable */ 961 if (n > MAXFRAMES) /* keep it reasonable */
756 n = MAXFRAMES; 962 n = MAXFRAMES;
757 963
758 d = aoedev_by_sysminor_m(sysminor, n); 964 d = aoedev_by_sysminor_m(sysminor);
759 if (d == NULL) { 965 if (d == NULL) {
760 printk(KERN_INFO "aoe: device sysminor_m failure\n"); 966 printk(KERN_INFO "aoe: device sysminor_m failure\n");
761 return; 967 return;
@@ -763,38 +969,77 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
763 969
764 spin_lock_irqsave(&d->lock, flags); 970 spin_lock_irqsave(&d->lock, flags);
765 971
766 /* permit device to migrate mac and network interface */ 972 t = gettgt(d, h->src);
767 d->ifp = skb->dev; 973 if (!t) {
768 memcpy(d->addr, h->src, sizeof d->addr); 974 t = addtgt(d, h->src, n);
769 if (!(d->flags & DEVFL_MAXBCNT)) { 975 if (!t) {
770 n = d->ifp->mtu; 976 printk(KERN_INFO
977 "aoe: device addtgt failure; "
978 "too many targets?\n");
979 spin_unlock_irqrestore(&d->lock, flags);
980 return;
981 }
982 }
983 ifp = getif(t, skb->dev);
984 if (!ifp) {
985 ifp = addif(t, skb->dev);
986 if (!ifp) {
987 printk(KERN_INFO
988 "aoe: device addif failure; "
989 "too many interfaces?\n");
990 spin_unlock_irqrestore(&d->lock, flags);
991 return;
992 }
993 }
994 if (ifp->maxbcnt) {
995 n = ifp->nd->mtu;
771 n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr); 996 n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
772 n /= 512; 997 n /= 512;
773 if (n > ch->scnt) 998 if (n > ch->scnt)
774 n = ch->scnt; 999 n = ch->scnt;
775 n = n ? n * 512 : DEFAULTBCNT; 1000 n = n ? n * 512 : DEFAULTBCNT;
776 if (n != d->maxbcnt) { 1001 if (n != ifp->maxbcnt) {
777 printk(KERN_INFO 1002 printk(KERN_INFO
778 "aoe: e%ld.%ld: setting %d byte data frames on %s\n", 1003 "aoe: e%ld.%d: setting %d%s%s:%012llx\n",
779 d->aoemajor, d->aoeminor, n, d->ifp->name); 1004 d->aoemajor, d->aoeminor, n,
780 d->maxbcnt = n; 1005 " byte data frames on ", ifp->nd->name,
1006 (unsigned long long) mac_addr(t->addr));
1007 ifp->maxbcnt = n;
781 } 1008 }
782 } 1009 }
783 1010
784 /* don't change users' perspective */ 1011 /* don't change users' perspective */
785 if (d->nopen && !(d->flags & DEVFL_PAUSE)) { 1012 if (d->nopen) {
786 spin_unlock_irqrestore(&d->lock, flags); 1013 spin_unlock_irqrestore(&d->lock, flags);
787 return; 1014 return;
788 } 1015 }
789 d->flags |= DEVFL_PAUSE; /* force pause */
790 d->mintimer = MINTIMER;
791 d->fw_ver = be16_to_cpu(ch->fwver); 1016 d->fw_ver = be16_to_cpu(ch->fwver);
792 1017
793 /* check for already outstanding ataid */ 1018 sl = aoecmd_ata_id(d);
794 sl = aoedev_isbusy(d) == 0 ? aoecmd_ata_id(d) : NULL;
795 1019
796 spin_unlock_irqrestore(&d->lock, flags); 1020 spin_unlock_irqrestore(&d->lock, flags);
797 1021
798 aoenet_xmit(sl); 1022 aoenet_xmit(sl);
799} 1023}
800 1024
1025void
1026aoecmd_cleanslate(struct aoedev *d)
1027{
1028 struct aoetgt **t, **te;
1029 struct aoeif *p, *e;
1030
1031 d->mintimer = MINTIMER;
1032
1033 t = d->targets;
1034 te = t + NTARGETS;
1035 for (; t < te && *t; t++) {
1036 (*t)->maxout = (*t)->nframes;
1037 p = (*t)->ifs;
1038 e = p + NAOEIFS;
1039 for (; p < e; p++) {
1040 p->lostjumbo = 0;
1041 p->lost = 0;
1042 p->maxbcnt = DEFAULTBCNT;
1043 }
1044 }
1045}