On Thu, 2012-03-01 at 08:57 -0500, Neil Horman wrote:
> There is potentially lots of contention for the rx_list_lock.  On a cpu that 
> is
> receiving lots of fcoe traffic, the softirq context has to add and release the
> lock for every frame it receives, as does the receiving per-cpu thread.  We 
> can
> reduce this contention somewhat by altering the per-cpu threads loop such that
> when traffic is detected on the fcoe_rx_list, we splice it to a temporary 
> list.
> In this way, we can process multiple skbs while only having to acquire and
> release the fcoe_rx_list lock once.
> 
> Signed-off-by: Neil Horman <nhor...@tuxdriver.com>
> CC: Robert Love <robert.w.l...@intel.com>
> CC: Vasu Dev <vasu....@linux.intel.com>
> CC: "James E.J. Bottomley" <jbottom...@parallels.com>
> 
> ---
> Change notes:
> v2)
> As per Vasu's note, remove the get_more_skbs label as its unused
> ---
>  drivers/scsi/fcoe/fcoe.c |   23 +++++++++++++++--------
>  1 files changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
> index dc5597b..cd40b66 100644
> --- a/drivers/scsi/fcoe/fcoe.c
> +++ b/drivers/scsi/fcoe/fcoe.c
> @@ -1463,7 +1463,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct 
> net_device *netdev,
>        * in softirq context.
>        */
>       __skb_queue_tail(&fps->fcoe_rx_list, skb);
> -     if (fps->fcoe_rx_list.qlen == 1)
> +     if (fps->thread->state == TASK_INTERRUPTIBLE)
>               wake_up_process(fps->thread);
>       spin_unlock(&fps->fcoe_rx_list.lock);
>  
> @@ -1782,23 +1782,30 @@ static int fcoe_percpu_receive_thread(void *arg)
>  {
>       struct fcoe_percpu_s *p = arg;
>       struct sk_buff *skb;
> +     struct sk_buff_head tmp;
> +
> +     skb_queue_head_init(&tmp);
>  
>       set_user_nice(current, -20);
>  
>       while (!kthread_should_stop()) {
>  
>               spin_lock_bh(&p->fcoe_rx_list.lock);
> -             while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
> +             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)) {
>                       set_current_state(TASK_INTERRUPTIBLE);
>                       spin_unlock_bh(&p->fcoe_rx_list.lock);
>                       schedule();
>                       set_current_state(TASK_RUNNING);
> -                     if (kthread_should_stop())
> -                             return 0;
> -                     spin_lock_bh(&p->fcoe_rx_list.lock);
> -             }
> -             spin_unlock_bh(&p->fcoe_rx_list.lock);
> -             fcoe_recv_frame(skb);
> +             } else
> +                     spin_unlock_bh(&p->fcoe_rx_list.lock);
>       }
>       return 0;
>  }

Acked-by: Vasu Dev <vasu....@intel.com>


_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to