[NET]: Eliminate netif_rx massive packet drops.

Eliminate the throttling behaviour when the netif receive queue fills
because it behaves badly when using high speed networks under load.
The throttling cause multiple packet drops that cause TCP to go into
slow start mode. The same effective patch has been part of BIC TCP and
H-TCP as well as part of Web100.

The existing code drops 100's of packets when the queue fills;
this changes it to individual packet drop-tail.

Signed-off-by: Stephen Hemmminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Stephen Hemminger and committed by David S. Miller 31aa02c5 34008d8c

+3 -22
+1 -3
include/linux/netdevice.h
··· 164 164 unsigned total; 165 165 unsigned dropped; 166 166 unsigned time_squeeze; 167 - unsigned throttled; 168 167 unsigned cpu_collision; 169 168 }; 170 169 ··· 556 557 557 558 struct softnet_data 558 559 { 559 - int throttle; 560 + struct net_device *output_queue; 560 561 struct sk_buff_head input_pkt_queue; 561 562 struct list_head poll_list; 562 - struct net_device *output_queue; 563 563 struct sk_buff *completion_queue; 564 564 565 565 struct net_device backlog_dev; /* Sorry. 8) */
+2 -19
net/core/dev.c
··· 198 198 * Device drivers call our routines to queue packets here. We empty the 199 199 * queue in the local softnet handler. 200 200 */ 201 - DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, }; 201 + DEFINE_PER_CPU(struct softnet_data, softnet_data) = { NULL }; 202 202 203 203 #ifdef CONFIG_SYSFS 204 204 extern int netdev_sysfs_init(void); ··· 1372 1372 1373 1373 int netif_rx(struct sk_buff *skb) 1374 1374 { 1375 - int this_cpu; 1376 1375 struct softnet_data *queue; 1377 1376 unsigned long flags; 1378 1377 ··· 1387 1388 * short when CPU is congested, but is still operating. 1388 1389 */ 1389 1390 local_irq_save(flags); 1390 - this_cpu = smp_processor_id(); 1391 1391 queue = &__get_cpu_var(softnet_data); 1392 1392 1393 1393 __get_cpu_var(netdev_rx_stat).total++; 1394 1394 if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { 1395 1395 if (queue->input_pkt_queue.qlen) { 1396 - if (queue->throttle) 1397 - goto drop; 1398 - 1399 1396 enqueue: 1400 1397 dev_hold(skb->dev); 1401 1398 __skb_queue_tail(&queue->input_pkt_queue, skb); ··· 1399 1404 return NET_RX_SUCCESS; 1400 1405 } 1401 1406 1402 - if (queue->throttle) 1403 - queue->throttle = 0; 1404 - 1405 1407 netif_rx_schedule(&queue->backlog_dev); 1406 1408 goto enqueue; 1407 1409 } 1408 1410 1409 - if (!queue->throttle) { 1410 - queue->throttle = 1; 1411 - __get_cpu_var(netdev_rx_stat).throttled++; 1412 - } 1413 - 1414 - drop: 1415 1411 __get_cpu_var(netdev_rx_stat).dropped++; 1416 1412 local_irq_restore(flags); 1417 1413 ··· 1687 1701 smp_mb__before_clear_bit(); 1688 1702 netif_poll_enable(backlog_dev); 1689 1703 1690 - if (queue->throttle) 1691 - queue->throttle = 0; 1692 1704 local_irq_enable(); 1693 1705 return 0; 1694 1706 } ··· 1960 1976 struct netif_rx_stats *s = v; 1961 1977 1962 1978 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", 1963 - s->total, s->dropped, s->time_squeeze, s->throttled, 1979 + s->total, s->dropped, s->time_squeeze, 0, 1964 1980 0, 0, 0, 0, /* was fastroute */ 1965 1981 s->cpu_collision ); 1966 1982 return 0; ··· 3204 3220 3205 3221 queue = &per_cpu(softnet_data, i); 3206 3222 skb_queue_head_init(&queue->input_pkt_queue); 3207 - queue->throttle = 0; 3208 3223 queue->completion_queue = NULL; 3209 3224 INIT_LIST_HEAD(&queue->poll_list); 3210 3225 set_bit(__LINK_STATE_START, &queue->backlog_dev.state);