]> Git Repo - linux.git/blobdiff - drivers/net/netdevsim/dev.c
arm64: Use a variable to store non-global mappings decision
[linux.git] / drivers / net / netdevsim / dev.c
index 54ca6681ba3182fa758f3eb1a6c768726ec92cb7..059711edfc61e9d8119d1a35afc7b0dc468f9ed2 100644 (file)
@@ -90,6 +90,10 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
                            &nsim_dev->test1);
        debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, nsim_dev,
                            &nsim_dev_take_snapshot_fops);
+       debugfs_create_bool("dont_allow_reload", 0600, nsim_dev->ddir,
+                           &nsim_dev->dont_allow_reload);
+       debugfs_create_bool("fail_reload", 0600, nsim_dev->ddir,
+                           &nsim_dev->fail_reload);
        return 0;
 }
 
@@ -123,39 +127,6 @@ static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port)
        debugfs_remove_recursive(nsim_dev_port->ddir);
 }
 
-static struct net *nsim_devlink_net(struct devlink *devlink)
-{
-       return &init_net;
-}
-
-static u64 nsim_dev_ipv4_fib_resource_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false);
-}
-
-static u64 nsim_dev_ipv4_fib_rules_res_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false);
-}
-
-static u64 nsim_dev_ipv6_fib_resource_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false);
-}
-
-static u64 nsim_dev_ipv6_fib_rules_res_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false);
-}
-
 static int nsim_dev_resources_register(struct devlink *devlink)
 {
        struct devlink_resource_size_params params = {
@@ -163,9 +134,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                .size_granularity = 1,
                .unit = DEVLINK_RESOURCE_UNIT_ENTRY
        };
-       struct net *net = nsim_devlink_net(devlink);
        int err;
-       u64 n;
 
        /* Resources for IPv4 */
        err = devlink_resource_register(devlink, "IPv4", (u64)-1,
@@ -177,8 +146,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                goto out;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true);
-       err = devlink_resource_register(devlink, "fib", n,
+       err = devlink_resource_register(devlink, "fib", (u64)-1,
                                        NSIM_RESOURCE_IPV4_FIB,
                                        NSIM_RESOURCE_IPV4, &params);
        if (err) {
@@ -186,8 +154,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                return err;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true);
-       err = devlink_resource_register(devlink, "fib-rules", n,
+       err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
                                        NSIM_RESOURCE_IPV4_FIB_RULES,
                                        NSIM_RESOURCE_IPV4, &params);
        if (err) {
@@ -205,8 +172,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                goto out;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true);
-       err = devlink_resource_register(devlink, "fib", n,
+       err = devlink_resource_register(devlink, "fib", (u64)-1,
                                        NSIM_RESOURCE_IPV6_FIB,
                                        NSIM_RESOURCE_IPV6, &params);
        if (err) {
@@ -214,8 +180,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                return err;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true);
-       err = devlink_resource_register(devlink, "fib-rules", n,
+       err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
                                        NSIM_RESOURCE_IPV6_FIB_RULES,
                                        NSIM_RESOURCE_IPV6, &params);
        if (err) {
@@ -223,22 +188,6 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                return err;
        }
 
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV4_FIB,
-                                         nsim_dev_ipv4_fib_resource_occ_get,
-                                         net);
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV4_FIB_RULES,
-                                         nsim_dev_ipv4_fib_rules_res_occ_get,
-                                         net);
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV6_FIB,
-                                         nsim_dev_ipv6_fib_resource_occ_get,
-                                         net);
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV6_FIB_RULES,
-                                         nsim_dev_ipv6_fib_rules_res_occ_get,
-                                         net);
 out:
        return err;
 }
@@ -524,36 +473,48 @@ static void nsim_dev_traps_exit(struct devlink *devlink)
        kfree(nsim_dev->trap_data);
 }
 
-static int nsim_dev_reload_down(struct devlink *devlink,
+static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
+                                 struct netlink_ext_ack *extack);
+static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev);
+
+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);
+
+       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");
+               return -EOPNOTSUPP;
+       }
+
+       nsim_dev_reload_destroy(nsim_dev);
        return 0;
 }
 
 static int nsim_dev_reload_up(struct devlink *devlink,
                              struct netlink_ext_ack *extack)
 {
-       enum nsim_resource_id res_ids[] = {
-               NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES,
-               NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES
-       };
-       struct net *net = nsim_devlink_net(devlink);
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(res_ids); ++i) {
-               int err;
-               u64 val;
+       struct nsim_dev *nsim_dev = devlink_priv(devlink);
 
-               err = devlink_resource_size_get(devlink, res_ids[i], &val);
-               if (!err) {
-                       err = nsim_fib_set_max(net, res_ids[i], val, extack);
-                       if (err)
-                               return err;
-               }
+       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");
+               return -EINVAL;
        }
-       nsim_devlink_param_load_driverinit_values(devlink);
 
-       return 0;
+       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);
 }
 
 #define NSIM_DEV_FLASH_SIZE 500000
