Thu, Mar 22, 2018 at 11:57:57PM CET, d...@cumulusnetworks.com wrote: >From: David Ahern <dsah...@gmail.com>
[...] >+void nsim_devlink_teardown(struct netdevsim *ns) >+{ >+ if (ns->devlink) { >+ struct net *net = dev_net(ns->netdev); >+ bool *reg_devlink = net_generic(net, nsim_devlink_id); >+ >+ devlink_unregister(ns->devlink); >+ devlink_free(ns->devlink); >+ ns->devlink = NULL; >+ >+ nsim_devlink_net_reset(net); >+ *reg_devlink = true; >+ } >+} >+ >+void nsim_devlink_setup(struct netdevsim *ns) >+{ >+ struct net *net = dev_net(ns->netdev); >+ bool *reg_devlink = net_generic(net, nsim_devlink_id); >+ struct devlink *devlink; >+ int err = -ENOMEM; >+ >+ /* only one device per namespace controls devlink */ >+ if (!*reg_devlink) { >+ ns->devlink = NULL; >+ return; >+ } >+ >+ devlink = devlink_alloc(&nsim_devlink_ops, 0); >+ if (!devlink) >+ return; >+ >+ devlink_net_set(devlink, net); >+ err = devlink_register(devlink, &ns->dev); This reg_devlink construct looks odd. Why don't you leave the devlink instance in init_ns? >+ if (err) >+ goto err_devlink_free; >+ >+ err = devlink_resources_register(devlink); >+ if (err) >+ goto err_dl_unregister; >+ >+ ns->devlink = devlink; >+ >+ *reg_devlink = false; >+ >+ return; >+ >+err_dl_unregister: >+ devlink_unregister(devlink); >+err_devlink_free: >+ devlink_free(devlink); >+} >+ >+/* Initialize per network namespace state */ >+static int __net_init nsim_devlink_netns_init(struct net *net) >+{ >+ bool *reg_devlink = net_generic(net, nsim_devlink_id); >+ >+ *reg_devlink = true; >+ >+ return 0; >+} >+ >+static struct pernet_operations nsim_devlink_net_ops __net_initdata = { >+ .init = nsim_devlink_netns_init, >+ .id = &nsim_devlink_id, >+ .size = sizeof(bool), >+ .async = true, >+};