diff options
author | Neil Horman <nhorman@tuxdriver.com> | 2012-07-06 21:40:05 +0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 11:58:55 +0400 |
commit | 95fdd5e980e6eea4579c15043f7a9be6ad63012c (patch) | |
tree | e74fcd944435fe471d15e78e901dee32e1b46a98 /drivers/scsi/fcoe/fcoe.c | |
parent | 902a45af5c9fad283a530c3bc71225fa6a8e616a (diff) | |
download | linux-95fdd5e980e6eea4579c15043f7a9be6ad63012c.tar.xz |
[SCSI] fcoe: Cleanup locking on fcoe_percpu_receive_thread
Noticed that we can shuffle the code around in fcoe_percpu_receive_thread a bit
and avoid taking the fcoe_rx_list lock twice per iteration. This should improve
throughput somewhat. With this change we take the lock, and check for new
frames in a single critical section. Only if the list is empty do we drop the
lock and re-acquire it after being signaled to wake up.
Change Notes:
v2) did some further cleanup on the patch by replacing the 2nd call of
spin_lock/splice_init with a goto to the top of the outer loop. This allows me
to change the inner while loop to an if conditional and remove the sencond check
of kthread_should_stop. Based on suggestion from Vasu Dev.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 2b065d26a5ae..078d262ac7cc 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1851,23 +1851,25 @@ static int fcoe_percpu_receive_thread(void *arg) set_user_nice(current, -20); +retry: while (!kthread_should_stop()) { spin_lock_bh(&p->fcoe_rx_list.lock); skb_queue_splice_init(&p->fcoe_rx_list, &tmp); - spin_unlock_bh(&p->fcoe_rx_list.lock); - - while ((skb = __skb_dequeue(&tmp)) != NULL) - fcoe_recv_frame(skb); - spin_lock_bh(&p->fcoe_rx_list.lock); - if (!skb_queue_len(&p->fcoe_rx_list)) { + if (!skb_queue_len(&tmp)) { set_current_state(TASK_INTERRUPTIBLE); spin_unlock_bh(&p->fcoe_rx_list.lock); schedule(); set_current_state(TASK_RUNNING); - } else - spin_unlock_bh(&p->fcoe_rx_list.lock); + goto retry; + } + + spin_unlock_bh(&p->fcoe_rx_list.lock); + + while ((skb = __skb_dequeue(&tmp)) != NULL) + fcoe_recv_frame(skb); + } return 0; } |