The patch titled Subject: aoe: use a kernel thread for transmissions has been added to the -mm tree. Its filename is aoe-use-a-kernel-thread-for-transmissions.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Ed Cashin <ecashin@xxxxxxxxxx> Subject: aoe: use a kernel thread for transmissions The dev_queue_xmit function needs to have interrupts enabled, so the most simple way to get the locking right but still fulfill that requirement is to use a process that can call dev_queue_xmit serially over queued transmissions. Signed-off-by: Ed Cashin <ecashin@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- drivers/block/aoe/aoe.h | 2 + drivers/block/aoe/aoecmd.c | 4 +-- drivers/block/aoe/aoenet.c | 37 ++++++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff -puN drivers/block/aoe/aoe.h~aoe-use-a-kernel-thread-for-transmissions drivers/block/aoe/aoe.h --- a/drivers/block/aoe/aoe.h~aoe-use-a-kernel-thread-for-transmissions +++ a/drivers/block/aoe/aoe.h @@ -210,6 +210,8 @@ struct sk_buff *aoecmd_ata_id(struct aoe void aoe_freetframe(struct frame *); void aoe_flush_iocq(void); void aoe_end_request(struct aoedev *, struct request *, int); +int aoe_ktstart(struct ktstate *k); +void aoe_ktstop(struct ktstate *k); int aoedev_init(void); void aoedev_exit(void); diff -puN drivers/block/aoe/aoecmd.c~aoe-use-a-kernel-thread-for-transmissions drivers/block/aoe/aoecmd.c --- a/drivers/block/aoe/aoecmd.c~aoe-use-a-kernel-thread-for-transmissions +++ a/drivers/block/aoe/aoecmd.c @@ -1109,14 +1109,14 @@ kthread(void *vp) return 0; } -static void +void aoe_ktstop(struct ktstate *k) { kthread_stop(k->task); wait_for_completion(&k->rendez); } -static int +int aoe_ktstart(struct ktstate *k) { struct task_struct *task; diff -puN drivers/block/aoe/aoenet.c~aoe-use-a-kernel-thread-for-transmissions drivers/block/aoe/aoenet.c --- a/drivers/block/aoe/aoenet.c~aoe-use-a-kernel-thread-for-transmissions +++ a/drivers/block/aoe/aoenet.c @@ -33,6 +33,9 @@ static char aoe_iflist[IFLISTSZ]; module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600); MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\""); +static wait_queue_head_t txwq; +static struct ktstate kts; + #ifndef MODULE static int __init aoe_iflist_setup(char *str) { @@ -44,6 +47,23 @@ static int __init aoe_iflist_setup(char __setup("aoe_iflist=", aoe_iflist_setup); #endif +static spinlock_t txlock; +static struct sk_buff_head skbtxq; + +/* enters with txlock held */ +static int +tx(void) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(&skbtxq))) { + spin_unlock_irq(&txlock); + dev_queue_xmit(skb); + spin_lock_irq(&txlock); + } + return 0; +} + int is_aoe_netif(struct net_device *ifp) { @@ -88,10 +108,14 @@ void aoenet_xmit(struct sk_buff_head *queue) { struct sk_buff *skb, *tmp; + ulong flags; skb_queue_walk_safe(queue, skb, tmp) { __skb_unlink(skb, queue); - dev_queue_xmit(skb); + spin_lock_irqsave(&txlock, flags); + skb_queue_tail(&skbtxq, skb); + spin_unlock_irqrestore(&txlock, flags); + wake_up(&txwq); } } @@ -169,6 +193,15 @@ static struct packet_type aoe_pt __read_ int __init aoenet_init(void) { + skb_queue_head_init(&skbtxq); + init_waitqueue_head(&txwq); + spin_lock_init(&txlock); + kts.lock = &txlock; + kts.fn = tx; + kts.waitq = &txwq; + kts.name = "aoe_tx"; + if (aoe_ktstart(&kts)) + return -EAGAIN; dev_add_pack(&aoe_pt); return 0; } @@ -176,6 +209,8 @@ aoenet_init(void) void aoenet_exit(void) { + aoe_ktstop(&kts); + skb_queue_purge(&skbtxq); dev_remove_pack(&aoe_pt); } _ Patches currently in -mm which might be from ecashin@xxxxxxxxxx are aoe-for-performance-support-larger-packet-payloads.patch aoe-kernel-thread-handles-i-o-completions-for-simple-locking.patch aoe-become-i-o-request-queue-handler-for-increased-user-control.patch aoe-use-a-kernel-thread-for-transmissions.patch aoe-use-packets-that-work-with-the-smallest-mtu-local-interface.patch aoe-failover-remote-interface-based-on-aoe_deadsecs-parameter.patch aoe-do-revalidation-steps-in-order.patch aoe-disallow-unsupported-aoe-minor-addresses.patch aoe-associate-frames-with-the-aoe-storage-target.patch aoe-increase-net_device-reference-count-while-using-it.patch aoe-remove-unused-code-and-add-cosmetic-improvements.patch aoe-update-internal-version-number-to-49.patch aoe-update-copyright-year-in-touched-files.patch aoe-update-documentation-with-new-url-and-vm-settings-reference.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html