diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 600bb23c4c2e..e8eb2b478344 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -122,6 +122,7 @@ | |||
122 | #include <linux/if_arp.h> | 122 | #include <linux/if_arp.h> |
123 | #include <linux/if_vlan.h> | 123 | #include <linux/if_vlan.h> |
124 | #include <linux/ip.h> | 124 | #include <linux/ip.h> |
125 | #include <net/ip.h> | ||
125 | #include <linux/ipv6.h> | 126 | #include <linux/ipv6.h> |
126 | #include <linux/in.h> | 127 | #include <linux/in.h> |
127 | #include <linux/jhash.h> | 128 | #include <linux/jhash.h> |
@@ -1339,19 +1340,23 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1339 | } | 1340 | } |
1340 | 1341 | ||
1341 | 1342 | ||
1342 | void __netif_schedule(struct Qdisc *q) | 1343 | static inline void __netif_reschedule(struct Qdisc *q) |
1343 | { | 1344 | { |
1344 | if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) { | 1345 | struct softnet_data *sd; |
1345 | struct softnet_data *sd; | 1346 | unsigned long flags; |
1346 | unsigned long flags; | ||
1347 | 1347 | ||
1348 | local_irq_save(flags); | 1348 | local_irq_save(flags); |
1349 | sd = &__get_cpu_var(softnet_data); | 1349 | sd = &__get_cpu_var(softnet_data); |
1350 | q->next_sched = sd->output_queue; | 1350 | q->next_sched = sd->output_queue; |
1351 | sd->output_queue = q; | 1351 | sd->output_queue = q; |
1352 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 1352 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
1353 | local_irq_restore(flags); | 1353 | local_irq_restore(flags); |
1354 | } | 1354 | } |
1355 | |||
1356 | void __netif_schedule(struct Qdisc *q) | ||
1357 | { | ||
1358 | if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) | ||
1359 | __netif_reschedule(q); | ||
1355 | } | 1360 | } |
1356 | EXPORT_SYMBOL(__netif_schedule); | 1361 | EXPORT_SYMBOL(__netif_schedule); |
1357 | 1362 | ||
@@ -1663,7 +1668,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) | |||
1663 | { | 1668 | { |
1664 | u32 addr1, addr2, ports; | 1669 | u32 addr1, addr2, ports; |
1665 | u32 hash, ihl; | 1670 | u32 hash, ihl; |
1666 | u8 ip_proto; | 1671 | u8 ip_proto = 0; |
1667 | 1672 | ||
1668 | if (unlikely(!simple_tx_hashrnd_initialized)) { | 1673 | if (unlikely(!simple_tx_hashrnd_initialized)) { |
1669 | get_random_bytes(&simple_tx_hashrnd, 4); | 1674 | get_random_bytes(&simple_tx_hashrnd, 4); |
@@ -1672,7 +1677,8 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb) | |||
1672 | 1677 | ||
1673 | switch (skb->protocol) { | 1678 | switch (skb->protocol) { |
1674 | case __constant_htons(ETH_P_IP): | 1679 | case __constant_htons(ETH_P_IP): |
1675 | ip_proto = ip_hdr(skb)->protocol; | 1680 | if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET))) |
1681 | ip_proto = ip_hdr(skb)->protocol; | ||
1676 | addr1 = ip_hdr(skb)->saddr; | 1682 | addr1 = ip_hdr(skb)->saddr; |
1677 | addr2 = ip_hdr(skb)->daddr; | 1683 | addr2 = ip_hdr(skb)->daddr; |
1678 | ihl = ip_hdr(skb)->ihl; | 1684 | ihl = ip_hdr(skb)->ihl; |
@@ -1800,9 +1806,13 @@ gso: | |||
1800 | 1806 | ||
1801 | spin_lock(root_lock); | 1807 | spin_lock(root_lock); |
1802 | 1808 | ||
1803 | rc = qdisc_enqueue_root(skb, q); | 1809 | if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) { |
1804 | qdisc_run(q); | 1810 | kfree_skb(skb); |
1805 | 1811 | rc = NET_XMIT_DROP; | |
1812 | } else { | ||
1813 | rc = qdisc_enqueue_root(skb, q); | ||
1814 | qdisc_run(q); | ||
1815 | } | ||
1806 | spin_unlock(root_lock); | 1816 | spin_unlock(root_lock); |
1807 | 1817 | ||
1808 | goto out; | 1818 | goto out; |
@@ -1974,15 +1984,22 @@ static void net_tx_action(struct softirq_action *h) | |||
1974 | 1984 | ||
1975 | head = head->next_sched; | 1985 | head = head->next_sched; |
1976 | 1986 | ||
1977 | smp_mb__before_clear_bit(); | ||
1978 | clear_bit(__QDISC_STATE_SCHED, &q->state); | ||
1979 | |||
1980 | root_lock = qdisc_lock(q); | 1987 | root_lock = qdisc_lock(q); |
1981 | if (spin_trylock(root_lock)) { | 1988 | if (spin_trylock(root_lock)) { |
1989 | smp_mb__before_clear_bit(); | ||
1990 | clear_bit(__QDISC_STATE_SCHED, | ||
1991 | &q->state); | ||
1982 | qdisc_run(q); | 1992 | qdisc_run(q); |
1983 | spin_unlock(root_lock); | 1993 | spin_unlock(root_lock); |
1984 | } else { | 1994 | } else { |
1985 | __netif_schedule(q); | 1995 | if (!test_bit(__QDISC_STATE_DEACTIVATED, |
1996 | &q->state)) { | ||
1997 | __netif_reschedule(q); | ||
1998 | } else { | ||
1999 | smp_mb__before_clear_bit(); | ||
2000 | clear_bit(__QDISC_STATE_SCHED, | ||
2001 | &q->state); | ||
2002 | } | ||
1986 | } | 2003 | } |
1987 | } | 2004 | } |
1988 | } | 2005 | } |
@@ -2084,7 +2101,8 @@ static int ing_filter(struct sk_buff *skb) | |||
2084 | q = rxq->qdisc; | 2101 | q = rxq->qdisc; |
2085 | if (q != &noop_qdisc) { | 2102 | if (q != &noop_qdisc) { |
2086 | spin_lock(qdisc_lock(q)); | 2103 | spin_lock(qdisc_lock(q)); |
2087 | result = qdisc_enqueue_root(skb, q); | 2104 | if (likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) |
2105 | result = qdisc_enqueue_root(skb, q); | ||
2088 | spin_unlock(qdisc_lock(q)); | 2106 | spin_unlock(qdisc_lock(q)); |
2089 | } | 2107 | } |
2090 | 2108 | ||