@@ -649,6 +610,7 @@ nsim_dev_devlink_trap_action_set(struct devlink *devlink,
 static const struct devlink_ops nsim_dev_devlink_ops = {
        .reload_down = nsim_dev_reload_down,
        .reload_up = nsim_dev_reload_up,
+       .info_get = nsim_dev_info_get,
        .flash_update = nsim_dev_flash_update,
        .trap_init = nsim_dev_devlink_trap_init,
        .trap_action_set = nsim_dev_devlink_trap_action_set,
@@ -657,93 +619,6 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
 #define NSIM_DEV_MAX_MACS_DEFAULT 32
 #define NSIM_DEV_TEST1_DEFAULT true
 
-static struct nsim_dev *
-nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
-{
-       struct nsim_dev *nsim_dev;
-       struct devlink *devlink;
-       int err;
-
-       devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev));
-       if (!devlink)
-               return ERR_PTR(-ENOMEM);
-       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->port_list_lock);
-       nsim_dev->fw_update_status = true;
-       nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
-       nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
-
-       err = nsim_dev_resources_register(devlink);
-       if (err)
-               goto err_devlink_free;
-
-       err = devlink_register(devlink, &nsim_bus_dev->dev);
-       if (err)
-               goto err_resources_unregister;
-
-       err = devlink_params_register(devlink, nsim_devlink_params,
-                                     ARRAY_SIZE(nsim_devlink_params));
-       if (err)
-               goto err_dl_unregister;
-       nsim_devlink_set_params_init_values(nsim_dev, devlink);
-
-       err = nsim_dev_dummy_region_init(nsim_dev, devlink);
-       if (err)
-               goto err_params_unregister;
-
-       err = nsim_dev_traps_init(devlink);
-       if (err)
-               goto err_dummy_region_exit;
-
-       err = nsim_dev_debugfs_init(nsim_dev);
-       if (err)
-               goto err_traps_exit;
-
-       err = nsim_bpf_dev_init(nsim_dev);
-       if (err)
-               goto err_debugfs_exit;
-
-       devlink_params_publish(devlink);
-       return nsim_dev;
-
-err_debugfs_exit:
-       nsim_dev_debugfs_exit(nsim_dev);
-err_traps_exit:
-       nsim_dev_traps_exit(devlink);
-err_dummy_region_exit:
-       nsim_dev_dummy_region_exit(nsim_dev);
-err_params_unregister:
-       devlink_params_unregister(devlink, nsim_devlink_params,
-                                 ARRAY_SIZE(nsim_devlink_params));
-err_dl_unregister:
-       devlink_unregister(devlink);
-err_resources_unregister:
-       devlink_resources_unregister(devlink, NULL);
-err_devlink_free:
-       devlink_free(devlink);
-       return ERR_PTR(err);
-}
-
-static void nsim_dev_destroy(struct nsim_dev *nsim_dev)
-{
-       struct devlink *devlink = priv_to_devlink(nsim_dev);
-
-       nsim_bpf_dev_exit(nsim_dev);
-       nsim_dev_debugfs_exit(nsim_dev);
-       nsim_dev_traps_exit(devlink);
-       nsim_dev_dummy_region_exit(nsim_dev);
-       devlink_params_unregister(devlink, nsim_devlink_params,
-                                 ARRAY_SIZE(nsim_devlink_params));
-       devlink_unregister(devlink);
-       devlink_resources_unregister(devlink, NULL);
-       mutex_destroy(&nsim_dev->port_list_lock);
-       devlink_free(devlink);
-}
-
 static int __nsim_dev_port_add(struct nsim_dev *nsim_dev,
                               unsigned int port_index)
 {
@@ -813,39 +688,195 @@ static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
        mutex_unlock(&nsim_dev->port_list_lock);
 }
 
