From: Jiri Pirko <jiri@resnulli.us>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, mlxsw@mellanox.com,
jakub.kicinski@netronome.com, dsahern@gmail.com
Subject: [patch net-next v4 13/16] netdevsim: implement dev probe/remove skeleton with port initialization
Date: Thu, 25 Apr 2019 15:59:53 +0200 [thread overview]
Message-ID: <20190425135956.3970-14-jiri@resnulli.us> (raw)
In-Reply-To: <20190425135956.3970-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Implement netdevsim bus probing of netdevsim devices. For every probed
device create a devlink instance. According to the user-passed value,
create a number of ports represented by devlink port instances.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v3->v4:
- fix wrapping of function declararions according to Jakub's rules.
- rebased
v1->v2:
- changed port array to port list
- port struct are allocated separately
---
drivers/net/netdevsim/bus.c | 29 +++++++
drivers/net/netdevsim/dev.c | 130 ++++++++++++++++++++++++++----
drivers/net/netdevsim/netdev.c | 15 +---
drivers/net/netdevsim/netdevsim.h | 16 +++-
4 files changed, 160 insertions(+), 30 deletions(-)
diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index c30692f17374..1ee14e1bb12d 100644
--- a/drivers/net/netdevsim/bus.c
+++ b/drivers/net/netdevsim/bus.c
@@ -194,6 +194,21 @@ static struct attribute *nsim_bus_attrs[] = {
};
ATTRIBUTE_GROUPS(nsim_bus);
+static int nsim_bus_probe(struct device *dev)
+{
+ struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
+
+ return nsim_dev_probe(nsim_bus_dev);
+}
+
+static int nsim_bus_remove(struct device *dev)
+{
+ struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
+
+ nsim_dev_remove(nsim_bus_dev);
+ return 0;
+}
+
int nsim_num_vf(struct device *dev)
{
struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
@@ -205,6 +220,8 @@ static struct bus_type nsim_bus = {
.name = DRV_NAME,
.dev_name = DRV_NAME,
.bus_groups = nsim_bus_groups,
+ .probe = nsim_bus_probe,
+ .remove = nsim_bus_remove,
.num_vf = nsim_num_vf,
};
@@ -238,6 +255,18 @@ struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count)
return ERR_PTR(err);
}
+struct nsim_bus_dev *nsim_bus_dev_new_with_ns(struct netdevsim *ns)
+{
+ struct nsim_bus_dev *nsim_bus_dev;
+
+ dev_hold(ns->netdev);
+ rtnl_unlock();
+ nsim_bus_dev = nsim_bus_dev_new(~0, 0);
+ rtnl_lock();
+ dev_put(ns->netdev);
+ return nsim_bus_dev;
+}
+
void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
{
device_unregister(&nsim_bus_dev->dev);
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 14946d162e53..6ee9d43ae252 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -17,6 +17,7 @@
#include <linux/debugfs.h>
#include <linux/device.h>
+#include <linux/list.h>
#include <linux/random.h>
#include <linux/rtnetlink.h>
#include <net/devlink.h>
@@ -45,6 +46,30 @@ static void nsim_dev_debugfs_exit(struct nsim_dev *nsim_dev)
debugfs_remove_recursive(nsim_dev->ddir);
}
+static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev,
+ struct nsim_dev_port *nsim_dev_port)
+{
+ char port_ddir_name[16];
+ char dev_link_name[32];
+
+ sprintf(port_ddir_name, "%u", nsim_dev_port->port_index);
+ nsim_dev_port->ddir = debugfs_create_dir(port_ddir_name,
+ nsim_dev->ports_ddir);
+ if (IS_ERR_OR_NULL(nsim_dev_port->ddir))
+ return -ENOMEM;
+
+ sprintf(dev_link_name, "../../../" DRV_NAME "%u",
+ nsim_dev->nsim_bus_dev->dev.id);
+ debugfs_create_symlink("dev", nsim_dev_port->ddir, dev_link_name);
+
+ return 0;
+}
+
+static void nsim_dev_port_debugfs_exit(struct nsim_dev_port *nsim_dev_port)
+{
+ debugfs_remove_recursive(nsim_dev_port->ddir);
+}
+
static u64 nsim_dev_ipv4_fib_resource_occ_get(void *priv)
{
struct nsim_dev *nsim_dev = priv;
@@ -198,7 +223,8 @@ static const struct devlink_ops nsim_dev_devlink_ops = {
.reload = nsim_dev_reload,
};
-static struct nsim_dev *nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev)
+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;
@@ -211,6 +237,7 @@ static struct nsim_dev *nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev)
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);
nsim_dev->fib_data = nsim_fib_create();
if (IS_ERR(nsim_dev->fib_data)) {
@@ -249,20 +276,6 @@ static struct nsim_dev *nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev)
return ERR_PTR(err);
}
-struct nsim_dev *
-nsim_dev_create_with_ns(struct nsim_bus_dev *nsim_bus_dev,
- struct netdevsim *ns)
-{
- struct nsim_dev *nsim_dev;
-
- dev_hold(ns->netdev);
- rtnl_unlock();
- nsim_dev = nsim_dev_create(nsim_bus_dev);
- rtnl_lock();
- dev_put(ns->netdev);
- return nsim_dev;
-}
-
void nsim_dev_destroy(struct nsim_dev *nsim_dev)
{
struct devlink *devlink = priv_to_devlink(nsim_dev);
@@ -275,6 +288,93 @@ void nsim_dev_destroy(struct nsim_dev *nsim_dev)
devlink_free(devlink);
}
+static int nsim_dev_port_add(struct nsim_dev *nsim_dev, unsigned int port_index)
+{
+ struct nsim_dev_port *nsim_dev_port;
+ struct devlink_port *devlink_port;
+ int err;
+
+ nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL);
+ if (!nsim_dev_port)
+ return -ENOMEM;
+ nsim_dev_port->port_index = port_index;
+
+ devlink_port = &nsim_dev_port->devlink_port;
+ devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
+ port_index + 1, 0, 0,
+ nsim_dev->switch_id.id,
+ nsim_dev->switch_id.id_len);
+ err = devlink_port_register(priv_to_devlink(nsim_dev), devlink_port,
+ port_index);
+ if (err)
+ goto err_port_free;
+
+ err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port);
+ if (err)
+ goto err_dl_port_unregister;
+
+ list_add(&nsim_dev_port->list, &nsim_dev->port_list);
+
+ return 0;
+
+err_dl_port_unregister:
+ devlink_port_unregister(devlink_port);
+err_port_free:
+ kfree(nsim_dev_port);
+ return err;
+}
+
+static void nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
+{
+ struct devlink_port *devlink_port = &nsim_dev_port->devlink_port;
+
+ list_del(&nsim_dev_port->list);
+ nsim_dev_port_debugfs_exit(nsim_dev_port);
+ devlink_port_unregister(devlink_port);
+ kfree(nsim_dev_port);
+}
+
+static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
+{
+ struct nsim_dev_port *nsim_dev_port, *tmp;
+
+ list_for_each_entry_safe(nsim_dev_port, tmp,
+ &nsim_dev->port_list, list)
+ nsim_dev_port_del(nsim_dev_port);
+}
+
+int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
+{
+ 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);
+
+ for (i = 0; i < nsim_bus_dev->port_count; i++) {
+ err = nsim_dev_port_add(nsim_dev, i);
+ if (err)
+ goto err_port_del_all;
+ }
+ return 0;
+
+err_port_del_all:
+ nsim_dev_port_del_all(nsim_dev);
+ nsim_dev_destroy(nsim_dev);
+ return err;
+}
+
+void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
+{
+ struct nsim_dev *nsim_dev = dev_get_drvdata(&nsim_bus_dev->dev);
+
+ nsim_dev_port_del_all(nsim_dev);
+ nsim_dev_destroy(nsim_dev);
+}
+
int nsim_dev_init(void)
{
nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index eb823bd0dc39..99169fe521f2 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -74,7 +74,6 @@ static void nsim_free(struct net_device *dev)
{
struct netdevsim *ns = netdev_priv(dev);
- nsim_dev_destroy(ns->nsim_dev);
nsim_bus_dev_del(ns->nsim_bus_dev);
/* netdev and vf state will be freed out of device_release() */
}
@@ -364,26 +363,20 @@ static int nsim_newlink(struct net *src_net, struct net_device *dev,
struct netdevsim *ns = netdev_priv(dev);
int err;
- ns->nsim_bus_dev = nsim_bus_dev_new(~0, 0);
+ ns->netdev = dev;
+ ns->nsim_bus_dev = nsim_bus_dev_new_with_ns(ns);
if (IS_ERR(ns->nsim_bus_dev))
return PTR_ERR(ns->nsim_bus_dev);
SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
- ns->netdev = dev;
- ns->nsim_dev = nsim_dev_create_with_ns(ns->nsim_bus_dev, ns);
- if (IS_ERR(ns->nsim_dev)) {
- err = PTR_ERR(ns->nsim_dev);
- goto err_dev_del;
- }
+ ns->nsim_dev = dev_get_drvdata(&ns->nsim_bus_dev->dev);
err = register_netdevice(dev);
if (err)
- goto err_dev_destroy;
+ goto err_dev_del;
return 0;
-err_dev_destroy:
- nsim_dev_destroy(ns->nsim_dev);
err_dev_del:
nsim_bus_dev_del(ns->nsim_bus_dev);
return err;
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index e951b1ccc3f2..0e6ca85e5487 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -18,6 +18,7 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/u64_stats_sync.h>
+#include <net/devlink.h>
#include <net/xdp.h>
#define DRV_NAME "netdevsim"
@@ -130,6 +131,13 @@ enum nsim_resource_id {
NSIM_RESOURCE_IPV6_FIB_RULES,
};
+struct nsim_dev_port {
+ struct list_head list;
+ struct devlink_port devlink_port;
+ unsigned int port_index;
+ struct dentry *ddir;
+};
+
struct nsim_dev {
struct nsim_bus_dev *nsim_bus_dev;
struct nsim_fib_data *fib_data;
@@ -143,14 +151,13 @@ struct nsim_dev {
struct list_head bpf_bound_progs;
struct list_head bpf_bound_maps;
struct netdev_phys_item_id switch_id;
+ struct list_head port_list;
};
-struct nsim_dev *
-nsim_dev_create_with_ns(struct nsim_bus_dev *nsim_bus_dev,
- struct netdevsim *ns);
-void nsim_dev_destroy(struct nsim_dev *nsim_dev);
int nsim_dev_init(void);
void nsim_dev_exit(void);
+int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev);
+void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev);
struct nsim_fib_data *nsim_fib_create(void);
void nsim_fib_destroy(struct nsim_fib_data *fib_data);
@@ -201,6 +208,7 @@ struct nsim_bus_dev {
};
struct nsim_bus_dev *nsim_bus_dev_new(unsigned int id, unsigned int port_count);
+struct nsim_bus_dev *nsim_bus_dev_new_with_ns(struct netdevsim *ns);
void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
int nsim_bus_init(void);
void nsim_bus_exit(void);
--
2.17.2
next prev parent reply other threads:[~2019-04-25 14:00 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-25 13:59 [patch net-next v4 00/16] netdevsim: implement proper device model Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 01/16] netdevsim: move device registration on bus to be done earlier in init Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 02/16] netdevsim: create devlink instance per netdevsim instance Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 03/16] netdevsim: rename devlink.c to dev.c to contain per-dev(asic) items Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 04/16] netdevsim: put netdevsim bus code into separate file Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 05/16] netdevsim: move device registration and related code to bus.c Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 06/16] netdevsim: add stub netdevsim driver implementation Jiri Pirko
2019-04-25 15:38 ` Sergei Shtylyov
2019-04-25 13:59 ` [patch net-next v4 07/16] netdevsim: use ida for bus device ids Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 08/16] netdevsim: add bus attributes to add new and delete devices Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 09/16] netdevsim: rename dev_init/exit() functions and make them independent on ns Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 10/16] netdevsim: merge sdev into dev Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 11/16] netdevsim: generate random switch id instead of using dev id Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 12/16] netdevsim: change debugfs tree topology Jiri Pirko
2019-04-25 13:59 ` Jiri Pirko [this message]
2019-04-25 13:59 ` [patch net-next v4 14/16] netdevsim: extend device attrs to support port addition and deletion Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 15/16] netdevsim: move netdev creation/destruction to dev probe Jiri Pirko
2019-04-25 13:59 ` [patch net-next v4 16/16] netdevsim: implement ndo_get_devlink_port Jiri Pirko
2019-04-25 14:02 ` [patch net-next v4 00/16] netdevsim: implement proper device model Jiri Pirko
2019-04-25 22:11 ` Jakub Kicinski
2019-04-26 5:52 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190425135956.3970-14-jiri@resnulli.us \
--to=jiri@resnulli.us \
--cc=davem@davemloft.net \
--cc=dsahern@gmail.com \
--cc=jakub.kicinski@netronome.com \
--cc=mlxsw@mellanox.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox