[SCSI] fcoe: Cleanup locking on fcoe_percpu_receive_thread
authorNeil Horman <nhorman@tuxdriver.com>
Fri, 6 Jul 2012 17:40:05 +0000 (10:40 -0700)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 20 Jul 2012 07:58:55 +0000 (08:58 +0100)
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>
drivers/scsi/fcoe/fcoe.c

index 2b065d26a5ae215c82d640eecf90ce57b9731e8a..078d262ac7ccf568a8840ec894ddd42136e9a46b 100644 (file)
@@ -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;
 }