-int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
+static int nsim_dev_port_add_all(struct nsim_dev *nsim_dev,
+                                unsigned int port_count)
 {
-       struct nsim_dev *nsim_dev;
-       int i;
-       int err;
-
-       nsim_dev = nsim_dev_create(nsim_bus_dev, nsim_bus_dev->port_count);
-       if (IS_ERR(nsim_dev))
-               return PTR_ERR(nsim_dev);
-       dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
+       int i, err;
 
-       mutex_lock(&nsim_dev->port_list_lock);
-       for (i = 0; i < nsim_bus_dev->port_count; i++) {
+       for (i = 0; i < port_count; i++) {
                err = __nsim_dev_port_add(nsim_dev, i);
                if (err)
                        goto err_port_del_all;
        }
-       mutex_unlock(&nsim_dev->port_list_lock);
        return 0;
 
 err_port_del_all:
-       mutex_unlock(&nsim_dev->port_list_lock);
        nsim_dev_port_del_all(nsim_dev);
-       nsim_dev_destroy(nsim_dev);
        return err;
 }
 
+static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
+                                 struct netlink_ext_ack *extack)
+{
+       struct nsim_bus_dev *nsim_bus_dev = nsim_dev->nsim_bus_dev;
+       struct devlink *devlink;
+       int err;
+
+       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->fib_data = nsim_fib_create(devlink, extack);
+       if (IS_ERR(nsim_dev->fib_data))
+               return PTR_ERR(nsim_dev->fib_data);
+
+       nsim_devlink_param_load_driverinit_values(devlink);
+
+       err = nsim_dev_dummy_region_init(nsim_dev, devlink);
+       if (err)
+               goto err_fib_destroy;
+
+       err = nsim_dev_traps_init(devlink);
+       if (err)
+               goto err_dummy_region_exit;
+
+       err = nsim_dev_health_init(nsim_dev, devlink);
+       if (err)
+               goto err_traps_exit;
+
+       err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
+       if (err)
+               goto err_health_exit;
+
+       return 0;
+
+err_health_exit:
+       nsim_dev_health_exit(nsim_dev);
+err_traps_exit:
+       nsim_dev_traps_exit(devlink);
+err_dummy_region_exit:
+       nsim_dev_dummy_region_exit(nsim_dev);
+err_fib_destroy:
+       nsim_fib_destroy(devlink, nsim_dev->fib_data);
+       return err;
+}
+
+int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
+{
+       struct nsim_dev *nsim_dev;
+       struct devlink *devlink;
+       int err;
+
+       devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev));
+       if (!devlink)
+               return -ENOMEM;
+       devlink_net_set(devlink, nsim_bus_dev->initial_net);
+       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->port_list_lock);
+       nsim_dev->fw_update_status = true;
+       nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
+       nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
+
+       dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
+
+       err = nsim_dev_resources_register(devlink);
+       if (err)
+               goto err_devlink_free;
+
+       nsim_dev->fib_data = nsim_fib_create(devlink, NULL);
+       if (IS_ERR(nsim_dev->fib_data)) {
+               err = PTR_ERR(nsim_dev->fib_data);
+               goto err_resources_unregister;
+       }
+
+       err = devlink_register(devlink, &nsim_bus_dev->dev);
+       if (err)
+               goto err_fib_destroy;
+
+       err = devlink_params_register(devlink, nsim_devlink_params,
+                                     ARRAY_SIZE(nsim_devlink_params));
+       if (err)
+               goto err_dl_unregister;
+       nsim_devlink_set_params_init_values(nsim_dev, devlink);
+
+       err = nsim_dev_dummy_region_init(nsim_dev, devlink);
+       if (err)
+               goto err_params_unregister;
+
+       err = nsim_dev_traps_init(devlink);
+       if (err)
+               goto err_dummy_region_exit;
+
+       err = nsim_dev_debugfs_init(nsim_dev);
+       if (err)
+               goto err_traps_exit;
+
+       err = nsim_dev_health_init(nsim_dev, devlink);
+       if (err)
+               goto err_debugfs_exit;
+
+       err = nsim_bpf_dev_init(nsim_dev);
+       if (err)
+               goto err_health_exit;
+
+       err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count);
+       if (err)
+               goto err_bpf_dev_exit;
+
+       devlink_params_publish(devlink);
+       devlink_reload_enable(devlink);
+       return 0;
+
+err_bpf_dev_exit:
+       nsim_bpf_dev_exit(nsim_dev);
+err_health_exit:
+       nsim_dev_health_exit(nsim_dev);
+err_debugfs_exit:
+       nsim_dev_debugfs_exit(nsim_dev);
+err_traps_exit:
+       nsim_dev_traps_exit(devlink);
+err_dummy_region_exit:
+       nsim_dev_dummy_region_exit(nsim_dev);
+err_params_unregister:
+       devlink_params_unregister(devlink, nsim_devlink_params,
+                                 ARRAY_SIZE(nsim_devlink_params));
+err_dl_unregister:
+       devlink_unregister(devlink);
+err_fib_destroy:
+       nsim_fib_destroy(devlink, nsim_dev->fib_data);
+err_resources_unregister:
+       devlink_resources_unregister(devlink, NULL);
+err_devlink_free:
+       devlink_free(devlink);
+       return err;
+}
+
+static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
+{
+       struct devlink *devlink = priv_to_devlink(nsim_dev);
+
+       if (devlink_is_reload_failed(devlink))
+               return;
+       nsim_dev_port_del_all(nsim_dev);
+       nsim_dev_health_exit(nsim_dev);
+       nsim_dev_traps_exit(devlink);
+       nsim_dev_dummy_region_exit(nsim_dev);
+       mutex_destroy(&nsim_dev->port_list_lock);
+       nsim_fib_destroy(devlink, nsim_dev->fib_data);
+}
+
 void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
 {
        struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
+       struct devlink *devlink = priv_to_devlink(nsim_dev);
 
-       nsim_dev_port_del_all(nsim_dev);
-       nsim_dev_destroy(nsim_dev);
+       devlink_reload_disable(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_unregister(devlink);
+       devlink_resources_unregister(devlink, NULL);
+       devlink_free(devlink);
 }
 
 static struct nsim_dev_port *
This page took 0.044278 seconds and 4 git commands to generate.