aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/pkt_sched.h2
-rw-r--r--include/net/sch_generic.h15
-rw-r--r--net/core/dev.c4
-rw-r--r--net/sched/sch_generic.c4
4 files changed, 20 insertions, 5 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 9d4d87cc970e..d9549af6929a 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -95,7 +95,7 @@ extern void __qdisc_run(struct Qdisc *q);
95 95
96static inline void qdisc_run(struct Qdisc *q) 96static inline void qdisc_run(struct Qdisc *q)
97{ 97{
98 if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) 98 if (qdisc_run_begin(q))
99 __qdisc_run(q); 99 __qdisc_run(q);
100} 100}
101 101
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 03ca5d826757..9707daed761e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -76,6 +76,21 @@ struct Qdisc {
76 struct rcu_head rcu_head; 76 struct rcu_head rcu_head;
77}; 77};
78 78
79static inline bool qdisc_is_running(struct Qdisc *qdisc)
80{
81 return test_bit(__QDISC_STATE_RUNNING, &qdisc->state);
82}
83
84static inline bool qdisc_run_begin(struct Qdisc *qdisc)
85{
86 return !test_and_set_bit(__QDISC_STATE_RUNNING, &qdisc->state);
87}
88
89static inline void qdisc_run_end(struct Qdisc *qdisc)
90{
91 clear_bit(__QDISC_STATE_RUNNING, &qdisc->state);
92}
93
79struct Qdisc_class_ops { 94struct Qdisc_class_ops {
80 /* Child qdisc manipulation */ 95 /* Child qdisc manipulation */
81 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); 96 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *);
diff --git a/net/core/dev.c b/net/core/dev.c
index 983a3c1d65c4..2733226d90b2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2047,7 +2047,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
2047 kfree_skb(skb); 2047 kfree_skb(skb);
2048 rc = NET_XMIT_DROP; 2048 rc = NET_XMIT_DROP;
2049 } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) && 2049 } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
2050 !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) { 2050 qdisc_run_begin(q)) {
2051 /* 2051 /*
2052 * This is a work-conserving queue; there are no old skbs 2052 * This is a work-conserving queue; there are no old skbs
2053 * waiting to be sent out; and the qdisc is not running - 2053 * waiting to be sent out; and the qdisc is not running -
@@ -2059,7 +2059,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
2059 if (sch_direct_xmit(skb, q, dev, txq, root_lock)) 2059 if (sch_direct_xmit(skb, q, dev, txq, root_lock))
2060 __qdisc_run(q); 2060 __qdisc_run(q);
2061 else 2061 else
2062 clear_bit(__QDISC_STATE_RUNNING, &q->state); 2062 qdisc_run_end(q);
2063 2063
2064 rc = NET_XMIT_SUCCESS; 2064 rc = NET_XMIT_SUCCESS;
2065 } else { 2065 } else {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index bd1892fe4b21..37b86eab6779 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -205,7 +205,7 @@ void __qdisc_run(struct Qdisc *q)
205 } 205 }
206 } 206 }
207 207
208 clear_bit(__QDISC_STATE_RUNNING, &q->state); 208 qdisc_run_end(q);
209} 209}
210 210
211unsigned long dev_trans_start(struct net_device *dev) 211unsigned long dev_trans_start(struct net_device *dev)
@@ -797,7 +797,7 @@ static bool some_qdisc_is_busy(struct net_device *dev)
797 797
798 spin_lock_bh(root_lock); 798 spin_lock_bh(root_lock);
799 799
800 val = (test_bit(__QDISC_STATE_RUNNING, &q->state) || 800 val = (qdisc_is_running(q) ||
801 test_bit(__QDISC_STATE_SCHED, &q->state)); 801 test_bit(__QDISC_STATE_SCHED, &q->state));
802 802
803 spin_unlock_bh(root_lock); 803 spin_unlock_bh(root_lock);