Message ID | 1272018366.7895.7930.camel@edumazet-laptop |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Fri, 23 Apr 2010 12:26:06 +0200 > Le vendredi 23 avril 2010 à 16:12 +0800, Changli Gao a écrit : >> batch skb dequeueing from softnet input_pkt_queue. >> >> batch skb dequeueing from softnet input_pkt_queue to reduce potential lock >> contention when RPS is enabled. >> >> Note: in the worst case, the number of packets in a softnet_data may be double >> of netdev_max_backlog. >> >> Signed-off-by: Changli Gao <xiaosuo@gmail.com> >> ---- > > Oops, reading it again, I found process_backlog() was still taking the > lock twice, if only one packet is waiting in input_pkt_queue. > > Possible fix, on top of your patch : I've applied Changli's patch with this fixup added to it. If there are any follow-on changes necessary after further analysis, please send patches on top of this work. Thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/core/dev.c b/net/core/dev.c index 0eddd23..0569be7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3296,8 +3296,9 @@ static int process_backlog(struct napi_struct *napi, int quota) #endif napi->weight = weight_p; local_irq_disable(); - while (1) { + while (work < quota) { struct sk_buff *skb; + unsigned int qlen; while ((skb = __skb_dequeue(&sd->process_queue))) { local_irq_enable(); @@ -3308,13 +3309,15 @@ static int process_backlog(struct napi_struct *napi, int quota) } rps_lock(sd); - input_queue_head_add(sd, skb_queue_len(&sd->input_pkt_queue)); - skb_queue_splice_tail_init(&sd->input_pkt_queue, - &sd->process_queue); - if (skb_queue_empty(&sd->process_queue)) { + qlen = skb_queue_len(&sd->input_pkt_queue); + if (qlen) { + input_queue_head_add(sd, qlen); + skb_queue_splice_tail_init(&sd->input_pkt_queue, + &sd->process_queue); + } + if (qlen < quota - work) { __napi_complete(napi); - rps_unlock(sd); - break; + quota = work + qlen; } rps_unlock(sd); }