Skip to content

Commit 6e583ce

Browse files
Stephen Hemmingerdavem330
authored andcommitted
net: eliminate refcounting in backlog queue
Avoid the overhead of atomic increment/decrement on each received packet. This helps performance of non-NAPI devices (like loopback). Use cleanup function to walk queue on each cpu and clean out any left over packets. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 283d07a commit 6e583ce

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

net/core/dev.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,6 @@ int netif_rx(struct sk_buff *skb)
19091909
if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
19101910
if (queue->input_pkt_queue.qlen) {
19111911
enqueue:
1912-
dev_hold(skb->dev);
19131912
__skb_queue_tail(&queue->input_pkt_queue, skb);
19141913
local_irq_restore(flags);
19151914
return NET_RX_SUCCESS;
@@ -2270,6 +2269,20 @@ int netif_receive_skb(struct sk_buff *skb)
22702269
return ret;
22712270
}
22722271

2272+
/* Network device is going away, flush any packets still pending */
2273+
static void flush_backlog(void *arg)
2274+
{
2275+
struct net_device *dev = arg;
2276+
struct softnet_data *queue = &__get_cpu_var(softnet_data);
2277+
struct sk_buff *skb, *tmp;
2278+
2279+
skb_queue_walk_safe(&queue->input_pkt_queue, skb, tmp)
2280+
if (skb->dev == dev) {
2281+
__skb_unlink(skb, &queue->input_pkt_queue);
2282+
kfree_skb(skb);
2283+
}
2284+
}
2285+
22732286
static int process_backlog(struct napi_struct *napi, int quota)
22742287
{
22752288
int work = 0;
@@ -2279,7 +2292,6 @@ static int process_backlog(struct napi_struct *napi, int quota)
22792292
napi->weight = weight_p;
22802293
do {
22812294
struct sk_buff *skb;
2282-
struct net_device *dev;
22832295

22842296
local_irq_disable();
22852297
skb = __skb_dequeue(&queue->input_pkt_queue);
@@ -2288,14 +2300,9 @@ static int process_backlog(struct napi_struct *napi, int quota)
22882300
local_irq_enable();
22892301
break;
22902302
}
2291-
22922303
local_irq_enable();
22932304

2294-
dev = skb->dev;
2295-
22962305
netif_receive_skb(skb);
2297-
2298-
dev_put(dev);
22992306
} while (++work < quota && jiffies == start_time);
23002307

23012308
return work;
@@ -4169,6 +4176,8 @@ void netdev_run_todo(void)
41694176

41704177
dev->reg_state = NETREG_UNREGISTERED;
41714178

4179+
on_each_cpu(flush_backlog, dev, 1);
4180+
41724181
netdev_wait_allrefs(dev);
41734182

41744183
/* paranoia */

0 commit comments

Comments
 (0)