aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/sch_generic.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/sch_generic.h')
-rw-r--r--include/net/sch_generic.h58
1 files changed, 50 insertions, 8 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 03ca5d826757..3c8728aaab4e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -23,11 +23,17 @@ struct qdisc_rate_table {
23}; 23};
24 24
25enum qdisc_state_t { 25enum qdisc_state_t {
26 __QDISC_STATE_RUNNING,
27 __QDISC_STATE_SCHED, 26 __QDISC_STATE_SCHED,
28 __QDISC_STATE_DEACTIVATED, 27 __QDISC_STATE_DEACTIVATED,
29}; 28};
30 29
30/*
31 * following bits are only changed while qdisc lock is held
32 */
33enum qdisc___state_t {
34 __QDISC___STATE_RUNNING,
35};
36
31struct qdisc_size_table { 37struct qdisc_size_table {
32 struct list_head list; 38 struct list_head list;
33 struct tc_sizespec szopts; 39 struct tc_sizespec szopts;
@@ -72,10 +78,27 @@ struct Qdisc {
72 unsigned long state; 78 unsigned long state;
73 struct sk_buff_head q; 79 struct sk_buff_head q;
74 struct gnet_stats_basic_packed bstats; 80 struct gnet_stats_basic_packed bstats;
81 unsigned long __state;
75 struct gnet_stats_queue qstats; 82 struct gnet_stats_queue qstats;
76 struct rcu_head rcu_head; 83 struct rcu_head rcu_head;
84 spinlock_t busylock;
77}; 85};
78 86
87static inline bool qdisc_is_running(struct Qdisc *qdisc)
88{
89 return test_bit(__QDISC___STATE_RUNNING, &qdisc->__state);
90}
91
92static inline bool qdisc_run_begin(struct Qdisc *qdisc)
93{
94 return !__test_and_set_bit(__QDISC___STATE_RUNNING, &qdisc->__state);
95}
96
97static inline void qdisc_run_end(struct Qdisc *qdisc)
98{
99 __clear_bit(__QDISC___STATE_RUNNING, &qdisc->__state);
100}
101
79struct Qdisc_class_ops { 102struct Qdisc_class_ops {
80 /* Child qdisc manipulation */ 103 /* Child qdisc manipulation */
81 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *); 104 struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *);
@@ -313,12 +336,24 @@ extern void qdisc_calculate_pkt_len(struct sk_buff *skb,
313extern void tcf_destroy(struct tcf_proto *tp); 336extern void tcf_destroy(struct tcf_proto *tp);
314extern void tcf_destroy_chain(struct tcf_proto **fl); 337extern void tcf_destroy_chain(struct tcf_proto **fl);
315 338
316/* Reset all TX qdiscs of a device. */ 339/* Reset all TX qdiscs greater then index of a device. */
340static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
341{
342 struct Qdisc *qdisc;
343
344 for (; i < dev->num_tx_queues; i++) {
345 qdisc = netdev_get_tx_queue(dev, i)->qdisc;
346 if (qdisc) {
347 spin_lock_bh(qdisc_lock(qdisc));
348 qdisc_reset(qdisc);
349 spin_unlock_bh(qdisc_lock(qdisc));
350 }
351 }
352}
353
317static inline void qdisc_reset_all_tx(struct net_device *dev) 354static inline void qdisc_reset_all_tx(struct net_device *dev)
318{ 355{
319 unsigned int i; 356 qdisc_reset_all_tx_gt(dev, 0);
320 for (i = 0; i < dev->num_tx_queues; i++)
321 qdisc_reset(netdev_get_tx_queue(dev, i)->qdisc);
322} 357}
323 358
324/* Are all TX queues of the device empty? */ 359/* Are all TX queues of the device empty? */
@@ -571,9 +606,16 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen)
571} 606}
572 607
573#ifdef CONFIG_NET_CLS_ACT 608#ifdef CONFIG_NET_CLS_ACT
574static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) 609static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
610 int action)
575{ 611{
576 struct sk_buff *n = skb_clone(skb, gfp_mask); 612 struct sk_buff *n;
613
614 if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) &&
615 !skb_shared(skb))
616 n = skb_get(skb);
617 else
618 n = skb_clone(skb, gfp_mask);
577 619
578 if (n) { 620 if (n) {
579 n->tc_verd = SET_TC_VERD(n->tc_verd, 0); 621 n->tc_verd = SET_TC_VERD(n->tc_verd, 0);