diff options
| author | David S. Miller <davem@davemloft.net> | 2017-11-03 08:57:35 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-11-03 08:57:35 -0400 |
| commit | 6ee79b6ebf6613f1c5bf2be0c3dca4e51817f2ca (patch) | |
| tree | 54915d3a3f2af715f1681da274e3a98f6198e71b /include | |
| parent | aa5fbf07541bbec0d79f4b32415aff2233971853 (diff) | |
| parent | 46209401f8f6116bd0b2c2d14a63958e83ffca0b (diff) | |
Merge branch 'net-mini_Qdisc'
Jiri Pirko says:
====================
net: core: introduce mini_Qdisc and eliminate usage of tp->q for clsact fastpath
This patchset's main patch is patch number 2. It carries the
description. Patch 1 is just a dependency.
---
v3->v4:
- rebased to be applicable on top of the current net-next
v2->v3:
- Using head change callback to replace miniq pointer every time tp head
changes. This eliminates one rcu dereference and makes the claim "without
added overhead" valid.
v1->v2:
- Use dev instead of skb->dev in sch_handle_egress as pointed out by Daniel
- Fixed synchronize_rcu_bh() in mini_qdisc_disable and commented
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/netdevice.h | 9 | ||||
| -rw-r--r-- | include/net/pkt_cls.h | 14 | ||||
| -rw-r--r-- | include/net/sch_generic.h | 37 |
3 files changed, 48 insertions, 12 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5e02f79b2110..7de7656550c2 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1559,6 +1559,8 @@ enum netdev_priv_flags { | |||
| 1559 | * | 1559 | * |
| 1560 | * @rx_handler: handler for received packets | 1560 | * @rx_handler: handler for received packets |
| 1561 | * @rx_handler_data: XXX: need comments on this one | 1561 | * @rx_handler_data: XXX: need comments on this one |
| 1562 | * @miniq_ingress: ingress/clsact qdisc specific data for | ||
| 1563 | * ingress processing | ||
| 1562 | * @ingress_queue: XXX: need comments on this one | 1564 | * @ingress_queue: XXX: need comments on this one |
| 1563 | * @broadcast: hw bcast address | 1565 | * @broadcast: hw bcast address |
| 1564 | * | 1566 | * |
| @@ -1576,7 +1578,8 @@ enum netdev_priv_flags { | |||
| 1576 | * @tx_global_lock: XXX: need comments on this one | 1578 | * @tx_global_lock: XXX: need comments on this one |
| 1577 | * | 1579 | * |
| 1578 | * @xps_maps: XXX: need comments on this one | 1580 | * @xps_maps: XXX: need comments on this one |
| 1579 | * | 1581 | * @miniq_egress: clsact qdisc specific data for |
| 1582 | * egress processing | ||
| 1580 | * @watchdog_timeo: Represents the timeout that is used by | 1583 | * @watchdog_timeo: Represents the timeout that is used by |
| 1581 | * the watchdog (see dev_watchdog()) | 1584 | * the watchdog (see dev_watchdog()) |
| 1582 | * @watchdog_timer: List of timers | 1585 | * @watchdog_timer: List of timers |
| @@ -1795,7 +1798,7 @@ struct net_device { | |||
| 1795 | void __rcu *rx_handler_data; | 1798 | void __rcu *rx_handler_data; |
| 1796 | 1799 | ||
| 1797 | #ifdef CONFIG_NET_CLS_ACT | 1800 | #ifdef CONFIG_NET_CLS_ACT |
| 1798 | struct tcf_proto __rcu *ingress_cl_list; | 1801 | struct mini_Qdisc __rcu *miniq_ingress; |
| 1799 | #endif | 1802 | #endif |
| 1800 | struct netdev_queue __rcu *ingress_queue; | 1803 | struct netdev_queue __rcu *ingress_queue; |
| 1801 | #ifdef CONFIG_NETFILTER_INGRESS | 1804 | #ifdef CONFIG_NETFILTER_INGRESS |
| @@ -1826,7 +1829,7 @@ struct net_device { | |||
| 1826 | struct xps_dev_maps __rcu *xps_maps; | 1829 | struct xps_dev_maps __rcu *xps_maps; |
| 1827 | #endif | 1830 | #endif |
| 1828 | #ifdef CONFIG_NET_CLS_ACT | 1831 | #ifdef CONFIG_NET_CLS_ACT |
| 1829 | struct tcf_proto __rcu *egress_cl_list; | 1832 | struct mini_Qdisc __rcu *miniq_egress; |
| 1830 | #endif | 1833 | #endif |
| 1831 | 1834 | ||
| 1832 | /* These may be needed for future network-power-down code. */ | 1835 | /* These may be needed for future network-power-down code. */ |
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index d15c40c7bde7..505d4b71975f 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h | |||
| @@ -26,6 +26,8 @@ enum tcf_block_binder_type { | |||
| 26 | 26 | ||
| 27 | struct tcf_block_ext_info { | 27 | struct tcf_block_ext_info { |
| 28 | enum tcf_block_binder_type binder_type; | 28 | enum tcf_block_binder_type binder_type; |
| 29 | tcf_chain_head_change_t *chain_head_change; | ||
| 30 | void *chain_head_change_priv; | ||
| 29 | }; | 31 | }; |
| 30 | 32 | ||
| 31 | struct tcf_block_cb; | 33 | struct tcf_block_cb; |
| @@ -37,12 +39,10 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, | |||
| 37 | void tcf_chain_put(struct tcf_chain *chain); | 39 | void tcf_chain_put(struct tcf_chain *chain); |
| 38 | int tcf_block_get(struct tcf_block **p_block, | 40 | int tcf_block_get(struct tcf_block **p_block, |
| 39 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q); | 41 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q); |
| 40 | int tcf_block_get_ext(struct tcf_block **p_block, | 42 | int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, |
| 41 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, | ||
| 42 | struct tcf_block_ext_info *ei); | 43 | struct tcf_block_ext_info *ei); |
| 43 | void tcf_block_put(struct tcf_block *block); | 44 | void tcf_block_put(struct tcf_block *block); |
| 44 | void tcf_block_put_ext(struct tcf_block *block, | 45 | void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, |
| 45 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, | ||
| 46 | struct tcf_block_ext_info *ei); | 46 | struct tcf_block_ext_info *ei); |
| 47 | 47 | ||
| 48 | static inline struct Qdisc *tcf_block_q(struct tcf_block *block) | 48 | static inline struct Qdisc *tcf_block_q(struct tcf_block *block) |
| @@ -82,8 +82,7 @@ int tcf_block_get(struct tcf_block **p_block, | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static inline | 84 | static inline |
| 85 | int tcf_block_get_ext(struct tcf_block **p_block, | 85 | int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, |
| 86 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, | ||
| 87 | struct tcf_block_ext_info *ei) | 86 | struct tcf_block_ext_info *ei) |
| 88 | { | 87 | { |
| 89 | return 0; | 88 | return 0; |
| @@ -94,8 +93,7 @@ static inline void tcf_block_put(struct tcf_block *block) | |||
| 94 | } | 93 | } |
| 95 | 94 | ||
| 96 | static inline | 95 | static inline |
| 97 | void tcf_block_put_ext(struct tcf_block *block, | 96 | void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, |
| 98 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, | ||
| 99 | struct tcf_block_ext_info *ei) | 97 | struct tcf_block_ext_info *ei) |
| 100 | { | 98 | { |
| 101 | } | 99 | } |
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c23e938f5b19..c64e62c9450a 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
| @@ -260,9 +260,12 @@ struct qdisc_skb_cb { | |||
| 260 | unsigned char data[QDISC_CB_PRIV_LEN]; | 260 | unsigned char data[QDISC_CB_PRIV_LEN]; |
| 261 | }; | 261 | }; |
| 262 | 262 | ||
| 263 | typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv); | ||
| 264 | |||
| 263 | struct tcf_chain { | 265 | struct tcf_chain { |
| 264 | struct tcf_proto __rcu *filter_chain; | 266 | struct tcf_proto __rcu *filter_chain; |
| 265 | struct tcf_proto __rcu **p_filter_chain; | 267 | tcf_chain_head_change_t *chain_head_change; |
| 268 | void *chain_head_change_priv; | ||
| 266 | struct list_head list; | 269 | struct list_head list; |
| 267 | struct tcf_block *block; | 270 | struct tcf_block *block; |
| 268 | u32 index; /* chain index */ | 271 | u32 index; /* chain index */ |
| @@ -901,4 +904,36 @@ static inline void psched_ratecfg_getrate(struct tc_ratespec *res, | |||
| 901 | res->linklayer = (r->linklayer & TC_LINKLAYER_MASK); | 904 | res->linklayer = (r->linklayer & TC_LINKLAYER_MASK); |
| 902 | } | 905 | } |
| 903 | 906 | ||
| 907 | /* Mini Qdisc serves for specific needs of ingress/clsact Qdisc. | ||
| 908 | * The fast path only needs to access filter list and to update stats | ||
| 909 | */ | ||
| 910 | struct mini_Qdisc { | ||
| 911 | struct tcf_proto *filter_list; | ||
| 912 | struct gnet_stats_basic_cpu __percpu *cpu_bstats; | ||
| 913 | struct gnet_stats_queue __percpu *cpu_qstats; | ||
| 914 | struct rcu_head rcu; | ||
| 915 | }; | ||
| 916 | |||
| 917 | static inline void mini_qdisc_bstats_cpu_update(struct mini_Qdisc *miniq, | ||
| 918 | const struct sk_buff *skb) | ||
| 919 | { | ||
| 920 | bstats_cpu_update(this_cpu_ptr(miniq->cpu_bstats), skb); | ||
| 921 | } | ||
| 922 | |||
| 923 | static inline void mini_qdisc_qstats_cpu_drop(struct mini_Qdisc *miniq) | ||
| 924 | { | ||
| 925 | this_cpu_inc(miniq->cpu_qstats->drops); | ||
| 926 | } | ||
| 927 | |||
| 928 | struct mini_Qdisc_pair { | ||
| 929 | struct mini_Qdisc miniq1; | ||
| 930 | struct mini_Qdisc miniq2; | ||
| 931 | struct mini_Qdisc __rcu **p_miniq; | ||
| 932 | }; | ||
| 933 | |||
| 934 | void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | ||
| 935 | struct tcf_proto *tp_head); | ||
| 936 | void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc, | ||
| 937 | struct mini_Qdisc __rcu **p_miniq); | ||
| 938 | |||
| 904 | #endif | 939 | #endif |
