Message ID | 20210206125551.8616-3-parav@nvidia.com |
---|---|
State | Superseded |
Headers | show |
Series | netdevsim port add, delete support | expand |
Hi Parav, Thank you for the patch! Yet something to improve: [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153 base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 6626a0266566c5aea16178c5e6cd7fc4db3f2f56 config: x86_64-randconfig-a004-20210206 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476) 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 # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://github.com/0day-ci/linux/commit/980b8cbe1c29602278397d53732cc258b1d62416 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Parav-Pandit/netdevsim-port-add-delete-support/20210206-210153 git checkout 980b8cbe1c29602278397d53732cc258b1d62416 # 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 errors (new ones prefixed by >>): In file included from drivers/net/netdevsim/port_function.c:7: drivers/net/netdevsim/netdevsim.h:318:23: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility] const struct devlink_port_new_attrs *attrs, ^ drivers/net/netdevsim/port_function.c:54:20: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility] const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:74:23: error: incomplete definition of type 'struct devlink_port_new_attrs' port->flavour = attrs->flavour; ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:76:11: error: incomplete definition of type 'struct devlink_port_new_attrs' if (attrs->port_index_valid) ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:78:16: error: incomplete definition of type 'struct devlink_port_new_attrs' attrs->port_index, ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:79:16: error: incomplete definition of type 'struct devlink_port_new_attrs' attrs->port_index, GFP_KERNEL); ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:91:16: error: incomplete definition of type 'struct devlink_port_new_attrs' attrs->pfnum, attrs->pfnum, ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:91:30: error: incomplete definition of type 'struct devlink_port_new_attrs' attrs->pfnum, attrs->pfnum, ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ >> drivers/net/netdevsim/port_function.c:97:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF' case DEVLINK_PORT_FLAVOUR_PCI_SF: ^ drivers/net/netdevsim/port_function.c:98:12: error: incomplete definition of type 'struct devlink_port_new_attrs' if (attrs->sfnum_valid) ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:99:63: error: incomplete definition of type 'struct devlink_port_new_attrs' ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum, ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:100:17: error: incomplete definition of type 'struct devlink_port_new_attrs' attrs->sfnum, GFP_KERNEL); ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:106:22: error: incomplete definition of type 'struct devlink_port_new_attrs' port->pfnum = attrs->pfnum; ~~~~~^ drivers/net/netdevsim/port_function.c:54:20: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:131:7: error: use of undeclared identifier 'DEVLINK_PORT_FLAVOUR_PCI_SF' case DEVLINK_PORT_FLAVOUR_PCI_SF: ^ drivers/net/netdevsim/port_function.c:151:19: warning: declaration of 'struct devlink_port_new_attrs' will not be visible outside of this function [-Wvisibility] const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:156:12: error: incomplete definition of type 'struct devlink_port_new_attrs' if (attrs->port_index_valid && ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:157:31: error: incomplete definition of type 'struct devlink_port_new_attrs' tmp->port_index == attrs->port_index) ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:159:12: error: incomplete definition of type 'struct devlink_port_new_attrs' if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF && ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:161:26: error: incomplete definition of type 'struct devlink_port_new_attrs' tmp->pfnum == attrs->pfnum) ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:164:12: error: incomplete definition of type 'struct devlink_port_new_attrs' if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF && ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:166:12: error: incomplete definition of type 'struct devlink_port_new_attrs' attrs->sfnum_valid && ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ drivers/net/netdevsim/port_function.c:167:26: error: incomplete definition of type 'struct devlink_port_new_attrs' tmp->sfnum == attrs->sfnum && tmp->pfnum == attrs->pfnum) ~~~~~^ drivers/net/netdevsim/port_function.c:151:19: note: forward declaration of 'struct devlink_port_new_attrs' const struct devlink_port_new_attrs *attrs) ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 3 warnings and 20 errors generated. vim +/DEVLINK_PORT_FLAVOUR_PCI_SF +97 drivers/net/netdevsim/port_function.c 51 52 static struct nsim_port_fn * 53 nsim_devlink_port_fn_alloc(struct nsim_dev *dev, 54 const struct devlink_port_new_attrs *attrs) 55 { 56 struct nsim_bus_dev *nsim_bus_dev = dev->nsim_bus_dev; 57 struct nsim_port_fn *port; 58 struct net_device *netdev; 59 int ret; 60 61 netdev = alloc_netdev(sizeof(*port), "eth%d", NET_NAME_UNKNOWN, 62 nsim_port_fn_ndev_setup); 63 if (!netdev) 64 return ERR_PTR(-ENOMEM); 65 66 dev_net_set(netdev, nsim_dev_net(dev)); 67 netdev->netdev_ops = &nsim_netdev_ops; 68 nsim_bus_dev = dev->nsim_bus_dev; 69 SET_NETDEV_DEV(netdev, &nsim_bus_dev->dev); 70 71 port = netdev_priv(netdev); 72 memset(port, 0, sizeof(*port)); 73 port->netdev = netdev; 74 port->flavour = attrs->flavour; 75 76 if (attrs->port_index_valid) 77 ret = ida_alloc_range(&dev->port_functions.ida, 78 attrs->port_index, 79 attrs->port_index, GFP_KERNEL); 80 else 81 ret = ida_alloc_min(&dev->port_functions.ida, 82 nsim_bus_dev->port_count, GFP_KERNEL); 83 if (ret < 0) 84 goto port_ida_err; 85 86 port->port_index = ret; 87 88 switch (port->flavour) { 89 case DEVLINK_PORT_FLAVOUR_PCI_PF: 90 ret = ida_alloc_range(&dev->port_functions.pfnum_ida, 91 attrs->pfnum, attrs->pfnum, 92 GFP_KERNEL); 93 if (ret < 0) 94 goto fn_ida_err; 95 port->pfnum = ret; 96 break; > 97 case DEVLINK_PORT_FLAVOUR_PCI_SF: 98 if (attrs->sfnum_valid) 99 ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum, 100 attrs->sfnum, GFP_KERNEL); 101 else 102 ret = ida_alloc(&dev->port_functions.sfnum_ida, GFP_KERNEL); 103 if (ret < 0) 104 goto fn_ida_err; 105 port->sfnum = ret; 106 port->pfnum = attrs->pfnum; 107 break; 108 default: 109 break; 110 } 111 /* refcount_t is not needed as port is protected by port_functions.mutex. 112 * This count is to keep track of how many SF ports are attached a PF port. 113 */ 114 port->refcount = 1; 115 return port; 116 117 fn_ida_err: 118 ida_simple_remove(&dev->port_functions.ida, port->port_index); 119 port_ida_err: 120 free_netdev(netdev); 121 return ERR_PTR(ret); 122 } 123 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 31beddede0f2..efa7c08d842a 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -233,6 +233,7 @@ struct nsim_dev { struct list_head head; struct ida ida; struct ida pfnum_ida; + struct ida sfnum_ida; struct mutex disable_mutex; /* protects port deletion * by driver unload context */ diff --git a/drivers/net/netdevsim/port_function.c b/drivers/net/netdevsim/port_function.c index a957b754ef92..a2f62a609e9b 100644 --- a/drivers/net/netdevsim/port_function.c +++ b/drivers/net/netdevsim/port_function.c @@ -9,9 +9,12 @@ struct nsim_port_fn { struct devlink_port dl_port; struct net_device *netdev; + struct nsim_port_fn *pf_pfn; struct list_head list; unsigned int port_index; enum devlink_port_flavour flavour; + int refcount; /* Counts how many sf ports are bound attached to this pf port. */ + u32 sfnum; u16 pfnum; }; @@ -91,9 +94,24 @@ nsim_devlink_port_fn_alloc(struct nsim_dev *dev, goto fn_ida_err; port->pfnum = ret; break; + case DEVLINK_PORT_FLAVOUR_PCI_SF: + if (attrs->sfnum_valid) + ret = ida_alloc_range(&dev->port_functions.sfnum_ida, attrs->sfnum, + attrs->sfnum, GFP_KERNEL); + else + ret = ida_alloc(&dev->port_functions.sfnum_ida, GFP_KERNEL); + if (ret < 0) + goto fn_ida_err; + port->sfnum = ret; + port->pfnum = attrs->pfnum; + break; default: break; } + /* refcount_t is not needed as port is protected by port_functions.mutex. + * This count is to keep track of how many SF ports are attached a PF port. + */ + port->refcount = 1; return port; fn_ida_err: @@ -110,6 +128,9 @@ nsim_devlink_port_fn_free(struct nsim_dev *dev, struct nsim_port_fn *port) case DEVLINK_PORT_FLAVOUR_PCI_PF: ida_simple_remove(&dev->port_functions.pfnum_ida, port->pfnum); break; + case DEVLINK_PORT_FLAVOUR_PCI_SF: + ida_simple_remove(&dev->port_functions.sfnum_ida, port->sfnum); + break; default: break; } @@ -139,6 +160,12 @@ nsim_dev_port_port_exists(struct nsim_dev *nsim_dev, tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF && tmp->pfnum == attrs->pfnum) return true; + + if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF && + tmp->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF && + attrs->sfnum_valid && + tmp->sfnum == attrs->sfnum && tmp->pfnum == attrs->pfnum) + return true; } return false; } @@ -153,20 +180,72 @@ nsim_dev_devlink_port_index_lookup(const struct nsim_dev *nsim_dev, list_for_each_entry(port, &nsim_dev->port_functions.head, list) { if (port->port_index != port_index) continue; + if (port->refcount > 1) { + NL_SET_ERR_MSG_MOD(extack, "Port is in use"); + return ERR_PTR(-EBUSY); + } return port; } NL_SET_ERR_MSG_MOD(extack, "User created port not found"); return ERR_PTR(-ENOENT); } +static struct nsim_port_fn * +pf_port_get(struct nsim_dev *nsim_dev, struct nsim_port_fn *port) +{ + struct nsim_port_fn *tmp; + + /* PF port addition doesn't need a parent. */ + if (port->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF) + return NULL; + + list_for_each_entry(tmp, &nsim_dev->port_functions.head, list) { + if (tmp->flavour != DEVLINK_PORT_FLAVOUR_PCI_PF || + tmp->pfnum != port->pfnum) + continue; + + if (tmp->refcount + 1 == INT_MAX) + return ERR_PTR(-ENOSPC); + + port->pf_pfn = tmp; + tmp->refcount++; + return tmp; + } + return ERR_PTR(-ENOENT); +} + +static void pf_port_put(struct nsim_port_fn *port) +{ + if (port->pf_pfn) { + port->pf_pfn->refcount--; + WARN_ON(port->pf_pfn->refcount < 0); + } + port->refcount--; + WARN_ON(port->refcount != 0); +} + static int nsim_devlink_port_fn_add(struct devlink *devlink, struct nsim_dev *nsim_dev, struct nsim_port_fn *port, struct netlink_ext_ack *extack) { + struct nsim_port_fn *pf_pfn; int err; - list_add(&port->list, &nsim_dev->port_functions.head); + /* Keep all PF ports at the start, so that when driver is unloaded + * All SF ports from the end of the list can be removed first. + */ + if (port->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF) + list_add(&port->list, &nsim_dev->port_functions.head); + else + list_add_tail(&port->list, &nsim_dev->port_functions.head); + + pf_pfn = pf_port_get(nsim_dev, port); + if (IS_ERR(pf_pfn)) { + NL_SET_ERR_MSG_MOD(extack, "Fail to get pf port"); + err = PTR_ERR(pf_pfn); + goto pf_err; + } err = devlink_port_register(devlink, &port->dl_port, port->port_index); if (err) @@ -183,6 +262,8 @@ static int nsim_devlink_port_fn_add(struct devlink *devlink, devlink_port_type_clear(&port->dl_port); devlink_port_unregister(&port->dl_port); reg_err: + pf_port_put(port); +pf_err: list_del(&port->list); return err; } @@ -194,13 +275,15 @@ static void nsim_devlink_port_fn_del(struct nsim_dev *nsim_dev, unregister_netdev(port->netdev); devlink_port_unregister(&port->dl_port); list_del(&port->list); + pf_port_put(port); } static bool nsim_dev_port_flavour_supported(const struct nsim_dev *nsim_dev, const struct devlink_port_new_attrs *attrs) { - return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF; + return attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF || + attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_SF; } int nsim_dev_devlink_port_new(struct devlink *devlink, @@ -245,7 +328,12 @@ int nsim_dev_devlink_port_new(struct devlink *devlink, nsim_dev->switch_id.id_len); port->dl_port.attrs.switch_id.id_len = nsim_dev->switch_id.id_len; - devlink_port_attrs_pci_pf_set(&port->dl_port, 0, port->pfnum, false); + if (attrs->flavour == DEVLINK_PORT_FLAVOUR_PCI_PF) + devlink_port_attrs_pci_pf_set(&port->dl_port, 0, + port->pfnum, false); + else + devlink_port_attrs_pci_sf_set(&port->dl_port, 0, port->pfnum, + port->sfnum); err = nsim_devlink_port_fn_add(devlink, nsim_dev, port, extack); if (err) @@ -300,10 +388,13 @@ void nsim_dev_port_fn_init(struct nsim_dev *nsim_dev) INIT_LIST_HEAD(&nsim_dev->port_functions.head); ida_init(&nsim_dev->port_functions.ida); ida_init(&nsim_dev->port_functions.pfnum_ida); + ida_init(&nsim_dev->port_functions.sfnum_ida); } void nsim_dev_port_fn_exit(struct nsim_dev *nsim_dev) { + WARN_ON(!ida_is_empty(&nsim_dev->port_functions.sfnum_ida)); + ida_destroy(&nsim_dev->port_functions.sfnum_ida); WARN_ON(!ida_is_empty(&nsim_dev->port_functions.pfnum_ida)); ida_destroy(&nsim_dev->port_functions.pfnum_ida); WARN_ON(!ida_is_empty(&nsim_dev->port_functions.ida)); @@ -332,6 +423,8 @@ void nsim_dev_port_fn_disable(struct nsim_dev *nsim_dev) * commands have completed, so it is safe to delete all user created * ports. */ + + /* Remove SF ports first, followed by PF ports. */ list_for_each_entry_safe_reverse(port, tmp, &nsim_dev->port_functions.head, list) { nsim_devlink_port_fn_del(nsim_dev, port);