Message ID | 20171017200615.4530-2-jiri@resnulli.us |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Series | net: sched: convert cls ndo_setup_tc offload calls to per-block callbacks | expand |
On Tue, 2017-10-17 at 22:05 +0200, Jiri Pirko wrote: > From: Jiri Pirko <jiri@mellanox.com> > > Introduce new type of ndo_setup_tc message to propage binding/unbinding > of a block to driver. Call this ndo whenever qdisc gets/puts a block. > Alongside with this, there's need to propagate binder type from qdisc > code down to the notifier. So introduce extended variants of > block_get/put in order to pass this info. > > Signed-off-by: Jiri Pirko <jiri@mellanox.com> > --- > include/linux/netdevice.h | 1 + > include/net/pkt_cls.h | 40 +++++++++++++++++++++++++++++++++ > net/sched/cls_api.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- > 3 files changed, 94 insertions(+), 3 deletions(-) > > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index 31bb301..062a4f5 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -771,6 +771,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, > > enum tc_setup_type { > TC_SETUP_MQPRIO, > + TC_SETUP_BLOCK, > TC_SETUP_CLSU32, > TC_SETUP_CLSFLOWER, > TC_SETUP_CLSMATCHALL, I'm not a big fan of adding this to the middle of the enum. It will make it harder for people that have to backport changes and such since it is reordering values that are passed as a part of the kabi between drivers and the kernel. Also does this patch set really need to be 20 patches long? Seems like you could have done this as a set of 8 and another of 12 since you need about 8 patches to get to the point where you start pulling the code out of the drivers. - Alex
Tue, Oct 17, 2017 at 10:22:16PM CEST, alexander.h.duyck@intel.com wrote: >On Tue, 2017-10-17 at 22:05 +0200, Jiri Pirko wrote: >> From: Jiri Pirko <jiri@mellanox.com> >> >> Introduce new type of ndo_setup_tc message to propage binding/unbinding >> of a block to driver. Call this ndo whenever qdisc gets/puts a block. >> Alongside with this, there's need to propagate binder type from qdisc >> code down to the notifier. So introduce extended variants of >> block_get/put in order to pass this info. >> >> Signed-off-by: Jiri Pirko <jiri@mellanox.com> >> --- >> include/linux/netdevice.h | 1 + >> include/net/pkt_cls.h | 40 +++++++++++++++++++++++++++++++++ >> net/sched/cls_api.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- >> 3 files changed, 94 insertions(+), 3 deletions(-) >> >> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h >> index 31bb301..062a4f5 100644 >> --- a/include/linux/netdevice.h >> +++ b/include/linux/netdevice.h >> @@ -771,6 +771,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, >> >> enum tc_setup_type { >> TC_SETUP_MQPRIO, >> + TC_SETUP_BLOCK, >> TC_SETUP_CLSU32, >> TC_SETUP_CLSFLOWER, >> TC_SETUP_CLSMATCHALL, > >I'm not a big fan of adding this to the middle of the enum. It will >make it harder for people that have to backport changes and such since >it is reordering values that are passed as a part of the kabi between >drivers and the kernel. I put it where I think it fits. I never think about backport while working on upstream kernel. I believe it is a bad practise if you do so. But in this case, the backport is trivial, I don't see any problem with that. > >Also does this patch set really need to be 20 patches long? Seems like >you could have done this as a set of 8 and another of 12 since you need >about 8 patches to get to the point where you start pulling the code >out of the drivers. Yeah, basically I can cut the patchset in any place. But I wanted to show the whole change. If there was more drivers using this, I would have to add patches. Cutting it in half just because of the amount feels wrong, it's half way through there :/ If you insist, I can cut it. I can even squash multiple patches to one. But that also feels wrong :/
From: Jiri Pirko <jiri@resnulli.us> Date: Tue, 17 Oct 2017 22:05:56 +0200 > From: Jiri Pirko <jiri@mellanox.com> > > Introduce new type of ndo_setup_tc message to propage binding/unbinding > of a block to driver. Call this ndo whenever qdisc gets/puts a block. > Alongside with this, there's need to propagate binder type from qdisc > code down to the notifier. So introduce extended variants of > block_get/put in order to pass this info. > > Signed-off-by: Jiri Pirko <jiri@mellanox.com> > --- > include/linux/netdevice.h | 1 + > include/net/pkt_cls.h | 40 +++++++++++++++++++++++++++++++++ > net/sched/cls_api.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- > 3 files changed, 94 insertions(+), 3 deletions(-) > > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index 31bb301..062a4f5 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -771,6 +771,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, > > enum tc_setup_type { > TC_SETUP_MQPRIO, > + TC_SETUP_BLOCK, > TC_SETUP_CLSU32, > TC_SETUP_CLSFLOWER, > TC_SETUP_CLSMATCHALL, Like David I think you should add this to the end of the list. If you don't "think" about backporting issues when doing upstream work, you're not "think"ing about some of the people who end up using your code. Thank you.
Thu, Oct 19, 2017 at 02:23:11PM CEST, davem@davemloft.net wrote: >From: Jiri Pirko <jiri@resnulli.us> >Date: Tue, 17 Oct 2017 22:05:56 +0200 > >> From: Jiri Pirko <jiri@mellanox.com> >> >> Introduce new type of ndo_setup_tc message to propage binding/unbinding >> of a block to driver. Call this ndo whenever qdisc gets/puts a block. >> Alongside with this, there's need to propagate binder type from qdisc >> code down to the notifier. So introduce extended variants of >> block_get/put in order to pass this info. >> >> Signed-off-by: Jiri Pirko <jiri@mellanox.com> >> --- >> include/linux/netdevice.h | 1 + >> include/net/pkt_cls.h | 40 +++++++++++++++++++++++++++++++++ >> net/sched/cls_api.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- >> 3 files changed, 94 insertions(+), 3 deletions(-) >> >> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h >> index 31bb301..062a4f5 100644 >> --- a/include/linux/netdevice.h >> +++ b/include/linux/netdevice.h >> @@ -771,6 +771,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, >> >> enum tc_setup_type { >> TC_SETUP_MQPRIO, >> + TC_SETUP_BLOCK, >> TC_SETUP_CLSU32, >> TC_SETUP_CLSFLOWER, >> TC_SETUP_CLSMATCHALL, > >Like David I think you should add this to the end of the list. > >If you don't "think" about backporting issues when doing upstream >work, you're not "think"ing about some of the people who end up using >your code. Okay, I don't mind much putting this at the end. I did a lot of backports in my life, things like this are the easiest to handle, that's why I don't believe we should consider it. :) There are much more problematic things during backport, like changes of parameters of exported functions or adding fields to structs. That we correctly don't care about upstream. Now we care about adding new enum values to the end? That does not make sense to me, sorry :/ For the clarity, I know why I say "people should not think about backporting while working on features upstream". I was in position of adding a feature and doing the backport of it many times. The reason is simply because people would tend to do non-optimal solution just because it will be easy to backport and their work would be easier.
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 31bb301..062a4f5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -771,6 +771,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, enum tc_setup_type { TC_SETUP_MQPRIO, + TC_SETUP_BLOCK, TC_SETUP_CLSU32, TC_SETUP_CLSFLOWER, TC_SETUP_CLSMATCHALL, diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 49a143e..41bc7d7 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -17,13 +17,27 @@ struct tcf_walker { int register_tcf_proto_ops(struct tcf_proto_ops *ops); int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); +enum tcf_block_binder_type { + TCF_BLOCK_BINDER_TYPE_UNSPEC, +}; + +struct tcf_block_ext_info { + enum tcf_block_binder_type binder_type; +}; + #ifdef CONFIG_NET_CLS struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, bool create); void tcf_chain_put(struct tcf_chain *chain); int tcf_block_get(struct tcf_block **p_block, struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q); +int tcf_block_get_ext(struct tcf_block **p_block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct tcf_block_ext_info *ei); void tcf_block_put(struct tcf_block *block); +void tcf_block_put_ext(struct tcf_block *block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct tcf_block_ext_info *ei); static inline struct Qdisc *tcf_block_q(struct tcf_block *block) { @@ -46,10 +60,25 @@ int tcf_block_get(struct tcf_block **p_block, return 0; } +static inline +int tcf_block_get_ext(struct tcf_block **p_block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct tcf_block_ext_info *ei) +{ + return 0; +} + static inline void tcf_block_put(struct tcf_block *block) { } +static inline +void tcf_block_put_ext(struct tcf_block *block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct tcf_block_ext_info *ei) +{ +} + static inline struct Qdisc *tcf_block_q(struct tcf_block *block) { return NULL; @@ -434,6 +463,17 @@ tcf_match_indev(struct sk_buff *skb, int ifindex) int tc_setup_cb_call(struct tcf_exts *exts, enum tc_setup_type type, void *type_data, bool err_stop); +enum tc_block_command { + TC_BLOCK_BIND, + TC_BLOCK_UNBIND, +}; + +struct tc_block_offload { + enum tc_block_command command; + enum tcf_block_binder_type binder_type; + struct tcf_block *block; +}; + struct tc_cls_common_offload { u32 chain_index; __be16 protocol; diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 2e8e87f..92dce26 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -240,8 +240,36 @@ tcf_chain_filter_chain_ptr_set(struct tcf_chain *chain, chain->p_filter_chain = p_filter_chain; } -int tcf_block_get(struct tcf_block **p_block, - struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q) +static void tcf_block_offload_cmd(struct tcf_block *block, struct Qdisc *q, + struct tcf_block_ext_info *ei, + enum tc_block_command command) +{ + struct net_device *dev = q->dev_queue->dev; + struct tc_block_offload bo = {}; + + if (!tc_can_offload(dev)) + return; + bo.command = command; + bo.binder_type = ei->binder_type; + bo.block = block; + dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_BLOCK, &bo); +} + +static void tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q, + struct tcf_block_ext_info *ei) +{ + tcf_block_offload_cmd(block, q, ei, TC_BLOCK_BIND); +} + +static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q, + struct tcf_block_ext_info *ei) +{ + tcf_block_offload_cmd(block, q, ei, TC_BLOCK_UNBIND); +} + +int tcf_block_get_ext(struct tcf_block **p_block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct tcf_block_ext_info *ei) { struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL); struct tcf_chain *chain; @@ -259,6 +287,7 @@ int tcf_block_get(struct tcf_block **p_block, tcf_chain_filter_chain_ptr_set(chain, p_filter_chain); block->net = qdisc_net(q); block->q = q; + tcf_block_offload_bind(block, q, ei); *p_block = block; return 0; @@ -266,15 +295,28 @@ int tcf_block_get(struct tcf_block **p_block, kfree(block); return err; } +EXPORT_SYMBOL(tcf_block_get_ext); + +int tcf_block_get(struct tcf_block **p_block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q) +{ + struct tcf_block_ext_info ei = {0, }; + + return tcf_block_get_ext(p_block, p_filter_chain, q, &ei); +} EXPORT_SYMBOL(tcf_block_get); -void tcf_block_put(struct tcf_block *block) +void tcf_block_put_ext(struct tcf_block *block, + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct tcf_block_ext_info *ei) { struct tcf_chain *chain, *tmp; if (!block) return; + tcf_block_offload_unbind(block, q, ei); + /* XXX: Standalone actions are not allowed to jump to any chain, and * bound actions should be all removed after flushing. However, * filters are destroyed in RCU callbacks, we have to hold the chains @@ -302,6 +344,14 @@ void tcf_block_put(struct tcf_block *block) tcf_chain_put(chain); kfree(block); } +EXPORT_SYMBOL(tcf_block_put_ext); + +void tcf_block_put(struct tcf_block *block) +{ + struct tcf_block_ext_info ei = {0, }; + + tcf_block_put_ext(block, NULL, block->q, &ei); +} EXPORT_SYMBOL(tcf_block_put); /* Main classifier routine: scans classifier chain attached