Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

aoe: use dynamic number of remote ports for AoE storage target

Many AoE targets have four or fewer network ports, but some existing
storage devices have many, and the AoE protocol sets no limit.

This patch allows the use of more than eight remote MAC addresses per AoE
target, while reducing the amount of memory used by the aoe driver in
cases where there are many AoE targets with fewer than eight MAC addresses
each.

Signed-off-by: Ed Cashin <ecashin@coraid.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ed Cashin and committed by
Linus Torvalds
71114ec4 e52a2932

+49 -21
+3 -3
drivers/block/aoe/aoe.h
··· 84 84 enum { 85 85 DEFAULTBCNT = 2 * 512, /* 2 sectors */ 86 86 MIN_BUFS = 16, 87 - NTARGETS = 8, 87 + NTARGETS = 4, 88 88 NAOEIFS = 8, 89 89 NSKBPOOLMAX = 256, 90 90 NFACTIVE = 61, ··· 185 185 ulong maxbcnt; 186 186 struct list_head factive[NFACTIVE]; /* hash of active frames */ 187 187 struct list_head rexmitq; /* deferred retransmissions */ 188 - struct aoetgt *targets[NTARGETS]; 188 + struct aoetgt **targets; 189 + ulong ntargets; /* number of allocated aoetgt pointers */ 189 190 struct aoetgt **tgt; /* target in use when working */ 190 - ulong ntargets; 191 191 ulong kicked; 192 192 char ident[512]; 193 193 };
+1 -1
drivers/block/aoe/aoeblk.c
··· 67 67 nd = nds; 68 68 ne = nd + ARRAY_SIZE(nds); 69 69 t = d->targets; 70 - te = t + NTARGETS; 70 + te = t + d->ntargets; 71 71 for (; t < te && *t; t++) { 72 72 ifp = (*t)->ifs; 73 73 e = ifp + NAOEIFS;
+35 -15
drivers/block/aoe/aoecmd.c
··· 242 242 int use_tainted; 243 243 int has_untainted; 244 244 245 - if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */ 245 + if (!d->targets || !d->targets[0]) { 246 246 printk(KERN_ERR "aoe: NULL TARGETS!\n"); 247 247 return NULL; 248 248 } 249 249 tt = d->tgt; /* last used target */ 250 250 for (use_tainted = 0, has_untainted = 0;;) { 251 251 tt++; 252 - if (tt >= &d->targets[NTARGETS] || !*tt) 252 + if (tt >= &d->targets[d->ntargets] || !*tt) 253 253 tt = d->targets; 254 254 t = *tt; 255 255 if (!t->taint) { ··· 1104 1104 struct aoetgt **t, **e; 1105 1105 1106 1106 t = d->targets; 1107 - e = t + NTARGETS; 1107 + e = t + d->ntargets; 1108 1108 for (; t < e && *t; t++) 1109 1109 if (memcmp((*t)->addr, addr, sizeof((*t)->addr)) == 0) 1110 1110 return *t; ··· 1479 1479 return skb; 1480 1480 } 1481 1481 1482 + static struct aoetgt ** 1483 + grow_targets(struct aoedev *d) 1484 + { 1485 + ulong oldn, newn; 1486 + struct aoetgt **tt; 1487 + 1488 + oldn = d->ntargets; 1489 + newn = oldn * 2; 1490 + tt = kcalloc(newn, sizeof(*d->targets), GFP_ATOMIC); 1491 + if (!tt) 1492 + return NULL; 1493 + memmove(tt, d->targets, sizeof(*d->targets) * oldn); 1494 + d->tgt = tt + (d->tgt - d->targets); 1495 + kfree(d->targets); 1496 + d->targets = tt; 1497 + d->ntargets = newn; 1498 + 1499 + return &d->targets[oldn]; 1500 + } 1501 + 1482 1502 static struct aoetgt * 1483 1503 addtgt(struct aoedev *d, char *addr, ulong nframes) 1484 1504 { 1485 1505 struct aoetgt *t, **tt, **te; 1486 1506 1487 1507 tt = d->targets; 1488 - te = tt + NTARGETS; 1508 + te = tt + d->ntargets; 1489 1509 for (; tt < te && *tt; tt++) 1490 1510 ; 1491 1511 1492 1512 if (tt == te) { 1493 - printk(KERN_INFO 1494 - "aoe: device addtgt failure; too many targets\n"); 1495 - return NULL; 1513 + tt = grow_targets(d); 1514 + if (!tt) 1515 + goto nomem; 1496 1516 } 1497 1517 t = kzalloc(sizeof(*t), GFP_ATOMIC); 1498 - if (!t) { 1499 - printk(KERN_INFO "aoe: cannot allocate memory to add target\n"); 1500 - return NULL; 1501 - } 1502 - 1503 - d->ntargets++; 1518 + if (!t) 1519 + goto nomem; 1504 1520 t->nframes = nframes; 1505 1521 t->d = d; 1506 1522 memcpy(t->addr, addr, sizeof t->addr); ··· 1525 1509 t->maxout = t->nframes / 2; 1526 1510 INIT_LIST_HEAD(&t->ffree); 1527 1511 return *tt = t; 1512 + 1513 + nomem: 1514 + pr_info("aoe: cannot allocate memory to add target\n"); 1515 + return NULL; 1528 1516 } 1529 1517 1530 1518 static void ··· 1538 1518 int bcnt = 0; 1539 1519 1540 1520 t = d->targets; 1541 - e = t + NTARGETS; 1521 + e = t + d->ntargets; 1542 1522 for (; t < e && *t; t++) 1543 1523 if (bcnt == 0 || bcnt > (*t)->minbcnt) 1544 1524 bcnt = (*t)->minbcnt; ··· 1682 1662 d->maxbcnt = 0; 1683 1663 1684 1664 t = d->targets; 1685 - te = t + NTARGETS; 1665 + te = t + d->ntargets; 1686 1666 for (; t < te && *t; t++) 1687 1667 aoecmd_wreset(*t); 1688 1668 }
+10 -2
drivers/block/aoe/aoedev.c
··· 214 214 215 215 /* reset window dressings */ 216 216 tt = d->targets; 217 - te = tt + NTARGETS; 217 + te = tt + d->ntargets; 218 218 for (; tt < te && (t = *tt); tt++) { 219 219 aoecmd_wreset(t); 220 220 t->nout = 0; ··· 284 284 blk_cleanup_queue(d->blkq); 285 285 } 286 286 t = d->targets; 287 - e = t + NTARGETS; 287 + e = t + d->ntargets; 288 288 for (; t < e && *t; t++) 289 289 freetgt(d, *t); 290 290 if (d->bufpool) ··· 376 376 dd = &d->next; 377 377 } 378 378 spin_unlock(&d->lock); 379 + if (doomed) 380 + kfree(doomed->targets); 379 381 kfree(doomed); 380 382 } 381 383 spin_unlock_irqrestore(&devlist_lock, flags); ··· 458 456 d = kcalloc(1, sizeof *d, GFP_ATOMIC); 459 457 if (!d) 460 458 goto out; 459 + d->targets = kcalloc(NTARGETS, sizeof(*d->targets), GFP_ATOMIC); 460 + if (!d->targets) { 461 + kfree(d); 462 + goto out; 463 + } 464 + d->ntargets = NTARGETS; 461 465 INIT_WORK(&d->work, aoecmd_sleepwork); 462 466 spin_lock_init(&d->lock); 463 467 skb_queue_head_init(&d->skbpool);