Commit 64a80f5a authored by Ed Cashin's avatar Ed Cashin Committed by Linus Torvalds

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: default avatarEd Cashin <ecashin@coraid.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6583303c
...@@ -91,7 +91,7 @@ enum { ...@@ -91,7 +91,7 @@ enum {
NTARGETS = 8, NTARGETS = 8,
NAOEIFS = 8, NAOEIFS = 8,
NSKBPOOLMAX = 256, NSKBPOOLMAX = 256,
NFACTIVE = 17, NFACTIVE = 61,
TIMERTICK = HZ / 10, TIMERTICK = HZ / 10,
MINTIMER = HZ >> 2, MINTIMER = HZ >> 2,
...@@ -132,14 +132,11 @@ struct aoetgt { ...@@ -132,14 +132,11 @@ struct aoetgt {
unsigned char addr[6]; unsigned char addr[6];
ushort nframes; ushort nframes;
struct aoedev *d; /* parent device I belong to */ struct aoedev *d; /* parent device I belong to */
struct list_head factive[NFACTIVE]; /* hash of active frames */
struct list_head ffree; /* list of free frames */ struct list_head ffree; /* list of free frames */
struct aoeif ifs[NAOEIFS]; struct aoeif ifs[NAOEIFS];
struct aoeif *ifp; /* current aoeif in use */ struct aoeif *ifp; /* current aoeif in use */
ushort nout; ushort nout;
ushort maxout; ushort maxout;
u16 lasttag; /* last tag sent */
u16 useme;
ulong falloc; ulong falloc;
ulong lastwadj; /* last window adjustment */ ulong lastwadj; /* last window adjustment */
int minbcnt; int minbcnt;
...@@ -156,6 +153,8 @@ struct aoedev { ...@@ -156,6 +153,8 @@ struct aoedev {
u16 rttavg; /* round trip average of requests/responses */ u16 rttavg; /* round trip average of requests/responses */
u16 mintimer; u16 mintimer;
u16 fw_ver; /* version of blade's firmware */ u16 fw_ver; /* version of blade's firmware */
u16 lasttag; /* last tag sent */
u16 useme;
ulong ref; ulong ref;
struct work_struct work;/* disk create work struct */ struct work_struct work;/* disk create work struct */
struct gendisk *gd; struct gendisk *gd;
...@@ -172,6 +171,7 @@ struct aoedev { ...@@ -172,6 +171,7 @@ struct aoedev {
struct request *rq; struct request *rq;
} ip; } ip;
ulong maxbcnt; ulong maxbcnt;
struct list_head factive[NFACTIVE]; /* hash of active frames */
struct aoetgt *targets[NTARGETS]; struct aoetgt *targets[NTARGETS];
struct aoetgt **tgt; /* target in use when working */ struct aoetgt **tgt; /* target in use when working */
struct aoetgt *htgt; /* target needing rexmit assistance */ struct aoetgt *htgt; /* target needing rexmit assistance */
......
...@@ -59,14 +59,14 @@ new_skb(ulong len) ...@@ -59,14 +59,14 @@ new_skb(ulong len)
} }
static struct frame * static struct frame *
getframe(struct aoetgt *t, u32 tag) getframe(struct aoedev *d, u32 tag)
{ {
struct frame *f; struct frame *f;
struct list_head *head, *pos, *nx; struct list_head *head, *pos, *nx;
u32 n; u32 n;
n = tag % NFACTIVE; n = tag % NFACTIVE;
head = &t->factive[n]; head = &d->factive[n];
list_for_each_safe(pos, nx, head) { list_for_each_safe(pos, nx, head) {
f = list_entry(pos, struct frame, head); f = list_entry(pos, struct frame, head);
if (f->tag == tag) { if (f->tag == tag) {
...@@ -83,18 +83,18 @@ getframe(struct aoetgt *t, u32 tag) ...@@ -83,18 +83,18 @@ getframe(struct aoetgt *t, u32 tag)
* This driver reserves tag -1 to mean "unused frame." * This driver reserves tag -1 to mean "unused frame."
*/ */
static int static int
newtag(struct aoetgt *t) newtag(struct aoedev *d)
{ {
register ulong n; register ulong n;
n = jiffies & 0xffff; n = jiffies & 0xffff;
return n |= (++t->lasttag & 0x7fff) << 16; return n |= (++d->lasttag & 0x7fff) << 16;
} }
static u32 static u32
aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h) aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
{ {
u32 host_tag = newtag(t); u32 host_tag = newtag(d);
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
memcpy(h->dst, t->addr, sizeof h->dst); memcpy(h->dst, t->addr, sizeof h->dst);
...@@ -270,11 +270,11 @@ skb_fillup(struct sk_buff *skb, struct bio_vec *bv, ulong off, ulong cnt) ...@@ -270,11 +270,11 @@ skb_fillup(struct sk_buff *skb, struct bio_vec *bv, ulong off, ulong cnt)
static void static void
fhash(struct frame *f) fhash(struct frame *f)
{ {
struct aoetgt *t = f->t; struct aoedev *d = f->t->d;
u32 n; u32 n;
n = f->tag % NFACTIVE; n = f->tag % NFACTIVE;
list_add_tail(&f->head, &t->factive[n]); list_add_tail(&f->head, &d->factive[n]);
} }
static int static int
...@@ -433,7 +433,7 @@ resend(struct aoedev *d, struct frame *f) ...@@ -433,7 +433,7 @@ resend(struct aoedev *d, struct frame *f)
u32 n; u32 n;
t = f->t; t = f->t;
n = newtag(t); n = newtag(d);
skb = f->skb; skb = f->skb;
if (ifrotate(t) == NULL) { if (ifrotate(t) == NULL) {
/* probably can't happen, but set it up to fail anyway */ /* probably can't happen, but set it up to fail anyway */
...@@ -512,9 +512,12 @@ sthtith(struct aoedev *d) ...@@ -512,9 +512,12 @@ sthtith(struct aoedev *d)
int i; int i;
for (i = 0; i < NFACTIVE; i++) { for (i = 0; i < NFACTIVE; i++) {
head = &ht->factive[i]; head = &d->factive[i];
list_for_each_safe(pos, nx, head) { list_for_each_safe(pos, nx, head) {
f = list_entry(pos, struct frame, head); f = list_entry(pos, struct frame, head);
if (f->t != ht)
continue;
nf = newframe(d); nf = newframe(d);
if (!nf) if (!nf)
return 0; return 0;
...@@ -585,22 +588,20 @@ rexmit_timer(ulong vp) ...@@ -585,22 +588,20 @@ rexmit_timer(ulong vp)
} }
/* collect all frames to rexmit into flist */ /* collect all frames to rexmit into flist */
tt = d->targets; for (i = 0; i < NFACTIVE; i++) {
te = tt + NTARGETS; head = &d->factive[i];
for (; tt < te && *tt; tt++) { list_for_each_safe(pos, nx, head) {
t = *tt; f = list_entry(pos, struct frame, head);
for (i = 0; i < NFACTIVE; i++) { if (tsince(f->tag) < timeout)
head = &t->factive[i]; break; /* end of expired frames */
list_for_each_safe(pos, nx, head) { /* move to flist for later processing */
f = list_entry(pos, struct frame, head); list_move_tail(pos, &flist);
if (tsince(f->tag) < timeout)
continue;
/* move to flist for later processing */
list_move_tail(pos, &flist);
}
} }
}
/* window check */ /* window check */
tt = d->targets;
te = tt + d->ntargets;
for (; tt < te && (t = *tt); tt++) {
if (t->nout == t->maxout if (t->nout == t->maxout
&& t->maxout < t->nframes && t->maxout < t->nframes
&& (jiffies - t->lastwadj)/HZ > 10) { && (jiffies - t->lastwadj)/HZ > 10) {
...@@ -626,7 +627,7 @@ rexmit_timer(ulong vp) ...@@ -626,7 +627,7 @@ rexmit_timer(ulong vp)
* Hang all frames on first hash bucket for downdev * Hang all frames on first hash bucket for downdev
* to clean up. * to clean up.
*/ */
list_splice(&flist, &f->t->factive[0]); list_splice(&flist, &d->factive[0]);
aoedev_downdev(d); aoedev_downdev(d);
break; break;
} }
...@@ -1162,15 +1163,7 @@ aoecmd_ata_rsp(struct sk_buff *skb) ...@@ -1162,15 +1163,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
spin_lock_irqsave(&d->lock, flags); spin_lock_irqsave(&d->lock, flags);
n = be32_to_cpu(get_unaligned(&h->tag)); n = be32_to_cpu(get_unaligned(&h->tag));
t = gettgt(d, h->src); f = getframe(d, n);
if (t == NULL) {
printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n",
d->aoemajor, d->aoeminor, h->src);
spin_unlock_irqrestore(&d->lock, flags);
aoedev_put(d);
return skb;
}
f = getframe(t, n);
if (f == NULL) { if (f == NULL) {
calc_rttavg(d, -tsince(n)); calc_rttavg(d, -tsince(n));
spin_unlock_irqrestore(&d->lock, flags); spin_unlock_irqrestore(&d->lock, flags);
...@@ -1185,6 +1178,7 @@ aoecmd_ata_rsp(struct sk_buff *skb) ...@@ -1185,6 +1178,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
aoechr_error(ebuf); aoechr_error(ebuf);
return skb; return skb;
} }
t = f->t;
calc_rttavg(d, tsince(f->tag)); calc_rttavg(d, tsince(f->tag));
t->nout--; t->nout--;
aoecmd_work(d); aoecmd_work(d);
...@@ -1253,7 +1247,6 @@ static struct aoetgt * ...@@ -1253,7 +1247,6 @@ static struct aoetgt *
addtgt(struct aoedev *d, char *addr, ulong nframes) addtgt(struct aoedev *d, char *addr, ulong nframes)
{ {
struct aoetgt *t, **tt, **te; struct aoetgt *t, **tt, **te;
int i;
tt = d->targets; tt = d->targets;
te = tt + NTARGETS; te = tt + NTARGETS;
...@@ -1278,8 +1271,6 @@ addtgt(struct aoedev *d, char *addr, ulong nframes) ...@@ -1278,8 +1271,6 @@ addtgt(struct aoedev *d, char *addr, ulong nframes)
t->ifp = t->ifs; t->ifp = t->ifs;
t->maxout = t->nframes; t->maxout = t->nframes;
INIT_LIST_HEAD(&t->ffree); INIT_LIST_HEAD(&t->ffree);
for (i = 0; i < NFACTIVE; ++i)
INIT_LIST_HEAD(&t->factive[i]);
return *tt = t; return *tt = t;
} }
......
...@@ -103,22 +103,23 @@ aoedev_downdev(struct aoedev *d) ...@@ -103,22 +103,23 @@ aoedev_downdev(struct aoedev *d)
d->flags &= ~DEVFL_UP; d->flags &= ~DEVFL_UP;
/* clean out active buffers on all targets */ /* clean out active buffers */
for (i = 0; i < NFACTIVE; i++) {
head = &d->factive[i];
list_for_each_safe(pos, nx, head) {
f = list_entry(pos, struct frame, head);
list_del(pos);
if (f->buf) {
f->buf->nframesout--;
aoe_failbuf(d, f->buf);
}
aoe_freetframe(f);
}
}
/* reset window dressings */
tt = d->targets; tt = d->targets;
te = tt + NTARGETS; te = tt + NTARGETS;
for (; tt < te && (t = *tt); tt++) { for (; tt < te && (t = *tt); tt++) {
for (i = 0; i < NFACTIVE; i++) {
head = &t->factive[i];
list_for_each_safe(pos, nx, head) {
list_del(pos);
f = list_entry(pos, struct frame, head);
if (f->buf) {
f->buf->nframesout--;
aoe_failbuf(d, f->buf);
}
aoe_freetframe(f);
}
}
t->maxout = t->nframes; t->maxout = t->nframes;
t->nout = 0; t->nout = 0;
} }
...@@ -250,6 +251,7 @@ struct aoedev * ...@@ -250,6 +251,7 @@ struct aoedev *
aoedev_by_sysminor_m(ulong sysminor) aoedev_by_sysminor_m(ulong sysminor)
{ {
struct aoedev *d; struct aoedev *d;
int i;
ulong flags; ulong flags;
spin_lock_irqsave(&devlist_lock, flags); spin_lock_irqsave(&devlist_lock, flags);
...@@ -275,6 +277,8 @@ aoedev_by_sysminor_m(ulong sysminor) ...@@ -275,6 +277,8 @@ aoedev_by_sysminor_m(ulong sysminor)
d->bufpool = NULL; /* defer to aoeblk_gdalloc */ d->bufpool = NULL; /* defer to aoeblk_gdalloc */
d->tgt = d->targets; d->tgt = d->targets;
d->ref = 1; d->ref = 1;
for (i = 0; i < NFACTIVE; i++)
INIT_LIST_HEAD(&d->factive[i]);
d->sysminor = sysminor; d->sysminor = sysminor;
d->aoemajor = AOEMAJOR(sysminor); d->aoemajor = AOEMAJOR(sysminor);
d->aoeminor = AOEMINOR(sysminor); d->aoeminor = AOEMINOR(sysminor);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment