aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe
diff options
context:
space:
mode:
authorEd Cashin <ecashin@coraid.com>2012-10-04 20:16:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 14:05:27 -0400
commit64a80f5ac78a289f66c373ace61973205d960ee7 (patch)
tree3a8b9f5c1860acd8bab6d022dbbca32985e228ee /drivers/block/aoe
parent6583303c5e324a918ee1d57201acd9869f3be6da (diff)
aoe: associate frames with the AoE storage target
In the driver code, "target" and aoetgt refer to a particular remote interface on the AoE storage target. The latter is identified by its AoE major and minor addresses. Commands that are being sent to an AoE storage target {major, minor} can be sent or retransmitted to any of the remote MAC addresses associated with the AoE storage target. That is, frames are naturally associated with not an aoetgt (AoE major, AoE minor, remote MAC address) but an aoedev (AoE major, AoE minor). Making the code reflect that reality simplifies the driver, especially when the path to a remote MAC address becomes unusable. Signed-off-by: Ed Cashin <ecashin@coraid.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')
-rw-r--r--drivers/block/aoe/aoe.h8
-rw-r--r--drivers/block/aoe/aoecmd.c65
-rw-r--r--drivers/block/aoe/aoedev.c30
3 files changed, 49 insertions, 54 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index d17b72763973..dab7258ddb26 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -91,7 +91,7 @@ enum {
91 NTARGETS = 8, 91 NTARGETS = 8,
92 NAOEIFS = 8, 92 NAOEIFS = 8,
93 NSKBPOOLMAX = 256, 93 NSKBPOOLMAX = 256,
94 NFACTIVE = 17, 94 NFACTIVE = 61,
95 95
96 TIMERTICK = HZ / 10, 96 TIMERTICK = HZ / 10,
97 MINTIMER = HZ >> 2, 97 MINTIMER = HZ >> 2,
@@ -132,14 +132,11 @@ struct aoetgt {
132 unsigned char addr[6]; 132 unsigned char addr[6];
133 ushort nframes; 133 ushort nframes;
134 struct aoedev *d; /* parent device I belong to */ 134 struct aoedev *d; /* parent device I belong to */
135 struct list_head factive[NFACTIVE]; /* hash of active frames */
136 struct list_head ffree; /* list of free frames */ 135 struct list_head ffree; /* list of free frames */
137 struct aoeif ifs[NAOEIFS]; 136 struct aoeif ifs[NAOEIFS];
138 struct aoeif *ifp; /* current aoeif in use */ 137 struct aoeif *ifp; /* current aoeif in use */
139 ushort nout; 138 ushort nout;
140 ushort maxout; 139 ushort maxout;
141 u16 lasttag; /* last tag sent */
142 u16 useme;
143 ulong falloc; 140 ulong falloc;
144 ulong lastwadj; /* last window adjustment */ 141 ulong lastwadj; /* last window adjustment */
145 int minbcnt; 142 int minbcnt;
@@ -156,6 +153,8 @@ struct aoedev {
156 u16 rttavg; /* round trip average of requests/responses */ 153 u16 rttavg; /* round trip average of requests/responses */
157 u16 mintimer; 154 u16 mintimer;
158 u16 fw_ver; /* version of blade's firmware */ 155 u16 fw_ver; /* version of blade's firmware */
156 u16 lasttag; /* last tag sent */
157 u16 useme;
159 ulong ref; 158 ulong ref;
160 struct work_struct work;/* disk create work struct */ 159 struct work_struct work;/* disk create work struct */
161 struct gendisk *gd; 160 struct gendisk *gd;
@@ -172,6 +171,7 @@ struct aoedev {
172 struct request *rq; 171 struct request *rq;
173 } ip; 172 } ip;
174 ulong maxbcnt; 173 ulong maxbcnt;
174 struct list_head factive[NFACTIVE]; /* hash of active frames */
175 struct aoetgt *targets[NTARGETS]; 175 struct aoetgt *targets[NTARGETS];
176 struct aoetgt **tgt; /* target in use when working */ 176 struct aoetgt **tgt; /* target in use when working */
177 struct aoetgt *htgt; /* target needing rexmit assistance */ 177 struct aoetgt *htgt; /* target needing rexmit assistance */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 2a6a4316db00..cc692fee7ce1 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -59,14 +59,14 @@ new_skb(ulong len)
59} 59}
60 60
61static struct frame * 61static struct frame *
62getframe(struct aoetgt *t, u32 tag) 62getframe(struct aoedev *d, u32 tag)
63{ 63{
64 struct frame *f; 64 struct frame *f;
65 struct list_head *head, *pos, *nx; 65 struct list_head *head, *pos, *nx;
66 u32 n; 66 u32 n;
67 67
68 n = tag % NFACTIVE; 68 n = tag % NFACTIVE;
69 head = &t->factive[n]; 69 head = &d->factive[n];
70 list_for_each_safe(pos, nx, head) { 70 list_for_each_safe(pos, nx, head) {
71 f = list_entry(pos, struct frame, head); 71 f = list_entry(pos, struct frame, head);
72 if (f->tag == tag) { 72 if (f->tag == tag) {
@@ -83,18 +83,18 @@ getframe(struct aoetgt *t, u32 tag)
83 * This driver reserves tag -1 to mean "unused frame." 83 * This driver reserves tag -1 to mean "unused frame."
84 */ 84 */
85static int 85static int
86newtag(struct aoetgt *t) 86newtag(struct aoedev *d)
87{ 87{
88 register ulong n; 88 register ulong n;
89 89
90 n = jiffies & 0xffff; 90 n = jiffies & 0xffff;
91 return n |= (++t->lasttag & 0x7fff) << 16; 91 return n |= (++d->lasttag & 0x7fff) << 16;
92} 92}
93 93
94static u32 94static u32
95aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h) 95aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
96{ 96{
97 u32 host_tag = newtag(t); 97 u32 host_tag = newtag(d);
98 98
99 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); 99 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
100 memcpy(h->dst, t->addr, sizeof h->dst); 100 memcpy(h->dst, t->addr, sizeof h->dst);
@@ -270,11 +270,11 @@ loop:
270static void 270static void
271fhash(struct frame *f) 271fhash(struct frame *f)
272{ 272{
273 struct aoetgt *t = f->t; 273 struct aoedev *d = f->t->d;
274 u32 n; 274 u32 n;
275 275
276 n = f->tag % NFACTIVE; 276 n = f->tag % NFACTIVE;
277 list_add_tail(&f->head, &t->factive[n]); 277 list_add_tail(&f->head, &d->factive[n]);
278} 278}
279 279
280static int 280static int
@@ -433,7 +433,7 @@ resend(struct aoedev *d, struct frame *f)
433 u32 n; 433 u32 n;
434 434
435 t = f->t; 435 t = f->t;
436 n = newtag(t); 436 n = newtag(d);
437 skb = f->skb; 437 skb = f->skb;
438 if (ifrotate(t) == NULL) { 438 if (ifrotate(t) == NULL) {
439 /* probably can't happen, but set it up to fail anyway */ 439 /* probably can't happen, but set it up to fail anyway */
@@ -512,9 +512,12 @@ sthtith(struct aoedev *d)
512 int i; 512 int i;
513 513
514 for (i = 0; i < NFACTIVE; i++) { 514 for (i = 0; i < NFACTIVE; i++) {
515 head = &ht->factive[i]; 515 head = &d->factive[i];
516 list_for_each_safe(pos, nx, head) { 516 list_for_each_safe(pos, nx, head) {
517 f = list_entry(pos, struct frame, head); 517 f = list_entry(pos, struct frame, head);
518 if (f->t != ht)
519 continue;
520
518 nf = newframe(d); 521 nf = newframe(d);
519 if (!nf) 522 if (!nf)
520 return 0; 523 return 0;
@@ -585,22 +588,20 @@ rexmit_timer(ulong vp)
585 } 588 }
586 589
587 /* collect all frames to rexmit into flist */ 590 /* collect all frames to rexmit into flist */
588 tt = d->targets; 591 for (i = 0; i < NFACTIVE; i++) {
589 te = tt + NTARGETS; 592 head = &d->factive[i];
590 for (; tt < te && *tt; tt++) { 593 list_for_each_safe(pos, nx, head) {
591 t = *tt; 594 f = list_entry(pos, struct frame, head);
592 for (i = 0; i < NFACTIVE; i++) { 595 if (tsince(f->tag) < timeout)
593 head = &t->factive[i]; 596 break; /* end of expired frames */
594 list_for_each_safe(pos, nx, head) { 597 /* move to flist for later processing */
595 f = list_entry(pos, struct frame, head); 598 list_move_tail(pos, &flist);
596 if (tsince(f->tag) < timeout)
597 continue;
598 /* move to flist for later processing */
599 list_move_tail(pos, &flist);
600 }
601 } 599 }
602 600 }
603 /* window check */ 601 /* window check */
602 tt = d->targets;
603 te = tt + d->ntargets;
604 for (; tt < te && (t = *tt); tt++) {
604 if (t->nout == t->maxout 605 if (t->nout == t->maxout
605 && t->maxout < t->nframes 606 && t->maxout < t->nframes
606 && (jiffies - t->lastwadj)/HZ > 10) { 607 && (jiffies - t->lastwadj)/HZ > 10) {
@@ -626,7 +627,7 @@ rexmit_timer(ulong vp)
626 * Hang all frames on first hash bucket for downdev 627 * Hang all frames on first hash bucket for downdev
627 * to clean up. 628 * to clean up.
628 */ 629 */
629 list_splice(&flist, &f->t->factive[0]); 630 list_splice(&flist, &d->factive[0]);
630 aoedev_downdev(d); 631 aoedev_downdev(d);
631 break; 632 break;
632 } 633 }
@@ -1162,15 +1163,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
1162 spin_lock_irqsave(&d->lock, flags); 1163 spin_lock_irqsave(&d->lock, flags);
1163 1164
1164 n = be32_to_cpu(get_unaligned(&h->tag)); 1165 n = be32_to_cpu(get_unaligned(&h->tag));
1165 t = gettgt(d, h->src); 1166 f = getframe(d, n);
1166 if (t == NULL) {
1167 printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n",
1168 d->aoemajor, d->aoeminor, h->src);
1169 spin_unlock_irqrestore(&d->lock, flags);
1170 aoedev_put(d);
1171 return skb;
1172 }
1173 f = getframe(t, n);
1174 if (f == NULL) { 1167 if (f == NULL) {
1175 calc_rttavg(d, -tsince(n)); 1168 calc_rttavg(d, -tsince(n));
1176 spin_unlock_irqrestore(&d->lock, flags); 1169 spin_unlock_irqrestore(&d->lock, flags);
@@ -1185,6 +1178,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
1185 aoechr_error(ebuf); 1178 aoechr_error(ebuf);
1186 return skb; 1179 return skb;
1187 } 1180 }
1181 t = f->t;
1188 calc_rttavg(d, tsince(f->tag)); 1182 calc_rttavg(d, tsince(f->tag));
1189 t->nout--; 1183 t->nout--;
1190 aoecmd_work(d); 1184 aoecmd_work(d);
@@ -1253,7 +1247,6 @@ static struct aoetgt *
1253addtgt(struct aoedev *d, char *addr, ulong nframes) 1247addtgt(struct aoedev *d, char *addr, ulong nframes)
1254{ 1248{
1255 struct aoetgt *t, **tt, **te; 1249 struct aoetgt *t, **tt, **te;
1256 int i;
1257 1250
1258 tt = d->targets; 1251 tt = d->targets;
1259 te = tt + NTARGETS; 1252 te = tt + NTARGETS;
@@ -1278,8 +1271,6 @@ addtgt(struct aoedev *d, char *addr, ulong nframes)
1278 t->ifp = t->ifs; 1271 t->ifp = t->ifs;
1279 t->maxout = t->nframes; 1272 t->maxout = t->nframes;
1280 INIT_LIST_HEAD(&t->ffree); 1273 INIT_LIST_HEAD(&t->ffree);
1281 for (i = 0; i < NFACTIVE; ++i)
1282 INIT_LIST_HEAD(&t->factive[i]);
1283 return *tt = t; 1274 return *tt = t;
1284} 1275}
1285 1276
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index 635dc986cf77..3968fe6c0077 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -103,22 +103,23 @@ aoedev_downdev(struct aoedev *d)
103 103
104 d->flags &= ~DEVFL_UP; 104 d->flags &= ~DEVFL_UP;
105 105
106 /* clean out active buffers on all targets */ 106 /* clean out active buffers */
107 for (i = 0; i < NFACTIVE; i++) {
108 head = &d->factive[i];
109 list_for_each_safe(pos, nx, head) {
110 f = list_entry(pos, struct frame, head);
111 list_del(pos);
112 if (f->buf) {
113 f->buf->nframesout--;
114 aoe_failbuf(d, f->buf);
115 }
116 aoe_freetframe(f);
117 }
118 }
119 /* reset window dressings */
107 tt = d->targets; 120 tt = d->targets;
108 te = tt + NTARGETS; 121 te = tt + NTARGETS;
109 for (; tt < te && (t = *tt); tt++) { 122 for (; tt < te && (t = *tt); tt++) {
110 for (i = 0; i < NFACTIVE; i++) {
111 head = &t->factive[i];
112 list_for_each_safe(pos, nx, head) {
113 list_del(pos);
114 f = list_entry(pos, struct frame, head);
115 if (f->buf) {
116 f->buf->nframesout--;
117 aoe_failbuf(d, f->buf);
118 }
119 aoe_freetframe(f);
120 }
121 }
122 t->maxout = t->nframes; 123 t->maxout = t->nframes;
123 t->nout = 0; 124 t->nout = 0;
124 } 125 }
@@ -250,6 +251,7 @@ struct aoedev *
250aoedev_by_sysminor_m(ulong sysminor) 251aoedev_by_sysminor_m(ulong sysminor)
251{ 252{
252 struct aoedev *d; 253 struct aoedev *d;
254 int i;
253 ulong flags; 255 ulong flags;
254 256
255 spin_lock_irqsave(&devlist_lock, flags); 257 spin_lock_irqsave(&devlist_lock, flags);
@@ -275,6 +277,8 @@ aoedev_by_sysminor_m(ulong sysminor)
275 d->bufpool = NULL; /* defer to aoeblk_gdalloc */ 277 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
276 d->tgt = d->targets; 278 d->tgt = d->targets;
277 d->ref = 1; 279 d->ref = 1;
280 for (i = 0; i < NFACTIVE; i++)
281 INIT_LIST_HEAD(&d->factive[i]);
278 d->sysminor = sysminor; 282 d->sysminor = sysminor;
279 d->aoemajor = AOEMAJOR(sysminor); 283 d->aoemajor = AOEMAJOR(sysminor);
280 d->aoeminor = AOEMINOR(sysminor); 284 d->aoeminor = AOEMINOR(sysminor);