diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-06-02 06:24:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-02 06:24:13 -0400 |
commit | 371121057607e3127e19b3fa094330181b5b031e (patch) | |
tree | d0803bdf06a50fdad88435588f66b2f0f4c95008 /include/net/sch_generic.h | |
parent | bc135b23d01acf7ee926aaf75b0020c86d3869f9 (diff) |
net: QDISC_STATE_RUNNING dont need atomic bit ops
__QDISC_STATE_RUNNING is always changed while qdisc lock is held.
We can avoid two atomic operations in xmit path, if we move this bit in
a new __state container.
Location of this __state container is carefully chosen so that fast path
only dirties one qdisc cache line.
THROTTLED bit could later be moved into this __state location too, to
avoid dirtying first qdisc cache line.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/sch_generic.h')
-rw-r--r-- | include/net/sch_generic.h | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 9707daed761e..b3591e4a514c 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 | ||
25 | enum qdisc_state_t { | 25 | enum 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 | */ | ||
33 | enum qdisc___state_t { | ||
34 | __QDISC___STATE_RUNNING, | ||
35 | }; | ||
36 | |||
31 | struct qdisc_size_table { | 37 | struct qdisc_size_table { |
32 | struct list_head list; | 38 | struct list_head list; |
33 | struct tc_sizespec szopts; | 39 | struct tc_sizespec szopts; |
@@ -72,23 +78,24 @@ 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; |
77 | }; | 84 | }; |
78 | 85 | ||
79 | static inline bool qdisc_is_running(struct Qdisc *qdisc) | 86 | static inline bool qdisc_is_running(struct Qdisc *qdisc) |
80 | { | 87 | { |
81 | return test_bit(__QDISC_STATE_RUNNING, &qdisc->state); | 88 | return test_bit(__QDISC___STATE_RUNNING, &qdisc->__state); |
82 | } | 89 | } |
83 | 90 | ||
84 | static inline bool qdisc_run_begin(struct Qdisc *qdisc) | 91 | static inline bool qdisc_run_begin(struct Qdisc *qdisc) |
85 | { | 92 | { |
86 | return !test_and_set_bit(__QDISC_STATE_RUNNING, &qdisc->state); | 93 | return !__test_and_set_bit(__QDISC___STATE_RUNNING, &qdisc->__state); |
87 | } | 94 | } |
88 | 95 | ||
89 | static inline void qdisc_run_end(struct Qdisc *qdisc) | 96 | static inline void qdisc_run_end(struct Qdisc *qdisc) |
90 | { | 97 | { |
91 | clear_bit(__QDISC_STATE_RUNNING, &qdisc->state); | 98 | __clear_bit(__QDISC___STATE_RUNNING, &qdisc->__state); |
92 | } | 99 | } |
93 | 100 | ||
94 | struct Qdisc_class_ops { | 101 | struct Qdisc_class_ops { |