diff options
author | John Fastabend <john.fastabend@gmail.com> | 2014-09-12 23:04:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-13 12:30:25 -0400 |
commit | 46e5da40aec256155cfedee96dd21a75da941f2c (patch) | |
tree | cc3986c52025d252c2a063053692595e60c80e13 /net/core | |
parent | d1015645dd535bbf10e52a3ef6d02ee0c3e0b267 (diff) |
net: qdisc: use rcu prefix and silence sparse warnings
Add __rcu notation to qdisc handling by doing this we can make
smatch output more legible. And anyways some of the cases should
be using rcu_dereference() see qdisc_all_tx_empty(),
qdisc_tx_chainging(), and so on.
Also *wake_queue() API is commonly called from driver timer routines
without rcu lock or rtnl lock. So I added rcu_read_lock() blocks
around netif_wake_subqueue and netif_tx_wake_queue.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 3c6a967e5830..b3d6dbc0c696 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2177,6 +2177,53 @@ static struct dev_kfree_skb_cb *get_kfree_skb_cb(const struct sk_buff *skb) | |||
2177 | return (struct dev_kfree_skb_cb *)skb->cb; | 2177 | return (struct dev_kfree_skb_cb *)skb->cb; |
2178 | } | 2178 | } |
2179 | 2179 | ||
2180 | void netif_schedule_queue(struct netdev_queue *txq) | ||
2181 | { | ||
2182 | rcu_read_lock(); | ||
2183 | if (!(txq->state & QUEUE_STATE_ANY_XOFF)) { | ||
2184 | struct Qdisc *q = rcu_dereference(txq->qdisc); | ||
2185 | |||
2186 | __netif_schedule(q); | ||
2187 | } | ||
2188 | rcu_read_unlock(); | ||
2189 | } | ||
2190 | EXPORT_SYMBOL(netif_schedule_queue); | ||
2191 | |||
2192 | /** | ||
2193 | * netif_wake_subqueue - allow sending packets on subqueue | ||
2194 | * @dev: network device | ||
2195 | * @queue_index: sub queue index | ||
2196 | * | ||
2197 | * Resume individual transmit queue of a device with multiple transmit queues. | ||
2198 | */ | ||
2199 | void netif_wake_subqueue(struct net_device *dev, u16 queue_index) | ||
2200 | { | ||
2201 | struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index); | ||
2202 | |||
2203 | if (test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &txq->state)) { | ||
2204 | struct Qdisc *q; | ||
2205 | |||
2206 | rcu_read_lock(); | ||
2207 | q = rcu_dereference(txq->qdisc); | ||
2208 | __netif_schedule(q); | ||
2209 | rcu_read_unlock(); | ||
2210 | } | ||
2211 | } | ||
2212 | EXPORT_SYMBOL(netif_wake_subqueue); | ||
2213 | |||
2214 | void netif_tx_wake_queue(struct netdev_queue *dev_queue) | ||
2215 | { | ||
2216 | if (test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state)) { | ||
2217 | struct Qdisc *q; | ||
2218 | |||
2219 | rcu_read_lock(); | ||
2220 | q = rcu_dereference(dev_queue->qdisc); | ||
2221 | __netif_schedule(q); | ||
2222 | rcu_read_unlock(); | ||
2223 | } | ||
2224 | } | ||
2225 | EXPORT_SYMBOL(netif_tx_wake_queue); | ||
2226 | |||
2180 | void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason) | 2227 | void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason) |
2181 | { | 2228 | { |
2182 | unsigned long flags; | 2229 | unsigned long flags; |
@@ -3432,7 +3479,7 @@ static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq) | |||
3432 | skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl); | 3479 | skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl); |
3433 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS); | 3480 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS); |
3434 | 3481 | ||
3435 | q = rxq->qdisc; | 3482 | q = rcu_dereference(rxq->qdisc); |
3436 | if (q != &noop_qdisc) { | 3483 | if (q != &noop_qdisc) { |
3437 | spin_lock(qdisc_lock(q)); | 3484 | spin_lock(qdisc_lock(q)); |
3438 | if (likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) | 3485 | if (likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) |
@@ -3449,7 +3496,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, | |||
3449 | { | 3496 | { |
3450 | struct netdev_queue *rxq = rcu_dereference(skb->dev->ingress_queue); | 3497 | struct netdev_queue *rxq = rcu_dereference(skb->dev->ingress_queue); |
3451 | 3498 | ||
3452 | if (!rxq || rxq->qdisc == &noop_qdisc) | 3499 | if (!rxq || rcu_access_pointer(rxq->qdisc) == &noop_qdisc) |
3453 | goto out; | 3500 | goto out; |
3454 | 3501 | ||
3455 | if (*pt_prev) { | 3502 | if (*pt_prev) { |