aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorEd Cashin <ecashin@coraid.com>2012-10-04 20:16:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 14:05:24 -0400
commit896831f5909e2733c13c9cb13a1a215f10c3eaa8 (patch)
tree9541075df9b3703b7ea8853de619fa98c4be1456 /drivers/block
parent3d5b06051cd5fa82c9a4285f7ce8650a0f0845ff (diff)
aoe: kernel thread handles I/O completions for simple locking
Make the frames the aoe driver uses to track the relationship between bios and packets more flexible and detached, so that they can be passed to an "aoe_ktio" thread for completion of I/O. The frames are handled much like skbs, with a capped amount of preallocation so that real-world use cases are likely to run smoothly and degenerate gracefully even under memory pressure. Decoupling I/O completion from the receive path and serializing it in a process makes it easier to think about the correctness of the locking in the driver, especially in the case of a remote MAC address becoming unusable. [dan.carpenter@oracle.com: cleanup an allocation a bit] Signed-off-by: Ed Cashin <ecashin@coraid.com> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/aoe/aoe.h33
-rw-r--r--drivers/block/aoe/aoechr.c3
-rw-r--r--drivers/block/aoe/aoecmd.c732
-rw-r--r--drivers/block/aoe/aoedev.c84
-rw-r--r--drivers/block/aoe/aoemain.c8
-rw-r--r--drivers/block/aoe/aoenet.c6
6 files changed, 560 insertions, 306 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 8ca8c8a929ae..0cd6c0f7a535 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -91,6 +91,7 @@ enum {
91 NTARGETS = 8, 91 NTARGETS = 8,
92 NAOEIFS = 8, 92 NAOEIFS = 8,
93 NSKBPOOLMAX = 128, 93 NSKBPOOLMAX = 128,
94 NFACTIVE = 17,
94 95
95 TIMERTICK = HZ / 10, 96 TIMERTICK = HZ / 10,
96 MINTIMER = HZ >> 2, 97 MINTIMER = HZ >> 2,
@@ -112,13 +113,16 @@ struct buf {
112}; 113};
113 114
114struct frame { 115struct frame {
115 int tag; 116 struct list_head head;
117 u32 tag;
116 ulong waited; 118 ulong waited;
117 struct buf *buf; 119 struct buf *buf;
120 struct aoetgt *t; /* parent target I belong to */
118 char *bufaddr; 121 char *bufaddr;
119 ulong bcnt; 122 ulong bcnt;
120 sector_t lba; 123 sector_t lba;
121 struct sk_buff *skb; 124 struct sk_buff *skb; /* command skb freed on module exit */
125 struct sk_buff *r_skb; /* response skb for async processing */
122 struct bio_vec *bv; 126 struct bio_vec *bv;
123 ulong bv_off; 127 ulong bv_off;
124}; 128};
@@ -133,16 +137,18 @@ struct aoeif {
133struct aoetgt { 137struct aoetgt {
134 unsigned char addr[6]; 138 unsigned char addr[6];
135 ushort nframes; 139 ushort nframes;
136 struct frame *frames; 140 struct aoedev *d; /* parent device I belong to */
141 struct list_head factive[NFACTIVE]; /* hash of active frames */
142 struct list_head ffree; /* list of free frames */
137 struct aoeif ifs[NAOEIFS]; 143 struct aoeif ifs[NAOEIFS];
138 struct aoeif *ifp; /* current aoeif in use */ 144 struct aoeif *ifp; /* current aoeif in use */
139 ushort nout; 145 ushort nout;
140 ushort maxout; 146 ushort maxout;
141 u16 lasttag; /* last tag sent */ 147 u16 lasttag; /* last tag sent */
142 u16 useme; 148 u16 useme;
149 ulong falloc;
143 ulong lastwadj; /* last window adjustment */ 150 ulong lastwadj; /* last window adjustment */
144 int wpkts, rpkts; 151 int wpkts, rpkts;
145 int dataref;
146}; 152};
147 153
148struct aoedev { 154struct aoedev {
@@ -169,9 +175,20 @@ struct aoedev {
169 struct buf *inprocess; /* the one we're currently working on */ 175 struct buf *inprocess; /* the one we're currently working on */
170 struct aoetgt *targets[NTARGETS]; 176 struct aoetgt *targets[NTARGETS];
171 struct aoetgt **tgt; /* target in use when working */ 177 struct aoetgt **tgt; /* target in use when working */
172 struct aoetgt **htgt; /* target needing rexmit assistance */ 178 struct aoetgt *htgt; /* target needing rexmit assistance */
179 ulong ntargets;
180 ulong kicked;
173}; 181};
174 182
183/* kthread tracking */
184struct ktstate {
185 struct completion rendez;
186 struct task_struct *task;
187 wait_queue_head_t *waitq;
188 int (*fn) (void);
189 char *name;
190 spinlock_t *lock;
191};
175 192
176int aoeblk_init(void); 193int aoeblk_init(void);
177void aoeblk_exit(void); 194void aoeblk_exit(void);
@@ -184,11 +201,14 @@ void aoechr_error(char *);
184 201
185void aoecmd_work(struct aoedev *d); 202void aoecmd_work(struct aoedev *d);
186void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); 203void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
187void aoecmd_ata_rsp(struct sk_buff *); 204struct sk_buff *aoecmd_ata_rsp(struct sk_buff *);
188void aoecmd_cfg_rsp(struct sk_buff *); 205void aoecmd_cfg_rsp(struct sk_buff *);
189void aoecmd_sleepwork(struct work_struct *); 206void aoecmd_sleepwork(struct work_struct *);
190void aoecmd_cleanslate(struct aoedev *); 207void aoecmd_cleanslate(struct aoedev *);
208void aoecmd_exit(void);
209int aoecmd_init(void);
191struct sk_buff *aoecmd_ata_id(struct aoedev *); 210struct sk_buff *aoecmd_ata_id(struct aoedev *);
211void aoe_freetframe(struct frame *);
192 212
193int aoedev_init(void); 213int aoedev_init(void);
194void aoedev_exit(void); 214void aoedev_exit(void);
@@ -196,6 +216,7 @@ struct aoedev *aoedev_by_aoeaddr(int maj, int min);
196struct aoedev *aoedev_by_sysminor_m(ulong sysminor); 216struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
197void aoedev_downdev(struct aoedev *d); 217void aoedev_downdev(struct aoedev *d);
198int aoedev_flush(const char __user *str, size_t size); 218int aoedev_flush(const char __user *str, size_t size);
219void aoe_failbuf(struct aoedev *d, struct buf *buf);
199 220
200int aoenet_init(void); 221int aoenet_init(void);
201void aoenet_exit(void); 222void aoenet_exit(void);
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index e86d2062a164..f145388cb94a 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -86,10 +86,9 @@ revalidate(const char __user *str, size_t size)
86 if (copy_from_user(buf, str, size)) 86 if (copy_from_user(buf, str, size))
87 return -EFAULT; 87 return -EFAULT;
88 88
89 /* should be e%d.%d format */
90 n = sscanf(buf, "e%d.%d", &major, &minor); 89 n = sscanf(buf, "e%d.%d", &major, &minor);
91 if (n != 2) { 90 if (n != 2) {
92 printk(KERN_ERR "aoe: invalid device specification\n"); 91 pr_err("aoe: invalid device specification %s\n", buf);
93 return -EINVAL; 92 return -EINVAL;
94 } 93 }
95 d = aoedev_by_aoeaddr(major, minor); 94 d = aoedev_by_aoeaddr(major, minor);
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 9a58242290c0..59b333c902a6 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -12,10 +12,17 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/genhd.h> 13#include <linux/genhd.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/workqueue.h>
16#include <linux/kthread.h>
15#include <net/net_namespace.h> 17#include <net/net_namespace.h>
16#include <asm/unaligned.h> 18#include <asm/unaligned.h>
19#include <linux/uio.h>
17#include "aoe.h" 20#include "aoe.h"
18 21
22#define MAXIOC (8192) /* default meant to avoid most soft lockups */
23
24static void ktcomplete(struct frame *, struct sk_buff *);
25
19static int aoe_deadsecs = 60 * 3; 26static int aoe_deadsecs = 60 * 3;
20module_param(aoe_deadsecs, int, 0644); 27module_param(aoe_deadsecs, int, 0644);
21MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev."); 28MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
@@ -25,6 +32,15 @@ module_param(aoe_maxout, int, 0644);
25MODULE_PARM_DESC(aoe_maxout, 32MODULE_PARM_DESC(aoe_maxout,
26 "Only aoe_maxout outstanding packets for every MAC on eX.Y."); 33 "Only aoe_maxout outstanding packets for every MAC on eX.Y.");
27 34
35static wait_queue_head_t ktiowq;
36static struct ktstate kts;
37
38/* io completion queue */
39static struct {
40 struct list_head head;
41 spinlock_t lock;
42} iocq;
43
28static struct sk_buff * 44static struct sk_buff *
29new_skb(ulong len) 45new_skb(ulong len)
30{ 46{
@@ -41,15 +57,21 @@ new_skb(ulong len)
41} 57}
42 58
43static struct frame * 59static struct frame *
44getframe(struct aoetgt *t, int tag) 60getframe(struct aoetgt *t, u32 tag)
45{ 61{
46 struct frame *f, *e; 62 struct frame *f;
63 struct list_head *head, *pos, *nx;
64 u32 n;
47 65
48 f = t->frames; 66 n = tag % NFACTIVE;
49 e = f + t->nframes; 67 head = &t->factive[n];
50 for (; f<e; f++) 68 list_for_each_safe(pos, nx, head) {
51 if (f->tag == tag) 69 f = list_entry(pos, struct frame, head);
70 if (f->tag == tag) {
71 list_del(pos);
52 return f; 72 return f;
73 }
74 }
53 return NULL; 75 return NULL;
54} 76}
55 77
@@ -67,7 +89,7 @@ newtag(struct aoetgt *t)
67 return n |= (++t->lasttag & 0x7fff) << 16; 89 return n |= (++t->lasttag & 0x7fff) << 16;
68} 90}
69 91
70static int 92static u32
71aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h) 93aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
72{ 94{
73 u32 host_tag = newtag(t); 95 u32 host_tag = newtag(t);
@@ -129,75 +151,96 @@ skb_pool_get(struct aoedev *d)
129 return NULL; 151 return NULL;
130} 152}
131 153
132/* freeframe is where we do our load balancing so it's a little hairy. */ 154void
155aoe_freetframe(struct frame *f)
156{
157 struct aoetgt *t;
158
159 t = f->t;
160 f->buf = NULL;
161 f->bv = NULL;
162 f->r_skb = NULL;
163 list_add(&f->head, &t->ffree);
164}
165
133static struct frame * 166static struct frame *
134freeframe(struct aoedev *d) 167newtframe(struct aoedev *d, struct aoetgt *t)
135{ 168{
136 struct frame *f, *e, *rf; 169 struct frame *f;
137 struct aoetgt **t;
138 struct sk_buff *skb; 170 struct sk_buff *skb;
171 struct list_head *pos;
172
173 if (list_empty(&t->ffree)) {
174 if (t->falloc >= NSKBPOOLMAX*2)
175 return NULL;
176 f = kcalloc(1, sizeof(*f), GFP_ATOMIC);
177 if (f == NULL)
178 return NULL;
179 t->falloc++;
180 f->t = t;
181 } else {
182 pos = t->ffree.next;
183 list_del(pos);
184 f = list_entry(pos, struct frame, head);
185 }
186
187 skb = f->skb;
188 if (skb == NULL) {
189 f->skb = skb = new_skb(ETH_ZLEN);
190 if (!skb) {
191bail: aoe_freetframe(f);
192 return NULL;
193 }
194 }
195
196 if (atomic_read(&skb_shinfo(skb)->dataref) != 1) {
197 skb = skb_pool_get(d);
198 if (skb == NULL)
199 goto bail;
200 skb_pool_put(d, f->skb);
201 f->skb = skb;
202 }
203
204 skb->truesize -= skb->data_len;
205 skb_shinfo(skb)->nr_frags = skb->data_len = 0;
206 skb_trim(skb, 0);
207 return f;
208}
209
210static struct frame *
211newframe(struct aoedev *d)
212{
213 struct frame *f;
214 struct aoetgt *t, **tt;
215 int totout = 0;
139 216
140 if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */ 217 if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */
141 printk(KERN_ERR "aoe: NULL TARGETS!\n"); 218 printk(KERN_ERR "aoe: NULL TARGETS!\n");
142 return NULL; 219 return NULL;
143 } 220 }
144 t = d->tgt; 221 tt = d->tgt; /* last used target */
145 t++;
146 if (t >= &d->targets[NTARGETS] || !*t)
147 t = d->targets;
148 for (;;) { 222 for (;;) {
149 if ((*t)->nout < (*t)->maxout 223 tt++;
224 if (tt >= &d->targets[NTARGETS] || !*tt)
225 tt = d->targets;
226 t = *tt;
227 totout += t->nout;
228 if (t->nout < t->maxout
150 && t != d->htgt 229 && t != d->htgt
151 && (*t)->ifp->nd) { 230 && t->ifp->nd) {
152 rf = NULL; 231 f = newtframe(d, t);
153 f = (*t)->frames; 232 if (f) {
154 e = f + (*t)->nframes; 233 d->tgt = tt;
155 for (; f < e; f++) { 234 ifrotate(t);
156 if (f->tag != FREETAG)
157 continue;
158 skb = f->skb;
159 if (!skb
160 && !(f->skb = skb = new_skb(ETH_ZLEN)))
161 continue;
162 if (atomic_read(&skb_shinfo(skb)->dataref)
163 != 1) {
164 if (!rf)
165 rf = f;
166 continue;
167 }
168gotone: skb->truesize -= skb->data_len;
169 skb_shinfo(skb)->nr_frags = skb->data_len = 0;
170 skb_trim(skb, 0);
171 d->tgt = t;
172 ifrotate(*t);
173 return f; 235 return f;
174 } 236 }
175 /* Work can be done, but the network layer is
176 holding our precious packets. Try to grab
177 one from the pool. */
178 f = rf;
179 if (f == NULL) { /* more paranoia */
180 printk(KERN_ERR
181 "aoe: freeframe: %s.\n",
182 "unexpected null rf");
183 d->flags |= DEVFL_KICKME;
184 return NULL;
185 }
186 skb = skb_pool_get(d);
187 if (skb) {
188 skb_pool_put(d, f->skb);
189 f->skb = skb;
190 goto gotone;
191 }
192 (*t)->dataref++;
193 if ((*t)->nout == 0)
194 d->flags |= DEVFL_KICKME;
195 } 237 }
196 if (t == d->tgt) /* we've looped and found nada */ 238 if (tt == d->tgt) /* we've looped and found nada */
197 break; 239 break;
198 t++; 240 }
199 if (t >= &d->targets[NTARGETS] || !*t) 241 if (totout == 0) {
200 t = d->targets; 242 d->kicked++;
243 d->flags |= DEVFL_KICKME;
201 } 244 }
202 return NULL; 245 return NULL;
203} 246}
@@ -220,6 +263,16 @@ loop:
220 goto loop; 263 goto loop;
221} 264}
222 265
266static void
267fhash(struct frame *f)
268{
269 struct aoetgt *t = f->t;
270 u32 n;
271
272 n = f->tag % NFACTIVE;
273 list_add_tail(&f->head, &t->factive[n]);
274}
275
223static int 276static int
224aoecmd_ata_rw(struct aoedev *d) 277aoecmd_ata_rw(struct aoedev *d)
225{ 278{
@@ -236,7 +289,7 @@ aoecmd_ata_rw(struct aoedev *d)
236 writebit = 0x10; 289 writebit = 0x10;
237 extbit = 0x4; 290 extbit = 0x4;
238 291
239 f = freeframe(d); 292 f = newframe(d);
240 if (f == NULL) 293 if (f == NULL)
241 return 0; 294 return 0;
242 t = *d->tgt; 295 t = *d->tgt;
@@ -274,6 +327,7 @@ aoecmd_ata_rw(struct aoedev *d)
274 skb_put(skb, sizeof *h + sizeof *ah); 327 skb_put(skb, sizeof *h + sizeof *ah);
275 memset(h, 0, skb->len); 328 memset(h, 0, skb->len);
276 f->tag = aoehdr_atainit(d, t, h); 329 f->tag = aoehdr_atainit(d, t, h);
330 fhash(f);
277 t->nout++; 331 t->nout++;
278 f->waited = 0; 332 f->waited = 0;
279 f->buf = buf; 333 f->buf = buf;
@@ -358,14 +412,16 @@ cont:
358} 412}
359 413
360static void 414static void
361resend(struct aoedev *d, struct aoetgt *t, struct frame *f) 415resend(struct aoedev *d, struct frame *f)
362{ 416{
363 struct sk_buff *skb; 417 struct sk_buff *skb;
364 struct aoe_hdr *h; 418 struct aoe_hdr *h;
365 struct aoe_atahdr *ah; 419 struct aoe_atahdr *ah;
420 struct aoetgt *t;
366 char buf[128]; 421 char buf[128];
367 u32 n; 422 u32 n;
368 423
424 t = f->t;
369 ifrotate(t); 425 ifrotate(t);
370 n = newtag(t); 426 n = newtag(t);
371 skb = f->skb; 427 skb = f->skb;
@@ -379,28 +435,11 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
379 aoechr_error(buf); 435 aoechr_error(buf);
380 436
381 f->tag = n; 437 f->tag = n;
438 fhash(f);
382 h->tag = cpu_to_be32(n); 439 h->tag = cpu_to_be32(n);
383 memcpy(h->dst, t->addr, sizeof h->dst); 440 memcpy(h->dst, t->addr, sizeof h->dst);
384 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); 441 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
385 442
386 switch (ah->cmdstat) {
387 default:
388 break;
389 case ATA_CMD_PIO_READ:
390 case ATA_CMD_PIO_READ_EXT:
391 case ATA_CMD_PIO_WRITE:
392 case ATA_CMD_PIO_WRITE_EXT:
393 put_lba(ah, f->lba);
394
395 n = f->bcnt;
396 ah->scnt = n >> 9;
397 if (ah->aflags & AOEAFL_WRITE) {
398 skb_fillup(skb, f->bv, f->bv_off, n);
399 skb->len = sizeof *h + sizeof *ah + n;
400 skb->data_len = n;
401 skb->truesize += n;
402 }
403 }
404 skb->dev = t->ifp->nd; 443 skb->dev = t->ifp->nd;
405 skb = skb_clone(skb, GFP_ATOMIC); 444 skb = skb_clone(skb, GFP_ATOMIC);
406 if (skb == NULL) 445 if (skb == NULL)
@@ -409,7 +448,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
409} 448}
410 449
411static int 450static int
412tsince(int tag) 451tsince(u32 tag)
413{ 452{
414 int n; 453 int n;
415 454
@@ -463,26 +502,38 @@ ejectif(struct aoetgt *t, struct aoeif *ifp)
463static int 502static int
464sthtith(struct aoedev *d) 503sthtith(struct aoedev *d)
465{ 504{
466 struct frame *f, *e, *nf; 505 struct frame *f, *nf;
506 struct list_head *nx, *pos, *head;
467 struct sk_buff *skb; 507 struct sk_buff *skb;
468 struct aoetgt *ht = *d->htgt; 508 struct aoetgt *ht = d->htgt;
469 509 int i;
470 f = ht->frames; 510
471 e = f + ht->nframes; 511 for (i = 0; i < NFACTIVE; i++) {
472 for (; f < e; f++) { 512 head = &ht->factive[i];
473 if (f->tag == FREETAG) 513 list_for_each_safe(pos, nx, head) {
474 continue; 514 f = list_entry(pos, struct frame, head);
475 nf = freeframe(d); 515 nf = newframe(d);
476 if (!nf) 516 if (!nf)
477 return 0; 517 return 0;
478 skb = nf->skb; 518
479 *nf = *f; 519 /* remove frame from active list */
480 f->skb = skb; 520 list_del(pos);
481 f->tag = FREETAG; 521
482 nf->waited = 0; 522 /* reassign all pertinent bits to new outbound frame */
483 ht->nout--; 523 skb = nf->skb;
484 (*d->tgt)->nout++; 524 nf->skb = f->skb;
485 resend(d, *d->tgt, nf); 525 nf->buf = f->buf;
526 nf->bcnt = f->bcnt;
527 nf->lba = f->lba;
528 nf->bv = f->bv;
529 nf->bv_off = f->bv_off;
530 nf->waited = 0;
531 f->skb = skb;
532 aoe_freetframe(f);
533 ht->nout--;
534 nf->t->nout++;
535 resend(d, nf);
536 }
486 } 537 }
487 /* he's clean, he's useless. take away his interfaces */ 538 /* he's clean, he's useless. take away his interfaces */
488 memset(ht->ifs, 0, sizeof ht->ifs); 539 memset(ht->ifs, 0, sizeof ht->ifs);
@@ -507,9 +558,12 @@ rexmit_timer(ulong vp)
507 struct aoedev *d; 558 struct aoedev *d;
508 struct aoetgt *t, **tt, **te; 559 struct aoetgt *t, **tt, **te;
509 struct aoeif *ifp; 560 struct aoeif *ifp;
510 struct frame *f, *e; 561 struct frame *f;
562 struct list_head *head, *pos, *nx;
563 LIST_HEAD(flist);
511 register long timeout; 564 register long timeout;
512 ulong flags, n; 565 ulong flags, n;
566 int i;
513 567
514 d = (struct aoedev *) vp; 568 d = (struct aoedev *) vp;
515 569
@@ -523,41 +577,21 @@ rexmit_timer(ulong vp)
523 spin_unlock_irqrestore(&d->lock, flags); 577 spin_unlock_irqrestore(&d->lock, flags);
524 return; 578 return;
525 } 579 }
580
581 /* collect all frames to rexmit into flist */
526 tt = d->targets; 582 tt = d->targets;
527 te = tt + NTARGETS; 583 te = tt + NTARGETS;
528 for (; tt < te && *tt; tt++) { 584 for (; tt < te && *tt; tt++) {
529 t = *tt; 585 t = *tt;
530 f = t->frames; 586 for (i = 0; i < NFACTIVE; i++) {
531 e = f + t->nframes; 587 head = &t->factive[i];
532 for (; f < e; f++) { 588 list_for_each_safe(pos, nx, head) {
533 if (f->tag == FREETAG 589 f = list_entry(pos, struct frame, head);
534 || tsince(f->tag) < timeout) 590 if (tsince(f->tag) < timeout)
535 continue; 591 continue;
536 n = f->waited += timeout; 592 /* move to flist for later processing */
537 n /= HZ; 593 list_move_tail(pos, &flist);
538 if (n > aoe_deadsecs) {
539 /* waited too long. device failure. */
540 aoedev_downdev(d);
541 break;
542 }
543
544 if (n > HELPWAIT /* see if another target can help */
545 && (tt != d->targets || d->targets[1]))
546 d->htgt = tt;
547
548 if (t->nout == t->maxout) {
549 if (t->maxout > 1)
550 t->maxout--;
551 t->lastwadj = jiffies;
552 }
553
554 ifp = getif(t, f->skb->dev);
555 if (ifp && ++ifp->lost > (t->nframes << 1)
556 && (ifp != t->ifs || t->ifs[1].nd)) {
557 ejectif(t, ifp);
558 ifp = NULL;
559 } 594 }
560 resend(d, t, f);
561 } 595 }
562 596
563 /* window check */ 597 /* window check */
@@ -569,6 +603,44 @@ rexmit_timer(ulong vp)
569 } 603 }
570 } 604 }
571 605
606 /* process expired frames */
607 while (!list_empty(&flist)) {
608 pos = flist.next;
609 f = list_entry(pos, struct frame, head);
610 n = f->waited += timeout;
611 n /= HZ;
612 if (n > aoe_deadsecs) {
613 /* Waited too long. Device failure.
614 * Hang all frames on first hash bucket for downdev
615 * to clean up.
616 */
617 list_splice(&flist, &f->t->factive[0]);
618 aoedev_downdev(d);
619 break;
620 }
621 list_del(pos);
622
623 t = f->t;
624 if (n > HELPWAIT) {
625 /* see if another target can help */
626 if (d->ntargets > 1)
627 d->htgt = t;
628 }
629 if (t->nout == t->maxout) {
630 if (t->maxout > 1)
631 t->maxout--;
632 t->lastwadj = jiffies;
633 }
634
635 ifp = getif(t, f->skb->dev);
636 if (ifp && ++ifp->lost > (t->nframes << 1)
637 && (ifp != t->ifs || t->ifs[1].nd)) {
638 ejectif(t, ifp);
639 ifp = NULL;
640 }
641 resend(d, f);
642 }
643
572 if (!skb_queue_empty(&d->sendq)) { 644 if (!skb_queue_empty(&d->sendq)) {
573 n = d->rttavg <<= 1; 645 n = d->rttavg <<= 1;
574 if (n > MAXTIMER) 646 if (n > MAXTIMER)
@@ -750,7 +822,7 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
750} 822}
751 823
752static void 824static void
753bvcpy(struct bio_vec *bv, ulong off, struct sk_buff *skb, ulong cnt) 825bvcpy(struct bio_vec *bv, ulong off, struct sk_buff *skb, long cnt)
754{ 826{
755 ulong fcnt; 827 ulong fcnt;
756 char *p; 828 char *p;
@@ -771,60 +843,225 @@ loop:
771} 843}
772 844
773static void 845static void
774fadvance(struct frame *f, ulong cnt) 846ktiocomplete(struct frame *f)
775{ 847{
776 ulong fcnt; 848 struct aoe_hdr *hin, *hout;
849 struct aoe_atahdr *ahin, *ahout;
850 struct buf *buf;
851 struct sk_buff *skb;
852 struct aoetgt *t;
853 struct aoeif *ifp;
854 struct aoedev *d;
855 long n;
777 856
778 f->lba += cnt >> 9; 857 if (f == NULL)
779loop:
780 fcnt = f->bv->bv_len - (f->bv_off - f->bv->bv_offset);
781 if (fcnt > cnt) {
782 f->bv_off += cnt;
783 return; 858 return;
859
860 t = f->t;
861 d = t->d;
862
863 hout = (struct aoe_hdr *) skb_mac_header(f->skb);
864 ahout = (struct aoe_atahdr *) (hout+1);
865 buf = f->buf;
866 skb = f->r_skb;
867 if (skb == NULL)
868 goto noskb; /* just fail the buf. */
869
870 hin = (struct aoe_hdr *) skb->data;
871 skb_pull(skb, sizeof(*hin));
872 ahin = (struct aoe_atahdr *) skb->data;
873 skb_pull(skb, sizeof(*ahin));
874 if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
875 pr_err("aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n",
876 ahout->cmdstat, ahin->cmdstat,
877 d->aoemajor, d->aoeminor);
878noskb: if (buf)
879 buf->flags |= BUFFL_FAIL;
880 goto badrsp;
784 } 881 }
785 cnt -= fcnt; 882
786 f->bv++; 883 n = ahout->scnt << 9;
787 f->bv_off = f->bv->bv_offset; 884 switch (ahout->cmdstat) {
788 goto loop; 885 case ATA_CMD_PIO_READ:
886 case ATA_CMD_PIO_READ_EXT:
887 if (skb->len < n) {
888 pr_err("aoe: runt data size in read. skb->len=%d need=%ld\n",
889 skb->len, n);
890 buf->flags |= BUFFL_FAIL;
891 break;
892 }
893 bvcpy(f->bv, f->bv_off, skb, n);
894 case ATA_CMD_PIO_WRITE:
895 case ATA_CMD_PIO_WRITE_EXT:
896 spin_lock_irq(&d->lock);
897 ifp = getif(t, skb->dev);
898 if (ifp) {
899 ifp->lost = 0;
900 if (n > DEFAULTBCNT)
901 ifp->lostjumbo = 0;
902 }
903 if (d->htgt == t) /* I'll help myself, thank you. */
904 d->htgt = NULL;
905 spin_unlock_irq(&d->lock);
906 break;
907 case ATA_CMD_ID_ATA:
908 if (skb->len < 512) {
909 pr_info("aoe: runt data size in ataid. skb->len=%d\n",
910 skb->len);
911 break;
912 }
913 if (skb_linearize(skb))
914 break;
915 spin_lock_irq(&d->lock);
916 ataid_complete(d, t, skb->data);
917 spin_unlock_irq(&d->lock);
918 break;
919 default:
920 pr_info("aoe: unrecognized ata command %2.2Xh for %d.%d\n",
921 ahout->cmdstat,
922 be16_to_cpu(get_unaligned(&hin->major)),
923 hin->minor);
924 }
925badrsp:
926 spin_lock_irq(&d->lock);
927
928 aoe_freetframe(f);
929
930 if (buf && --buf->nframesout == 0 && buf->resid == 0) {
931 struct bio *bio = buf->bio;
932
933 diskstats(d->gd, bio, jiffies - buf->stime, buf->sector);
934 n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
935 mempool_free(buf, d->bufpool);
936 spin_unlock_irq(&d->lock);
937 if (n != -EIO)
938 bio_flush_dcache_pages(buf->bio);
939 bio_endio(bio, n);
940 } else
941 spin_unlock_irq(&d->lock);
942 dev_kfree_skb(skb);
789} 943}
790 944
791void 945/* Enters with iocq.lock held.
946 * Returns true iff responses needing processing remain.
947 */
948static int
949ktio(void)
950{
951 struct frame *f;
952 struct list_head *pos;
953 int i;
954
955 for (i = 0; ; ++i) {
956 if (i == MAXIOC)
957 return 1;
958 if (list_empty(&iocq.head))
959 return 0;
960 pos = iocq.head.next;
961 list_del(pos);
962 spin_unlock_irq(&iocq.lock);
963 f = list_entry(pos, struct frame, head);
964 ktiocomplete(f);
965 spin_lock_irq(&iocq.lock);
966 }
967}
968
969static int
970kthread(void *vp)
971{
972 struct ktstate *k;
973 DECLARE_WAITQUEUE(wait, current);
974 int more;
975
976 k = vp;
977 current->flags |= PF_NOFREEZE;
978 set_user_nice(current, -10);
979 complete(&k->rendez); /* tell spawner we're running */
980 do {
981 spin_lock_irq(k->lock);
982 more = k->fn();
983 if (!more) {
984 add_wait_queue(k->waitq, &wait);
985 __set_current_state(TASK_INTERRUPTIBLE);
986 }
987 spin_unlock_irq(k->lock);
988 if (!more) {
989 schedule();
990 remove_wait_queue(k->waitq, &wait);
991 } else
992 cond_resched();
993 } while (!kthread_should_stop());
994 complete(&k->rendez); /* tell spawner we're stopping */
995 return 0;
996}
997
998static void
999aoe_ktstop(struct ktstate *k)
1000{
1001 kthread_stop(k->task);
1002 wait_for_completion(&k->rendez);
1003}
1004
1005static int
1006aoe_ktstart(struct ktstate *k)
1007{
1008 struct task_struct *task;
1009
1010 init_completion(&k->rendez);
1011 task = kthread_run(kthread, k, k->name);
1012 if (task == NULL || IS_ERR(task))
1013 return -ENOMEM;
1014 k->task = task;
1015 wait_for_completion(&k->rendez); /* allow kthread to start */
1016 init_completion(&k->rendez); /* for waiting for exit later */
1017 return 0;
1018}
1019
1020/* pass it off to kthreads for processing */
1021static void
1022ktcomplete(struct frame *f, struct sk_buff *skb)
1023{
1024 ulong flags;
1025
1026 f->r_skb = skb;
1027 spin_lock_irqsave(&iocq.lock, flags);
1028 list_add_tail(&f->head, &iocq.head);
1029 spin_unlock_irqrestore(&iocq.lock, flags);
1030 wake_up(&ktiowq);
1031}
1032
1033struct sk_buff *
792aoecmd_ata_rsp(struct sk_buff *skb) 1034aoecmd_ata_rsp(struct sk_buff *skb)
793{ 1035{
794 struct sk_buff_head queue;
795 struct aoedev *d; 1036 struct aoedev *d;
796 struct aoe_hdr *hin, *hout; 1037 struct aoe_hdr *h;
797 struct aoe_atahdr *ahin, *ahout;
798 struct frame *f; 1038 struct frame *f;
799 struct buf *buf;
800 struct aoetgt *t; 1039 struct aoetgt *t;
801 struct aoeif *ifp; 1040 u32 n;
802 register long n;
803 ulong flags; 1041 ulong flags;
804 char ebuf[128]; 1042 char ebuf[128];
805 u16 aoemajor; 1043 u16 aoemajor;
806 1044
807 hin = (struct aoe_hdr *) skb_mac_header(skb); 1045 h = (struct aoe_hdr *) skb->data;
808 skb_pull(skb, sizeof(*hin)); 1046 aoemajor = be16_to_cpu(get_unaligned(&h->major));
809 aoemajor = get_unaligned_be16(&hin->major); 1047 d = aoedev_by_aoeaddr(aoemajor, h->minor);
810 d = aoedev_by_aoeaddr(aoemajor, hin->minor);
811 if (d == NULL) { 1048 if (d == NULL) {
812 snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response " 1049 snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
813 "for unknown device %d.%d\n", 1050 "for unknown device %d.%d\n",
814 aoemajor, hin->minor); 1051 aoemajor, h->minor);
815 aoechr_error(ebuf); 1052 aoechr_error(ebuf);
816 return; 1053 return skb;
817 } 1054 }
818 1055
819 spin_lock_irqsave(&d->lock, flags); 1056 spin_lock_irqsave(&d->lock, flags);
820 1057
821 n = get_unaligned_be32(&hin->tag); 1058 n = be32_to_cpu(get_unaligned(&h->tag));
822 t = gettgt(d, hin->src); 1059 t = gettgt(d, h->src);
823 if (t == NULL) { 1060 if (t == NULL) {
824 printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n", 1061 printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n",
825 d->aoemajor, d->aoeminor, hin->src); 1062 d->aoemajor, d->aoeminor, h->src);
826 spin_unlock_irqrestore(&d->lock, flags); 1063 spin_unlock_irqrestore(&d->lock, flags);
827 return; 1064 return skb;
828 } 1065 }
829 f = getframe(t, n); 1066 f = getframe(t, n);
830 if (f == NULL) { 1067 if (f == NULL) {
@@ -833,102 +1070,26 @@ aoecmd_ata_rsp(struct sk_buff *skb)
833 snprintf(ebuf, sizeof ebuf, 1070 snprintf(ebuf, sizeof ebuf,
834 "%15s e%d.%d tag=%08x@%08lx\n", 1071 "%15s e%d.%d tag=%08x@%08lx\n",
835 "unexpected rsp", 1072 "unexpected rsp",
836 get_unaligned_be16(&hin->major), 1073 get_unaligned_be16(&h->major),
837 hin->minor, 1074 h->minor,
838 get_unaligned_be32(&hin->tag), 1075 get_unaligned_be32(&h->tag),
839 jiffies); 1076 jiffies);
840 aoechr_error(ebuf); 1077 aoechr_error(ebuf);
841 return; 1078 return skb;
842 } 1079 }
843
844 calc_rttavg(d, tsince(f->tag)); 1080 calc_rttavg(d, tsince(f->tag));
845
846 ahin = (struct aoe_atahdr *) skb->data;
847 skb_pull(skb, sizeof(*ahin));
848 hout = (struct aoe_hdr *) skb_mac_header(f->skb);
849 ahout = (struct aoe_atahdr *) (hout+1);
850 buf = f->buf;
851
852 if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
853 printk(KERN_ERR
854 "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n",
855 ahout->cmdstat, ahin->cmdstat,
856 d->aoemajor, d->aoeminor);
857 if (buf)
858 buf->flags |= BUFFL_FAIL;
859 } else {
860 if (d->htgt && t == *d->htgt) /* I'll help myself, thank you. */
861 d->htgt = NULL;
862 n = ahout->scnt << 9;
863 switch (ahout->cmdstat) {
864 case ATA_CMD_PIO_READ:
865 case ATA_CMD_PIO_READ_EXT:
866 if (skb->len < n) {
867 printk(KERN_ERR
868 "aoe: %s. skb->len=%d need=%ld\n",
869 "runt data size in read", skb->len, n);
870 /* fail frame f? just returning will rexmit. */
871 spin_unlock_irqrestore(&d->lock, flags);
872 return;
873 }
874 bvcpy(f->bv, f->bv_off, skb, n);
875 case ATA_CMD_PIO_WRITE:
876 case ATA_CMD_PIO_WRITE_EXT:
877 ifp = getif(t, skb->dev);
878 if (ifp) {
879 ifp->lost = 0;
880 if (n > DEFAULTBCNT)
881 ifp->lostjumbo = 0;
882 }
883 if (f->bcnt -= n) {
884 fadvance(f, n);
885 resend(d, t, f);
886 goto xmit;
887 }
888 break;
889 case ATA_CMD_ID_ATA:
890 if (skb->len < 512) {
891 printk(KERN_INFO
892 "aoe: runt data size in ataid. skb->len=%d\n",
893 skb->len);
894 spin_unlock_irqrestore(&d->lock, flags);
895 return;
896 }
897 if (skb_linearize(skb))
898 break;
899 ataid_complete(d, t, skb->data);
900 break;
901 default:
902 printk(KERN_INFO
903 "aoe: unrecognized ata command %2.2Xh for %d.%d\n",
904 ahout->cmdstat,
905 get_unaligned_be16(&hin->major),
906 hin->minor);
907 }
908 }
909
910 if (buf && --buf->nframesout == 0 && buf->resid == 0) {
911 diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
912 if (buf->flags & BUFFL_FAIL)
913 bio_endio(buf->bio, -EIO);
914 else {
915 bio_flush_dcache_pages(buf->bio);
916 bio_endio(buf->bio, 0);
917 }
918 mempool_free(buf, d->bufpool);
919 }
920
921 f->buf = NULL;
922 f->tag = FREETAG;
923 t->nout--; 1081 t->nout--;
924
925 aoecmd_work(d); 1082 aoecmd_work(d);
926xmit:
927 __skb_queue_head_init(&queue);
928 skb_queue_splice_init(&d->sendq, &queue);
929 1083
930 spin_unlock_irqrestore(&d->lock, flags); 1084 spin_unlock_irqrestore(&d->lock, flags);
931 aoenet_xmit(&queue); 1085
1086 ktcomplete(f, skb);
1087
1088 /*
1089 * Note here that we do not perform an aoedev_put, as we are
1090 * leaving this reference for the ktio to release.
1091 */
1092 return NULL;
932} 1093}
933 1094
934void 1095void
@@ -950,7 +1111,7 @@ aoecmd_ata_id(struct aoedev *d)
950 struct sk_buff *skb; 1111 struct sk_buff *skb;
951 struct aoetgt *t; 1112 struct aoetgt *t;
952 1113
953 f = freeframe(d); 1114 f = newframe(d);
954 if (f == NULL) 1115 if (f == NULL)
955 return NULL; 1116 return NULL;
956 1117
@@ -963,6 +1124,7 @@ aoecmd_ata_id(struct aoedev *d)
963 skb_put(skb, sizeof *h + sizeof *ah); 1124 skb_put(skb, sizeof *h + sizeof *ah);
964 memset(h, 0, skb->len); 1125 memset(h, 0, skb->len);
965 f->tag = aoehdr_atainit(d, t, h); 1126 f->tag = aoehdr_atainit(d, t, h);
1127 fhash(f);
966 t->nout++; 1128 t->nout++;
967 f->waited = 0; 1129 f->waited = 0;
968 1130
@@ -983,7 +1145,7 @@ static struct aoetgt *
983addtgt(struct aoedev *d, char *addr, ulong nframes) 1145addtgt(struct aoedev *d, char *addr, ulong nframes)
984{ 1146{
985 struct aoetgt *t, **tt, **te; 1147 struct aoetgt *t, **tt, **te;
986 struct frame *f, *e; 1148 int i;
987 1149
988 tt = d->targets; 1150 tt = d->targets;
989 te = tt + NTARGETS; 1151 te = tt + NTARGETS;
@@ -995,23 +1157,21 @@ addtgt(struct aoedev *d, char *addr, ulong nframes)
995 "aoe: device addtgt failure; too many targets\n"); 1157 "aoe: device addtgt failure; too many targets\n");
996 return NULL; 1158 return NULL;
997 } 1159 }
998 t = kcalloc(1, sizeof *t, GFP_ATOMIC); 1160 t = kzalloc(sizeof(*t), GFP_ATOMIC);
999 f = kcalloc(nframes, sizeof *f, GFP_ATOMIC); 1161 if (!t) {
1000 if (!t || !f) {
1001 kfree(f);
1002 kfree(t);
1003 printk(KERN_INFO "aoe: cannot allocate memory to add target\n"); 1162 printk(KERN_INFO "aoe: cannot allocate memory to add target\n");
1004 return NULL; 1163 return NULL;
1005 } 1164 }
1006 1165
1166 d->ntargets++;
1007 t->nframes = nframes; 1167 t->nframes = nframes;
1008 t->frames = f; 1168 t->d = d;
1009 e = f + nframes;
1010 for (; f < e; f++)
1011 f->tag = FREETAG;
1012 memcpy(t->addr, addr, sizeof t->addr); 1169 memcpy(t->addr, addr, sizeof t->addr);
1013 t->ifp = t->ifs; 1170 t->ifp = t->ifs;
1014 t->maxout = t->nframes; 1171 t->maxout = t->nframes;
1172 INIT_LIST_HEAD(&t->ffree);
1173 for (i = 0; i < NFACTIVE; ++i)
1174 INIT_LIST_HEAD(&t->factive[i]);
1015 return *tt = t; 1175 return *tt = t;
1016} 1176}
1017 1177
@@ -1136,3 +1296,53 @@ aoecmd_cleanslate(struct aoedev *d)
1136 } 1296 }
1137 } 1297 }
1138} 1298}
1299
1300static void
1301flush_iocq(void)
1302{
1303 struct frame *f;
1304 struct aoedev *d;
1305 LIST_HEAD(flist);
1306 struct list_head *pos;
1307 struct sk_buff *skb;
1308 ulong flags;
1309
1310 spin_lock_irqsave(&iocq.lock, flags);
1311 list_splice_init(&iocq.head, &flist);
1312 spin_unlock_irqrestore(&iocq.lock, flags);
1313 while (!list_empty(&flist)) {
1314 pos = flist.next;
1315 list_del(pos);
1316 f = list_entry(pos, struct frame, head);
1317 d = f->t->d;
1318 skb = f->r_skb;
1319 spin_lock_irqsave(&d->lock, flags);
1320 if (f->buf) {
1321 f->buf->nframesout--;
1322 aoe_failbuf(d, f->buf);
1323 }
1324 aoe_freetframe(f);
1325 spin_unlock_irqrestore(&d->lock, flags);
1326 dev_kfree_skb(skb);
1327 }
1328}
1329
1330int __init
1331aoecmd_init(void)
1332{
1333 INIT_LIST_HEAD(&iocq.head);
1334 spin_lock_init(&iocq.lock);
1335 init_waitqueue_head(&ktiowq);
1336 kts.name = "aoe_ktio";
1337 kts.fn = ktio;
1338 kts.waitq = &ktiowq;
1339 kts.lock = &iocq.lock;
1340 return aoe_ktstart(&kts);
1341}
1342
1343void
1344aoecmd_exit(void)
1345{
1346 aoe_ktstop(&kts);
1347 flush_iocq();
1348}
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index b2d1fd354eac..40bae1a1ff1e 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -48,47 +48,60 @@ dummy_timer(ulong vp)
48} 48}
49 49
50void 50void
51aoedev_downdev(struct aoedev *d) 51aoe_failbuf(struct aoedev *d, struct buf *buf)
52{ 52{
53 struct aoetgt **t, **te;
54 struct frame *f, *e;
55 struct buf *buf;
56 struct bio *bio; 53 struct bio *bio;
57 54
58 t = d->targets; 55 if (buf == NULL)
59 te = t + NTARGETS; 56 return;
60 for (; t < te && *t; t++) { 57 buf->flags |= BUFFL_FAIL;
61 f = (*t)->frames; 58 if (buf->nframesout == 0) {
62 e = f + (*t)->nframes; 59 if (buf == d->inprocess) /* ensure we only process this once */
63 for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) { 60 d->inprocess = NULL;
64 if (f->tag == FREETAG || f->buf == NULL)
65 continue;
66 buf = f->buf;
67 bio = buf->bio;
68 if (--buf->nframesout == 0
69 && buf != d->inprocess) {
70 mempool_free(buf, d->bufpool);
71 bio_endio(bio, -EIO);
72 }
73 }
74 (*t)->maxout = (*t)->nframes;
75 (*t)->nout = 0;
76 }
77 buf = d->inprocess;
78 if (buf) {
79 bio = buf->bio; 61 bio = buf->bio;
80 mempool_free(buf, d->bufpool); 62 mempool_free(buf, d->bufpool);
81 bio_endio(bio, -EIO); 63 bio_endio(bio, -EIO);
82 } 64 }
65}
66
67void
68aoedev_downdev(struct aoedev *d)
69{
70 struct aoetgt *t, **tt, **te;
71 struct frame *f;
72 struct list_head *head, *pos, *nx;
73 int i;
74
75 /* clean out active buffers on all targets */
76 tt = d->targets;
77 te = tt + NTARGETS;
78 for (; tt < te && (t = *tt); tt++) {
79 for (i = 0; i < NFACTIVE; i++) {
80 head = &t->factive[i];
81 list_for_each_safe(pos, nx, head) {
82 list_del(pos);
83 f = list_entry(pos, struct frame, head);
84 if (f->buf) {
85 f->buf->nframesout--;
86 aoe_failbuf(d, f->buf);
87 }
88 aoe_freetframe(f);
89 }
90 }
91 t->maxout = t->nframes;
92 t->nout = 0;
93 }
94
95 /* clean out the in-process buffer (if any) */
96 aoe_failbuf(d, d->inprocess);
83 d->inprocess = NULL; 97 d->inprocess = NULL;
84 d->htgt = NULL; 98 d->htgt = NULL;
85 99
100 /* clean out all pending I/O */
86 while (!list_empty(&d->bufq)) { 101 while (!list_empty(&d->bufq)) {
87 buf = container_of(d->bufq.next, struct buf, bufs); 102 struct buf *buf = container_of(d->bufq.next, struct buf, bufs);
88 list_del(d->bufq.next); 103 list_del(d->bufq.next);
89 bio = buf->bio; 104 aoe_failbuf(d, buf);
90 mempool_free(buf, d->bufpool);
91 bio_endio(bio, -EIO);
92 } 105 }
93 106
94 if (d->gd) 107 if (d->gd)
@@ -242,13 +255,16 @@ aoedev_by_sysminor_m(ulong sysminor)
242static void 255static void
243freetgt(struct aoedev *d, struct aoetgt *t) 256freetgt(struct aoedev *d, struct aoetgt *t)
244{ 257{
245 struct frame *f, *e; 258 struct frame *f;
259 struct list_head *pos, *nx, *head;
246 260
247 f = t->frames; 261 head = &t->ffree;
248 e = f + t->nframes; 262 list_for_each_safe(pos, nx, head) {
249 for (; f < e; f++) 263 list_del(pos);
264 f = list_entry(pos, struct frame, head);
250 skbfree(f->skb); 265 skbfree(f->skb);
251 kfree(t->frames); 266 kfree(f);
267 }
252 kfree(t); 268 kfree(t);
253} 269}
254 270
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
index 7f83ad90e76f..6fc4b050fab1 100644
--- a/drivers/block/aoe/aoemain.c
+++ b/drivers/block/aoe/aoemain.c
@@ -61,6 +61,7 @@ aoe_exit(void)
61 61
62 aoenet_exit(); 62 aoenet_exit();
63 unregister_blkdev(AOE_MAJOR, DEVICE_NAME); 63 unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
64 aoecmd_exit();
64 aoechr_exit(); 65 aoechr_exit();
65 aoedev_exit(); 66 aoedev_exit();
66 aoeblk_exit(); /* free cache after de-allocating bufs */ 67 aoeblk_exit(); /* free cache after de-allocating bufs */
@@ -83,17 +84,20 @@ aoe_init(void)
83 ret = aoenet_init(); 84 ret = aoenet_init();
84 if (ret) 85 if (ret)
85 goto net_fail; 86 goto net_fail;
87 ret = aoecmd_init();
88 if (ret)
89 goto cmd_fail;
86 ret = register_blkdev(AOE_MAJOR, DEVICE_NAME); 90 ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
87 if (ret < 0) { 91 if (ret < 0) {
88 printk(KERN_ERR "aoe: can't register major\n"); 92 printk(KERN_ERR "aoe: can't register major\n");
89 goto blkreg_fail; 93 goto blkreg_fail;
90 } 94 }
91
92 printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION); 95 printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
93 discover_timer(TINIT); 96 discover_timer(TINIT);
94 return 0; 97 return 0;
95
96 blkreg_fail: 98 blkreg_fail:
99 aoecmd_exit();
100 cmd_fail:
97 aoenet_exit(); 101 aoenet_exit();
98 net_fail: 102 net_fail:
99 aoeblk_exit(); 103 aoeblk_exit();
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 07878076e43c..000eff2b53a8 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -142,7 +142,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
142 142
143 switch (h->cmd) { 143 switch (h->cmd) {
144 case AOECMD_ATA: 144 case AOECMD_ATA:
145 aoecmd_ata_rsp(skb); 145 /* ata_rsp may keep skb for later processing or give it back */
146 skb = aoecmd_ata_rsp(skb);
146 break; 147 break;
147 case AOECMD_CFG: 148 case AOECMD_CFG:
148 aoecmd_cfg_rsp(skb); 149 aoecmd_cfg_rsp(skb);
@@ -152,6 +153,9 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
152 break; /* don't complain about vendor commands */ 153 break; /* don't complain about vendor commands */
153 printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); 154 printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
154 } 155 }
156
157 if (!skb)
158 return 0;
155exit: 159exit:
156 dev_kfree_skb(skb); 160 dev_kfree_skb(skb);
157 return 0; 161 return 0;