diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 125 |
1 files changed, 8 insertions, 117 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ab935778ce81..7016e0c36b3d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -115,18 +115,6 @@ | |||
115 | #endif /* CONFIG_NET_RADIO */ | 115 | #endif /* CONFIG_NET_RADIO */ |
116 | #include <asm/current.h> | 116 | #include <asm/current.h> |
117 | 117 | ||
118 | /* This define, if set, will randomly drop a packet when congestion | ||
119 | * is more than moderate. It helps fairness in the multi-interface | ||
120 | * case when one of them is a hog, but it kills performance for the | ||
121 | * single interface case so it is off now by default. | ||
122 | */ | ||
123 | #undef RAND_LIE | ||
124 | |||
125 | /* Setting this will sample the queue lengths and thus congestion | ||
126 | * via a timer instead of as each packet is received. | ||
127 | */ | ||
128 | #undef OFFLINE_SAMPLE | ||
129 | |||
130 | /* | 118 | /* |
131 | * The list of packet types we will receive (as opposed to discard) | 119 | * The list of packet types we will receive (as opposed to discard) |
132 | * and the routines to invoke. | 120 | * and the routines to invoke. |
@@ -159,11 +147,6 @@ static DEFINE_SPINLOCK(ptype_lock); | |||
159 | static struct list_head ptype_base[16]; /* 16 way hashed list */ | 147 | static struct list_head ptype_base[16]; /* 16 way hashed list */ |
160 | static struct list_head ptype_all; /* Taps */ | 148 | static struct list_head ptype_all; /* Taps */ |
161 | 149 | ||
162 | #ifdef OFFLINE_SAMPLE | ||
163 | static void sample_queue(unsigned long dummy); | ||
164 | static struct timer_list samp_timer = TIMER_INITIALIZER(sample_queue, 0, 0); | ||
165 | #endif | ||
166 | |||
167 | /* | 150 | /* |
168 | * The @dev_base list is protected by @dev_base_lock and the rtln | 151 | * The @dev_base list is protected by @dev_base_lock and the rtln |
169 | * semaphore. | 152 | * semaphore. |
@@ -215,7 +198,7 @@ static struct notifier_block *netdev_chain; | |||
215 | * Device drivers call our routines to queue packets here. We empty the | 198 | * Device drivers call our routines to queue packets here. We empty the |
216 | * queue in the local softnet handler. | 199 | * queue in the local softnet handler. |
217 | */ | 200 | */ |
218 | DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, }; | 201 | DEFINE_PER_CPU(struct softnet_data, softnet_data) = { NULL }; |
219 | 202 | ||
220 | #ifdef CONFIG_SYSFS | 203 | #ifdef CONFIG_SYSFS |
221 | extern int netdev_sysfs_init(void); | 204 | extern int netdev_sysfs_init(void); |
@@ -1363,71 +1346,13 @@ out: | |||
1363 | Receiver routines | 1346 | Receiver routines |
1364 | =======================================================================*/ | 1347 | =======================================================================*/ |
1365 | 1348 | ||
1366 | int netdev_max_backlog = 300; | 1349 | int netdev_max_backlog = 1000; |
1350 | int netdev_budget = 300; | ||
1367 | int weight_p = 64; /* old backlog weight */ | 1351 | int weight_p = 64; /* old backlog weight */ |
1368 | /* These numbers are selected based on intuition and some | ||
1369 | * experimentatiom, if you have more scientific way of doing this | ||
1370 | * please go ahead and fix things. | ||
1371 | */ | ||
1372 | int no_cong_thresh = 10; | ||
1373 | int no_cong = 20; | ||
1374 | int lo_cong = 100; | ||
1375 | int mod_cong = 290; | ||
1376 | 1352 | ||
1377 | DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; | 1353 | DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; |
1378 | 1354 | ||
1379 | 1355 | ||
1380 | static void get_sample_stats(int cpu) | ||
1381 | { | ||
1382 | #ifdef RAND_LIE | ||
1383 | unsigned long rd; | ||
1384 | int rq; | ||
1385 | #endif | ||
1386 | struct softnet_data *sd = &per_cpu(softnet_data, cpu); | ||
1387 | int blog = sd->input_pkt_queue.qlen; | ||
1388 | int avg_blog = sd->avg_blog; | ||
1389 | |||
1390 | avg_blog = (avg_blog >> 1) + (blog >> 1); | ||
1391 | |||
1392 | if (avg_blog > mod_cong) { | ||
1393 | /* Above moderate congestion levels. */ | ||
1394 | sd->cng_level = NET_RX_CN_HIGH; | ||
1395 | #ifdef RAND_LIE | ||
1396 | rd = net_random(); | ||
1397 | rq = rd % netdev_max_backlog; | ||
1398 | if (rq < avg_blog) /* unlucky bastard */ | ||
1399 | sd->cng_level = NET_RX_DROP; | ||
1400 | #endif | ||
1401 | } else if (avg_blog > lo_cong) { | ||
1402 | sd->cng_level = NET_RX_CN_MOD; | ||
1403 | #ifdef RAND_LIE | ||
1404 | rd = net_random(); | ||
1405 | rq = rd % netdev_max_backlog; | ||
1406 | if (rq < avg_blog) /* unlucky bastard */ | ||
1407 | sd->cng_level = NET_RX_CN_HIGH; | ||
1408 | #endif | ||
1409 | } else if (avg_blog > no_cong) | ||
1410 | sd->cng_level = NET_RX_CN_LOW; | ||
1411 | else /* no congestion */ | ||
1412 | sd->cng_level = NET_RX_SUCCESS; | ||
1413 | |||
1414 | sd->avg_blog = avg_blog; | ||
1415 | } | ||
1416 | |||
1417 | #ifdef OFFLINE_SAMPLE | ||
1418 | static void sample_queue(unsigned long dummy) | ||
1419 | { | ||
1420 | /* 10 ms 0r 1ms -- i don't care -- JHS */ | ||
1421 | int next_tick = 1; | ||
1422 | int cpu = smp_processor_id(); | ||
1423 | |||
1424 | get_sample_stats(cpu); | ||
1425 | next_tick += jiffies; | ||
1426 | mod_timer(&samp_timer, next_tick); | ||
1427 | } | ||
1428 | #endif | ||
1429 | |||
1430 | |||
1431 | /** | 1356 | /** |
1432 | * netif_rx - post buffer to the network code | 1357 | * netif_rx - post buffer to the network code |
1433 | * @skb: buffer to post | 1358 | * @skb: buffer to post |
@@ -1448,7 +1373,6 @@ static void sample_queue(unsigned long dummy) | |||
1448 | 1373 | ||
1449 | int netif_rx(struct sk_buff *skb) | 1374 | int netif_rx(struct sk_buff *skb) |
1450 | { | 1375 | { |
1451 | int this_cpu; | ||
1452 | struct softnet_data *queue; | 1376 | struct softnet_data *queue; |
1453 | unsigned long flags; | 1377 | unsigned long flags; |
1454 | 1378 | ||
@@ -1464,38 +1388,22 @@ int netif_rx(struct sk_buff *skb) | |||
1464 | * short when CPU is congested, but is still operating. | 1388 | * short when CPU is congested, but is still operating. |
1465 | */ | 1389 | */ |
1466 | local_irq_save(flags); | 1390 | local_irq_save(flags); |
1467 | this_cpu = smp_processor_id(); | ||
1468 | queue = &__get_cpu_var(softnet_data); | 1391 | queue = &__get_cpu_var(softnet_data); |
1469 | 1392 | ||
1470 | __get_cpu_var(netdev_rx_stat).total++; | 1393 | __get_cpu_var(netdev_rx_stat).total++; |
1471 | if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { | 1394 | if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { |
1472 | if (queue->input_pkt_queue.qlen) { | 1395 | if (queue->input_pkt_queue.qlen) { |
1473 | if (queue->throttle) | ||
1474 | goto drop; | ||
1475 | |||
1476 | enqueue: | 1396 | enqueue: |
1477 | dev_hold(skb->dev); | 1397 | dev_hold(skb->dev); |
1478 | __skb_queue_tail(&queue->input_pkt_queue, skb); | 1398 | __skb_queue_tail(&queue->input_pkt_queue, skb); |
1479 | #ifndef OFFLINE_SAMPLE | ||
1480 | get_sample_stats(this_cpu); | ||
1481 | #endif | ||
1482 | local_irq_restore(flags); | 1399 | local_irq_restore(flags); |
1483 | return queue->cng_level; | 1400 | return NET_RX_SUCCESS; |
1484 | } | 1401 | } |
1485 | 1402 | ||
1486 | if (queue->throttle) | ||
1487 | queue->throttle = 0; | ||
1488 | |||
1489 | netif_rx_schedule(&queue->backlog_dev); | 1403 | netif_rx_schedule(&queue->backlog_dev); |
1490 | goto enqueue; | 1404 | goto enqueue; |
1491 | } | 1405 | } |
1492 | 1406 | ||
1493 | if (!queue->throttle) { | ||
1494 | queue->throttle = 1; | ||
1495 | __get_cpu_var(netdev_rx_stat).throttled++; | ||
1496 | } | ||
1497 | |||
1498 | drop: | ||
1499 | __get_cpu_var(netdev_rx_stat).dropped++; | 1407 | __get_cpu_var(netdev_rx_stat).dropped++; |
1500 | local_irq_restore(flags); | 1408 | local_irq_restore(flags); |
1501 | 1409 | ||
@@ -1780,8 +1688,6 @@ job_done: | |||
1780 | smp_mb__before_clear_bit(); | 1688 | smp_mb__before_clear_bit(); |
1781 | netif_poll_enable(backlog_dev); | 1689 | netif_poll_enable(backlog_dev); |
1782 | 1690 | ||
1783 | if (queue->throttle) | ||
1784 | queue->throttle = 0; | ||
1785 | local_irq_enable(); | 1691 | local_irq_enable(); |
1786 | return 0; | 1692 | return 0; |
1787 | } | 1693 | } |
@@ -1790,8 +1696,7 @@ static void net_rx_action(struct softirq_action *h) | |||
1790 | { | 1696 | { |
1791 | struct softnet_data *queue = &__get_cpu_var(softnet_data); | 1697 | struct softnet_data *queue = &__get_cpu_var(softnet_data); |
1792 | unsigned long start_time = jiffies; | 1698 | unsigned long start_time = jiffies; |
1793 | int budget = netdev_max_backlog; | 1699 | int budget = netdev_budget; |
1794 | |||
1795 | 1700 | ||
1796 | local_irq_disable(); | 1701 | local_irq_disable(); |
1797 | 1702 | ||
@@ -2055,15 +1960,9 @@ static int softnet_seq_show(struct seq_file *seq, void *v) | |||
2055 | struct netif_rx_stats *s = v; | 1960 | struct netif_rx_stats *s = v; |
2056 | 1961 | ||
2057 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", | 1962 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", |
2058 | s->total, s->dropped, s->time_squeeze, s->throttled, | 1963 | s->total, s->dropped, s->time_squeeze, 0, |
2059 | s->fastroute_hit, s->fastroute_success, s->fastroute_defer, | 1964 | 0, 0, 0, 0, /* was fastroute */ |
2060 | s->fastroute_deferred_out, | 1965 | s->cpu_collision ); |
2061 | #if 0 | ||
2062 | s->fastroute_latency_reduction | ||
2063 | #else | ||
2064 | s->cpu_collision | ||
2065 | #endif | ||
2066 | ); | ||
2067 | return 0; | 1966 | return 0; |
2068 | } | 1967 | } |
2069 | 1968 | ||
@@ -3305,9 +3204,6 @@ static int __init net_dev_init(void) | |||
3305 | 3204 | ||
3306 | queue = &per_cpu(softnet_data, i); | 3205 | queue = &per_cpu(softnet_data, i); |
3307 | skb_queue_head_init(&queue->input_pkt_queue); | 3206 | skb_queue_head_init(&queue->input_pkt_queue); |
3308 | queue->throttle = 0; | ||
3309 | queue->cng_level = 0; | ||
3310 | queue->avg_blog = 10; /* arbitrary non-zero */ | ||
3311 | queue->completion_queue = NULL; | 3207 | queue->completion_queue = NULL; |
3312 | INIT_LIST_HEAD(&queue->poll_list); | 3208 | INIT_LIST_HEAD(&queue->poll_list); |
3313 | set_bit(__LINK_STATE_START, &queue->backlog_dev.state); | 3209 | set_bit(__LINK_STATE_START, &queue->backlog_dev.state); |
@@ -3316,11 +3212,6 @@ static int __init net_dev_init(void) | |||
3316 | atomic_set(&queue->backlog_dev.refcnt, 1); | 3212 | atomic_set(&queue->backlog_dev.refcnt, 1); |
3317 | } | 3213 | } |
3318 | 3214 | ||
3319 | #ifdef OFFLINE_SAMPLE | ||
3320 | samp_timer.expires = jiffies + (10 * HZ); | ||
3321 | add_timer(&samp_timer); | ||
3322 | #endif | ||
3323 | |||
3324 | dev_boot_phase = 0; | 3215 | dev_boot_phase = 0; |
3325 | 3216 | ||
3326 | open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); | 3217 | open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); |