summaryrefslogtreecommitdiff
path: root/drivers/block/aoe/aoenet.c
diff options
context:
space:
mode:
authorEd Cashin <ecashin@coraid.com>2012-10-05 00:16:21 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-05 18:05:24 (GMT)
commit896831f5909e2733c13c9cb13a1a215f10c3eaa8 (patch)
tree9541075df9b3703b7ea8853de619fa98c4be1456 /drivers/block/aoe/aoenet.c
parent3d5b06051cd5fa82c9a4285f7ce8650a0f0845ff (diff)
downloadlinux-896831f5909e2733c13c9cb13a1a215f10c3eaa8.tar.xz
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/aoe/aoenet.c')
-rw-r--r--drivers/block/aoe/aoenet.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 0787807..000eff2 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,
switch (h->cmd) {
case AOECMD_ATA:
- aoecmd_ata_rsp(skb);
+ /* ata_rsp may keep skb for later processing or give it back */
+ skb = aoecmd_ata_rsp(skb);
break;
case AOECMD_CFG:
aoecmd_cfg_rsp(skb);
@@ -152,6 +153,9 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
break; /* don't complain about vendor commands */
printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
}
+
+ if (!skb)
+ return 0;
exit:
dev_kfree_skb(skb);
return 0;