diff options
Diffstat (limited to 'drivers/net/netdevsim/dev.c')
-rw-r--r-- | drivers/net/netdevsim/dev.c | 267 |
1 files changed, 141 insertions, 126 deletions
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 54345c096a16..a7880c7ce94c 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -59,7 +59,7 @@ static struct dentry *nsim_dev_ddir; unsigned int nsim_dev_get_vfs(struct nsim_dev *nsim_dev) { WARN_ON(!lockdep_rtnl_is_held() && - !lockdep_is_held(&nsim_dev->vfs_lock)); + !devl_lock_is_held(priv_to_devlink(nsim_dev))); return nsim_dev->nsim_bus_dev->num_vfs; } @@ -275,7 +275,7 @@ static ssize_t nsim_bus_dev_max_vfs_write(struct file *file, return -ENOMEM; nsim_dev = file->private_data; - mutex_lock(&nsim_dev->vfs_lock); + devl_lock(priv_to_devlink(nsim_dev)); /* Reject if VFs are configured */ if (nsim_dev_get_vfs(nsim_dev)) { ret = -EBUSY; @@ -285,7 +285,7 @@ static ssize_t nsim_bus_dev_max_vfs_write(struct file *file, *ppos += count; ret = count; } - mutex_unlock(&nsim_dev->vfs_lock); + devl_unlock(priv_to_devlink(nsim_dev)); kfree(vfconfigs); return ret; @@ -309,8 +309,10 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev) if (IS_ERR(nsim_dev->ddir)) return PTR_ERR(nsim_dev->ddir); nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir); - if (IS_ERR(nsim_dev->ports_ddir)) - return PTR_ERR(nsim_dev->ports_ddir); + if (IS_ERR(nsim_dev->ports_ddir)) { + err = PTR_ERR(nsim_dev->ports_ddir); + goto err_ddir; + } debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir, &nsim_dev->fw_update_status); debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir, @@ -339,13 +341,14 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev) debugfs_create_bool("fail_trap_policer_counter_get", 0600, nsim_dev->ddir, &nsim_dev->fail_trap_policer_counter_get); + /* caution, dev_max_vfs write takes devlink lock */ debugfs_create_file("max_vfs", 0600, nsim_dev->ddir, nsim_dev, &nsim_dev_max_vfs_fops); nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir); if (IS_ERR(nsim_dev->nodes_ddir)) { err = PTR_ERR(nsim_dev->nodes_ddir); - goto err_out; + goto err_ports_ddir; } debugfs_create_bool("fail_trap_drop_counter_get", 0600, nsim_dev->ddir, @@ -353,8 +356,9 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev) nsim_udp_tunnels_debugfs_create(nsim_dev); return 0; -err_out: +err_ports_ddir: debugfs_remove_recursive(nsim_dev->ports_ddir); +err_ddir: debugfs_remove_recursive(nsim_dev->ddir); return err; } @@ -435,64 +439,70 @@ static int nsim_dev_resources_register(struct devlink *devlink) int err; /* Resources for IPv4 */ - err = devlink_resource_register(devlink, "IPv4", (u64)-1, - NSIM_RESOURCE_IPV4, - DEVLINK_RESOURCE_ID_PARENT_TOP, - ¶ms); + err = devl_resource_register(devlink, "IPv4", (u64)-1, + NSIM_RESOURCE_IPV4, + DEVLINK_RESOURCE_ID_PARENT_TOP, + ¶ms); if (err) { pr_err("Failed to register IPv4 top resource\n"); - goto out; + goto err_out; } - err = devlink_resource_register(devlink, "fib", (u64)-1, - NSIM_RESOURCE_IPV4_FIB, - NSIM_RESOURCE_IPV4, ¶ms); + err = devl_resource_register(devlink, "fib", (u64)-1, + NSIM_RESOURCE_IPV4_FIB, + NSIM_RESOURCE_IPV4, ¶ms); if (err) { pr_err("Failed to register IPv4 FIB resource\n"); - return err; + goto err_out; } - err = devlink_resource_register(devlink, "fib-rules", (u64)-1, - NSIM_RESOURCE_IPV4_FIB_RULES, - NSIM_RESOURCE_IPV4, ¶ms); + err = devl_resource_register(devlink, "fib-rules", (u64)-1, + NSIM_RESOURCE_IPV4_FIB_RULES, + NSIM_RESOURCE_IPV4, ¶ms); if (err) { pr_err("Failed to register IPv4 FIB rules resource\n"); - return err; + goto err_out; } /* Resources for IPv6 */ - err = devlink_resource_register(devlink, "IPv6", (u64)-1, - NSIM_RESOURCE_IPV6, - DEVLINK_RESOURCE_ID_PARENT_TOP, - ¶ms); + err = devl_resource_register(devlink, "IPv6", (u64)-1, + NSIM_RESOURCE_IPV6, + DEVLINK_RESOURCE_ID_PARENT_TOP, + ¶ms); if (err) { pr_err("Failed to register IPv6 top resource\n"); - goto out; + goto err_out; } - err = devlink_resource_register(devlink, "fib", (u64)-1, - NSIM_RESOURCE_IPV6_FIB, - NSIM_RESOURCE_IPV6, ¶ms); + err = devl_resource_register(devlink, "fib", (u64)-1, + NSIM_RESOURCE_IPV6_FIB, + NSIM_RESOURCE_IPV6, ¶ms); if (err) { pr_err("Failed to register IPv6 FIB resource\n"); - return err; + goto err_out; } - err = devlink_resource_register(devlink, "fib-rules", (u64)-1, - NSIM_RESOURCE_IPV6_FIB_RULES, - NSIM_RESOURCE_IPV6, ¶ms); + err = devl_resource_register(devlink, "fib-rules", (u64)-1, + NSIM_RESOURCE_IPV6_FIB_RULES, + NSIM_RESOURCE_IPV6, ¶ms); if (err) { pr_err("Failed to register IPv6 FIB rules resource\n"); - return err; + goto err_out; } /* Resources for nexthops */ - err = devlink_resource_register(devlink, "nexthops", (u64)-1, - NSIM_RESOURCE_NEXTHOPS, - DEVLINK_RESOURCE_ID_PARENT_TOP, - ¶ms); + err = devl_resource_register(devlink, "nexthops", (u64)-1, + NSIM_RESOURCE_NEXTHOPS, + DEVLINK_RESOURCE_ID_PARENT_TOP, + ¶ms); + if (err) { + pr_err("Failed to register NEXTHOPS resource\n"); + goto err_out; + } + return 0; -out: +err_out: + devl_resources_unregister(devlink); return err; } @@ -556,17 +566,20 @@ static int nsim_dev_dummy_region_init(struct nsim_dev *nsim_dev, struct devlink *devlink) { nsim_dev->dummy_region = - devlink_region_create(devlink, &dummy_region_ops, - NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX, - NSIM_DEV_DUMMY_REGION_SIZE); + devl_region_create(devlink, &dummy_region_ops, + NSIM_DEV_DUMMY_REGION_SNAPSHOT_MAX, + NSIM_DEV_DUMMY_REGION_SIZE); return PTR_ERR_OR_ZERO(nsim_dev->dummy_region); } static void nsim_dev_dummy_region_exit(struct nsim_dev *nsim_dev) { - devlink_region_destroy(nsim_dev->dummy_region); + devl_region_destroy(nsim_dev->dummy_region); } +static int +__nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_type type, + unsigned int port_index); static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port); static int nsim_esw_legacy_enable(struct nsim_dev *nsim_dev, @@ -575,12 +588,10 @@ static int nsim_esw_legacy_enable(struct nsim_dev *nsim_dev, struct devlink *devlink = priv_to_devlink(nsim_dev); struct nsim_dev_port *nsim_dev_port, *tmp; - devlink_rate_nodes_destroy(devlink); - mutex_lock(&nsim_dev->port_list_lock); + devl_rate_nodes_destroy(devlink); list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) if (nsim_dev_port_is_vf(nsim_dev_port)) __nsim_dev_port_del(nsim_dev_port); - mutex_unlock(&nsim_dev->port_list_lock); nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY; return 0; } @@ -588,11 +599,11 @@ static int nsim_esw_legacy_enable(struct nsim_dev *nsim_dev, static int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, struct netlink_ext_ack *extack) { - struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev; + struct nsim_dev_port *nsim_dev_port, *tmp; int i, err; for (i = 0; i < nsim_dev_get_vfs(nsim_dev); i++) { - err = nsim_drv_port_add(nsim_bus_dev, NSIM_DEV_PORT_TYPE_VF, i); + err = __nsim_dev_port_add(nsim_dev, NSIM_DEV_PORT_TYPE_VF, i); if (err) { NL_SET_ERR_MSG_MOD(extack, "Failed to initialize VFs' netdevsim ports"); pr_err("Failed to initialize VF id=%d. %d.\n", i, err); @@ -603,8 +614,9 @@ static int nsim_esw_switchdev_enable(struct nsim_dev *nsim_dev, return 0; err_port_add_vfs: - for (i--; i >= 0; i--) - nsim_drv_port_del(nsim_bus_dev, NSIM_DEV_PORT_TYPE_VF, i); + list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) + if (nsim_dev_port_is_vf(nsim_dev_port)) + __nsim_dev_port_del(nsim_dev_port); return err; } @@ -612,22 +624,16 @@ static int nsim_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, struct netlink_ext_ack *extack) { struct nsim_dev *nsim_dev = devlink_priv(devlink); - int err = 0; - mutex_lock(&nsim_dev->vfs_lock); if (mode == nsim_dev->esw_mode) - goto unlock; + return 0; if (mode == DEVLINK_ESWITCH_MODE_LEGACY) - err = nsim_esw_legacy_enable(nsim_dev, extack); - else if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) - err = nsim_esw_switchdev_enable(nsim_dev, extack); - else - err = -EINVAL; + return nsim_esw_legacy_enable(nsim_dev, extack); + if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) + return nsim_esw_switchdev_enable(nsim_dev, extack); -unlock: - mutex_unlock(&nsim_dev->vfs_lock); - return err; + return -EINVAL; } static int nsim_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) @@ -835,14 +841,18 @@ static void nsim_dev_trap_report_work(struct work_struct *work) /* For each running port and enabled packet trap, generate a UDP * packet with a random 5-tuple and report it. */ - mutex_lock(&nsim_dev->port_list_lock); + if (!devl_trylock(priv_to_devlink(nsim_dev))) { + schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 0); + return; + } + list_for_each_entry(nsim_dev_port, &nsim_dev->port_list, list) { if (!netif_running(nsim_dev_port->ns->netdev)) continue; nsim_dev_trap_report(nsim_dev_port); } - mutex_unlock(&nsim_dev->port_list_lock); + devl_unlock(priv_to_devlink(nsim_dev)); schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); @@ -883,18 +893,18 @@ static int nsim_dev_traps_init(struct devlink *devlink) nsim_trap_data->nsim_dev = nsim_dev; nsim_dev->trap_data = nsim_trap_data; - err = devlink_trap_policers_register(devlink, nsim_trap_policers_arr, - policers_count); + err = devl_trap_policers_register(devlink, nsim_trap_policers_arr, + policers_count); if (err) goto err_trap_policers_cnt_free; - err = devlink_trap_groups_register(devlink, nsim_trap_groups_arr, - ARRAY_SIZE(nsim_trap_groups_arr)); + err = devl_trap_groups_register(devlink, nsim_trap_groups_arr, + ARRAY_SIZE(nsim_trap_groups_arr)); if (err) goto err_trap_policers_unregister; - err = devlink_traps_register(devlink, nsim_traps_arr, - ARRAY_SIZE(nsim_traps_arr), NULL); + err = devl_traps_register(devlink, nsim_traps_arr, + ARRAY_SIZE(nsim_traps_arr), NULL); if (err) goto err_trap_groups_unregister; @@ -906,11 +916,11 @@ static int nsim_dev_traps_init(struct devlink *devlink) return 0; err_trap_groups_unregister: - devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr, - ARRAY_SIZE(nsim_trap_groups_arr)); + devl_trap_groups_unregister(devlink, nsim_trap_groups_arr, + ARRAY_SIZE(nsim_trap_groups_arr)); err_trap_policers_unregister: - devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr, - ARRAY_SIZE(nsim_trap_policers_arr)); + devl_trap_policers_unregister(devlink, nsim_trap_policers_arr, + ARRAY_SIZE(nsim_trap_policers_arr)); err_trap_policers_cnt_free: kfree(nsim_trap_data->trap_policers_cnt_arr); err_trap_items_free: @@ -924,13 +934,14 @@ static void nsim_dev_traps_exit(struct devlink *devlink) { struct nsim_dev *nsim_dev = devlink_priv(devlink); + /* caution, trap work takes devlink lock */ cancel_delayed_work_sync(&nsim_dev->trap_data->trap_report_dw); - devlink_traps_unregister(devlink, nsim_traps_arr, - ARRAY_SIZE(nsim_traps_arr)); - devlink_trap_groups_unregister(devlink, nsim_trap_groups_arr, - ARRAY_SIZE(nsim_trap_groups_arr)); - devlink_trap_policers_unregister(devlink, nsim_trap_policers_arr, - ARRAY_SIZE(nsim_trap_policers_arr)); + devl_traps_unregister(devlink, nsim_traps_arr, + ARRAY_SIZE(nsim_traps_arr)); + devl_trap_groups_unregister(devlink, nsim_trap_groups_arr, + ARRAY_SIZE(nsim_trap_groups_arr)); + devl_trap_policers_unregister(devlink, nsim_trap_policers_arr, + ARRAY_SIZE(nsim_trap_policers_arr)); kfree(nsim_dev->trap_data->trap_policers_cnt_arr); kfree(nsim_dev->trap_data->trap_items_arr); kfree(nsim_dev->trap_data); @@ -945,24 +956,16 @@ static int nsim_dev_reload_down(struct devlink *devlink, bool netns_change, struct netlink_ext_ack *extack) { struct nsim_dev *nsim_dev = devlink_priv(devlink); - struct nsim_bus_dev *nsim_bus_dev; - - nsim_bus_dev = nsim_dev->nsim_bus_dev; - if (!mutex_trylock(&nsim_bus_dev->nsim_bus_reload_lock)) - return -EOPNOTSUPP; if (nsim_dev->dont_allow_reload) { /* For testing purposes, user set debugfs dont_allow_reload * value to true. So forbid it. */ NL_SET_ERR_MSG_MOD(extack, "User forbid the reload for testing purposes"); - mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock); return -EOPNOTSUPP; } - nsim_bus_dev->in_reload = true; nsim_dev_reload_destroy(nsim_dev); - mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock); return 0; } @@ -971,33 +974,35 @@ static int nsim_dev_reload_up(struct devlink *devlink, enum devlink_reload_actio struct netlink_ext_ack *extack) { struct nsim_dev *nsim_dev = devlink_priv(devlink); - struct nsim_bus_dev *nsim_bus_dev; - int ret; - - nsim_bus_dev = nsim_dev->nsim_bus_dev; - mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock); - nsim_bus_dev->in_reload = false; if (nsim_dev->fail_reload) { /* For testing purposes, user set debugfs fail_reload * value to true. Fail right away. */ NL_SET_ERR_MSG_MOD(extack, "User setup the reload to fail for testing purposes"); - mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock); return -EINVAL; } *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); - ret = nsim_dev_reload_create(nsim_dev, extack); - mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock); - return ret; + + return nsim_dev_reload_create(nsim_dev, extack); } static int nsim_dev_info_get(struct devlink *devlink, struct devlink_info_req *req, struct netlink_ext_ack *extack) { - return devlink_info_driver_name_put(req, DRV_NAME); + int err; + + err = devlink_info_driver_name_put(req, DRV_NAME); + if (err) + return err; + err = devlink_info_version_stored_put_ext(req, "fw.mgmt", "10.20.30", + DEVLINK_INFO_VERSION_TYPE_COMPONENT); + if (err) + return err; + return devlink_info_version_running_put_ext(req, "fw.mgmt", "10.20.30", + DEVLINK_INFO_VERSION_TYPE_COMPONENT); } #define NSIM_DEV_FLASH_SIZE 500000 @@ -1325,8 +1330,7 @@ nsim_dev_devlink_trap_drop_counter_get(struct devlink *devlink, static const struct devlink_ops nsim_dev_devlink_ops = { .eswitch_mode_set = nsim_devlink_eswitch_mode_set, .eswitch_mode_get = nsim_devlink_eswitch_mode_get, - .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT | - DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, + .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK, .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), .reload_down = nsim_dev_reload_down, .reload_up = nsim_dev_reload_up, @@ -1380,8 +1384,8 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ memcpy(attrs.switch_id.id, nsim_dev->switch_id.id, nsim_dev->switch_id.id_len); attrs.switch_id.id_len = nsim_dev->switch_id.id_len; devlink_port_attrs_set(devlink_port, &attrs); - err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port, - nsim_dev_port->port_index); + err = devl_port_register(priv_to_devlink(nsim_dev), devlink_port, + nsim_dev_port->port_index); if (err) goto err_port_free; @@ -1396,8 +1400,8 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ } if (nsim_dev_port_is_vf(nsim_dev_port)) { - err = devlink_rate_leaf_create(&nsim_dev_port->devlink_port, - nsim_dev_port); + err = devl_rate_leaf_create(&nsim_dev_port->devlink_port, + nsim_dev_port); if (err) goto err_nsim_destroy; } @@ -1412,7 +1416,7 @@ err_nsim_destroy: err_port_debugfs_exit: nsim_dev_port_debugfs_exit(nsim_dev_port); err_dl_port_unregister: - devlink_port_unregister(devlink_port); + devl_port_unregister(devlink_port); err_port_free: kfree(nsim_dev_port); return err; @@ -1424,11 +1428,11 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port) list_del(&nsim_dev_port->list); if (nsim_dev_port_is_vf(nsim_dev_port)) - devlink_rate_leaf_destroy(&nsim_dev_port->devlink_port); + devl_rate_leaf_destroy(&nsim_dev_port->devlink_port); devlink_port_type_clear(devlink_port); nsim_destroy(nsim_dev_port->ns); nsim_dev_port_debugfs_exit(nsim_dev_port); - devlink_port_unregister(devlink_port); + devl_port_unregister(devlink_port); kfree(nsim_dev_port); } @@ -1436,11 +1440,9 @@ static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev) { struct nsim_dev_port *nsim_dev_port, *tmp; - mutex_lock(&nsim_dev->port_list_lock); list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) __nsim_dev_port_del(nsim_dev_port); - mutex_unlock(&nsim_dev->port_list_lock); } static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev, @@ -1470,7 +1472,6 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, devlink = priv_to_devlink(nsim_dev); nsim_dev = devlink_priv(devlink); INIT_LIST_HEAD(&nsim_dev->port_list); - mutex_init(&nsim_dev->port_list_lock); nsim_dev->fw_update_status = true; nsim_dev->fw_update_overwrite_mask = 0; @@ -1498,10 +1499,14 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, if (err) goto err_health_exit; - err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + err = nsim_dev_hwstats_init(nsim_dev); if (err) goto err_psample_exit; + err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + if (err) + goto err_hwstats_exit; + nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, @@ -1509,6 +1514,8 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, &nsim_dev_take_snapshot_fops); return 0; +err_hwstats_exit: + nsim_dev_hwstats_exit(nsim_dev); err_psample_exit: nsim_dev_psample_exit(nsim_dev); err_health_exit: @@ -1532,13 +1539,12 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) nsim_bus_dev->initial_net, &nsim_bus_dev->dev); if (!devlink) return -ENOMEM; + devl_lock(devlink); nsim_dev = devlink_priv(devlink); nsim_dev->nsim_bus_dev = nsim_bus_dev; nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id); get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len); INIT_LIST_HEAD(&nsim_dev->port_list); - mutex_init(&nsim_dev->vfs_lock); - mutex_init(&nsim_dev->port_list_lock); nsim_dev->fw_update_status = true; nsim_dev->fw_update_overwrite_mask = 0; nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT; @@ -1552,7 +1558,7 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) GFP_KERNEL | __GFP_NOWARN); if (!nsim_dev->vfconfigs) { err = -ENOMEM; - goto err_devlink_free; + goto err_devlink_unlock; } err = nsim_dev_resources_register(devlink); @@ -1595,15 +1601,22 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) if (err) goto err_bpf_dev_exit; - err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + err = nsim_dev_hwstats_init(nsim_dev); if (err) goto err_psample_exit; + err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + if (err) + goto err_hwstats_exit; + nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_LEGACY; devlink_set_features(devlink, DEVLINK_F_RELOAD); + devl_unlock(devlink); devlink_register(devlink); return 0; +err_hwstats_exit: + nsim_dev_hwstats_exit(nsim_dev); err_psample_exit: nsim_dev_psample_exit(nsim_dev); err_bpf_dev_exit: @@ -1622,10 +1635,11 @@ err_params_unregister: devlink_params_unregister(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); err_dl_unregister: - devlink_resources_unregister(devlink, NULL); + devl_resources_unregister(devlink); err_vfc_free: kfree(nsim_dev->vfconfigs); -err_devlink_free: +err_devlink_unlock: + devl_unlock(devlink); devlink_free(devlink); dev_set_drvdata(&nsim_bus_dev->dev, NULL); return err; @@ -1639,21 +1653,19 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev) return; debugfs_remove(nsim_dev->take_snapshot); - mutex_lock(&nsim_dev->vfs_lock); if (nsim_dev_get_vfs(nsim_dev)) { nsim_bus_dev_set_vfs(nsim_dev->nsim_bus_dev, 0); if (nsim_esw_mode_is_switchdev(nsim_dev)) nsim_esw_legacy_enable(nsim_dev, NULL); } - mutex_unlock(&nsim_dev->vfs_lock); nsim_dev_port_del_all(nsim_dev); + nsim_dev_hwstats_exit(nsim_dev); nsim_dev_psample_exit(nsim_dev); nsim_dev_health_exit(nsim_dev); nsim_fib_destroy(devlink, nsim_dev->fib_data); nsim_dev_traps_exit(devlink); nsim_dev_dummy_region_exit(nsim_dev); - mutex_destroy(&nsim_dev->port_list_lock); } void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev) @@ -1662,14 +1674,16 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev) struct devlink *devlink = priv_to_devlink(nsim_dev); devlink_unregister(devlink); + devl_lock(devlink); nsim_dev_reload_destroy(nsim_dev); nsim_bpf_dev_exit(nsim_dev); nsim_dev_debugfs_exit(nsim_dev); devlink_params_unregister(devlink, nsim_devlink_params, ARRAY_SIZE(nsim_devlink_params)); - devlink_resources_unregister(devlink, NULL); + devl_resources_unregister(devlink); kfree(nsim_dev->vfconfigs); + devl_unlock(devlink); devlink_free(devlink); dev_set_drvdata(&nsim_bus_dev->dev, NULL); } @@ -1693,12 +1707,12 @@ int nsim_drv_port_add(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); int err; - mutex_lock(&nsim_dev->port_list_lock); + devl_lock(priv_to_devlink(nsim_dev)); if (__nsim_dev_port_lookup(nsim_dev, type, port_index)) err = -EEXIST; else err = __nsim_dev_port_add(nsim_dev, type, port_index); - mutex_unlock(&nsim_dev->port_list_lock); + devl_unlock(priv_to_devlink(nsim_dev)); return err; } @@ -1709,13 +1723,13 @@ int nsim_drv_port_del(struct nsim_bus_dev *nsim_bus_dev, enum nsim_dev_port_type struct nsim_dev_port *nsim_dev_port; int err = 0; - mutex_lock(&nsim_dev->port_list_lock); + devl_lock(priv_to_devlink(nsim_dev)); nsim_dev_port = __nsim_dev_port_lookup(nsim_dev, type, port_index); if (!nsim_dev_port) err = -ENOENT; else __nsim_dev_port_del(nsim_dev_port); - mutex_unlock(&nsim_dev->port_list_lock); + devl_unlock(priv_to_devlink(nsim_dev)); return err; } @@ -1723,9 +1737,10 @@ int nsim_drv_configure_vfs(struct nsim_bus_dev *nsim_bus_dev, unsigned int num_vfs) { struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev); + struct devlink *devlink = priv_to_devlink(nsim_dev); int ret = 0; - mutex_lock(&nsim_dev->vfs_lock); + devl_lock(devlink); if (nsim_bus_dev->num_vfs == num_vfs) goto exit_unlock; if (nsim_bus_dev->num_vfs && num_vfs) { @@ -1751,7 +1766,7 @@ int nsim_drv_configure_vfs(struct nsim_bus_dev *nsim_bus_dev, } exit_unlock: - mutex_unlock(&nsim_dev->vfs_lock); + devl_unlock(devlink); return ret; } |