Message ID | 20210817132217.100710-3-elic@nvidia.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Indirect dev ingress qdisc creation order | expand |
On Tue, 17 Aug 2021 16:22:17 +0300 Eli Cohen wrote: > Currently, when creating an ingress qdisc on an indirect device before > the driver registered for callbacks, the driver will not have a chance > to register its filter configuration callbacks. > > To fix that, modify the code such that it keeps track of all the ingress > qdiscs that call flow_indr_dev_setup_offload(). When a driver calls > flow_indr_dev_register(), go through the list of tracked ingress qdiscs > and call the driver callback entry point so as to give it a chance to > register its callback. > > Reviewed-by: Jiri Pirko <jiri@nvidia.com> > Signed-off-by: Eli Cohen <elic@nvidia.com> net/core/flow_offload.c: In function ‘existing_qdiscs_register’: net/core/flow_offload.c:365:20: warning: variable ‘block’ set but not used [-Wunused-but-set-variable] 365 | struct tcf_block *block; | ^~~~~
On Tue, Aug 17, 2021 at 07:00:41AM -0700, Jakub Kicinski wrote: > On Tue, 17 Aug 2021 16:22:17 +0300 Eli Cohen wrote: > > Currently, when creating an ingress qdisc on an indirect device before > > the driver registered for callbacks, the driver will not have a chance > > to register its filter configuration callbacks. > > > > To fix that, modify the code such that it keeps track of all the ingress > > qdiscs that call flow_indr_dev_setup_offload(). When a driver calls > > flow_indr_dev_register(), go through the list of tracked ingress qdiscs > > and call the driver callback entry point so as to give it a chance to > > register its callback. > > > > Reviewed-by: Jiri Pirko <jiri@nvidia.com> > > Signed-off-by: Eli Cohen <elic@nvidia.com> > > net/core/flow_offload.c: In function ‘existing_qdiscs_register’: > net/core/flow_offload.c:365:20: warning: variable ‘block’ set but not used [-Wunused-but-set-variable] > 365 | struct tcf_block *block; > | ^~~~~ Thanks Jakub. Would you mind telling me how you invoked the compiler to catch this?
On Tue, 17 Aug 2021 17:30:09 +0300 Eli Cohen wrote: > On Tue, Aug 17, 2021 at 07:00:41AM -0700, Jakub Kicinski wrote: > > On Tue, 17 Aug 2021 16:22:17 +0300 Eli Cohen wrote: > > > Currently, when creating an ingress qdisc on an indirect device before > > > the driver registered for callbacks, the driver will not have a chance > > > to register its filter configuration callbacks. > > > > > > To fix that, modify the code such that it keeps track of all the ingress > > > qdiscs that call flow_indr_dev_setup_offload(). When a driver calls > > > flow_indr_dev_register(), go through the list of tracked ingress qdiscs > > > and call the driver callback entry point so as to give it a chance to > > > register its callback. > > > > > > Reviewed-by: Jiri Pirko <jiri@nvidia.com> > > > Signed-off-by: Eli Cohen <elic@nvidia.com> > > > > net/core/flow_offload.c: In function ‘existing_qdiscs_register’: > > net/core/flow_offload.c:365:20: warning: variable ‘block’ set but not used [-Wunused-but-set-variable] > > 365 | struct tcf_block *block; > > | ^~~~~ > > Thanks Jakub. > Would you mind telling me how you invoked the compiler to catch this? make W=1
Hi Eli, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/Eli-Cohen/Indirect-dev-ingress-qdisc-creation-order/20210817-212524 base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 752be2976405b7499890c0b6bac6d30d34d08bd6 config: x86_64-randconfig-a011-20210816 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 2c6448cdc2f68f8c28fd0bd9404182b81306e6e6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/8e304f96c15799e4618967e3a19cfd25fc9868de git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Eli-Cohen/Indirect-dev-ingress-qdisc-creation-order/20210817-212524 git checkout 8e304f96c15799e4618967e3a19cfd25fc9868de # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> net/core/flow_offload.c:365:20: warning: variable 'block' set but not used [-Wunused-but-set-variable] struct tcf_block *block; ^ 1 warning generated. vim +/block +365 net/core/flow_offload.c 360 361 static void existing_qdiscs_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) 362 { 363 struct flow_block_offload bo; 364 struct flow_indir_dev_info *cur; > 365 struct tcf_block *block; 366 367 list_for_each_entry(cur, &flow_indir_dev_list, list) { 368 memset(&bo, 0, sizeof(bo)); 369 bo.command = cur->command; 370 bo.binder_type = cur->binder_type; 371 block = cur->data; 372 INIT_LIST_HEAD(&bo.cb_list); 373 cb(cur->dev, cur->sch, cb_priv, cur->type, &bo, cur->data, cur->cleanup); 374 list_splice(&bo.cb_list, cur->cb_list); 375 } 376 } 377 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index f3c2841566a0..5aa27acdb0b3 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -453,6 +453,7 @@ struct flow_block_offload { struct list_head *driver_block_list; struct netlink_ext_ack *extack; struct Qdisc *sch; + struct list_head *cb_list_head; }; enum tc_setup_type; diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c index 1da83997e86a..81a504d88e63 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -321,6 +321,7 @@ EXPORT_SYMBOL(flow_block_cb_setup_simple); static DEFINE_MUTEX(flow_indr_block_lock); static LIST_HEAD(flow_block_indr_list); static LIST_HEAD(flow_block_indr_dev_list); +static LIST_HEAD(flow_indir_dev_list); struct flow_indr_dev { struct list_head list; @@ -345,6 +346,35 @@ static struct flow_indr_dev *flow_indr_dev_alloc(flow_indr_block_bind_cb_t *cb, return indr_dev; } +struct flow_indir_dev_info { + void *data; + struct net_device *dev; + struct Qdisc *sch; + enum tc_setup_type type; + void (*cleanup)(struct flow_block_cb *block_cb); + struct list_head list; + enum flow_block_command command; + enum flow_block_binder_type binder_type; + struct list_head *cb_list; +}; + +static void existing_qdiscs_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) +{ + struct flow_block_offload bo; + struct flow_indir_dev_info *cur; + struct tcf_block *block; + + list_for_each_entry(cur, &flow_indir_dev_list, list) { + memset(&bo, 0, sizeof(bo)); + bo.command = cur->command; + bo.binder_type = cur->binder_type; + block = cur->data; + INIT_LIST_HEAD(&bo.cb_list); + cb(cur->dev, cur->sch, cb_priv, cur->type, &bo, cur->data, cur->cleanup); + list_splice(&bo.cb_list, cur->cb_list); + } +} + int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) { struct flow_indr_dev *indr_dev; @@ -366,6 +396,7 @@ int flow_indr_dev_register(flow_indr_block_bind_cb_t *cb, void *cb_priv) } list_add(&indr_dev->list, &flow_block_indr_dev_list); + existing_qdiscs_register(cb, cb_priv); mutex_unlock(&flow_indr_block_lock); return 0; @@ -462,7 +493,59 @@ struct flow_block_cb *flow_indr_block_cb_alloc(flow_setup_cb_t *cb, } EXPORT_SYMBOL(flow_indr_block_cb_alloc); -int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, +static struct flow_indir_dev_info *find_indir_dev(void *data) +{ + struct flow_indir_dev_info *cur; + + list_for_each_entry(cur, &flow_indir_dev_list, list) { + if (cur->data == data) + return cur; + } + return NULL; +} + +static int indir_dev_add(void *data, struct net_device *dev, struct Qdisc *sch, + enum tc_setup_type type, void (*cleanup)(struct flow_block_cb *block_cb), + struct flow_block_offload *bo) +{ + struct flow_indir_dev_info *info; + + info = find_indir_dev(data); + if (info) + return -EEXIST; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->data = data; + info->dev = dev; + info->sch = sch; + info->type = type; + info->cleanup = cleanup; + info->command = bo->command; + info->binder_type = bo->binder_type; + info->cb_list = bo->cb_list_head; + + list_add(&info->list, &flow_indir_dev_list); + return 0; +} + +static int indir_dev_remove(void *data) +{ + struct flow_indir_dev_info *info; + + info = find_indir_dev(data); + if (!info) + return -ENOENT; + + list_del(&info->list); + + kfree(info); + return 0; +} + +int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, enum tc_setup_type type, void *data, struct flow_block_offload *bo, void (*cleanup)(struct flow_block_cb *block_cb)) @@ -470,6 +553,12 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, struct flow_indr_dev *this; mutex_lock(&flow_indr_block_lock); + + if (bo->command == FLOW_BLOCK_BIND) + indir_dev_add(data, dev, sch, type, cleanup, bo); + else if (bo->command == FLOW_BLOCK_UNBIND) + indir_dev_remove(data); + list_for_each_entry(this, &flow_block_indr_dev_list, list) this->cb(dev, sch, this->cb_priv, type, bo, data, cleanup); diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c index f92006cec94c..cbd9f59098b7 100644 --- a/net/netfilter/nf_flow_table_offload.c +++ b/net/netfilter/nf_flow_table_offload.c @@ -1097,6 +1097,7 @@ static void nf_flow_table_block_offload_init(struct flow_block_offload *bo, bo->command = cmd; bo->binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS; bo->extack = extack; + bo->cb_list_head = &flowtable->flow_block.cb_list; INIT_LIST_HEAD(&bo->cb_list); } diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index b58d73a96523..9656c1646222 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -353,6 +353,7 @@ static void nft_flow_block_offload_init(struct flow_block_offload *bo, bo->command = cmd; bo->binder_type = FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS; bo->extack = extack; + bo->cb_list_head = &basechain->flow_block.cb_list; INIT_LIST_HEAD(&bo->cb_list); } diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index e3e79e9bd706..9b276d14be4c 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -634,6 +634,7 @@ static void tcf_block_offload_init(struct flow_block_offload *bo, bo->block_shared = shared; bo->extack = extack; bo->sch = sch; + bo->cb_list_head = &flow_block->cb_list; INIT_LIST_HEAD(&bo->cb_list); }