All of lore.kernel.org
 help / color / mirror / Atom feed
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 v2 13/16] netdevsim: implement dev probe/remove skeleton with port initialization
Date: Sat, 20 Apr 2019 12:29:19 +0200	[thread overview]
Message-ID: <20190420102922.6001-14-jiri@resnulli.us> (raw)
In-Reply-To: <20190420102922.6001-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>
---
v1->v2:
- changed port array to port list
- port struct are allocated separately
---
 drivers/net/netdevsim/bus.c       |  29 +++++++
 drivers/net/netdevsim/dev.c       | 129 ++++++++++++++++++++++++++----
 drivers/net/netdevsim/netdev.c    |  15 +---
 drivers/net/netdevsim/netdevsim.h |  15 +++-
 4 files changed, 160 insertions(+), 28 deletions(-)

diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index 4471f5db50ee..46108a926890 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 ef518d59afba..d2c030efba4a 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,19 +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);
@@ -274,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 ec678371865f..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,13 +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);
@@ -200,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


  parent reply	other threads:[~2019-04-20 10:29 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-20 10:29 [patch net-next v2 00/16] netdevsim: impement proper device model Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 01/16] netdevsim: move device registration on bus to be done earlier in init Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 02/16] netdevsim: create devlink instance per netdevsim instance Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 03/16] netdevsim: rename devlink.c to dev.c to contain per-dev(asic) items Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 04/16] netdevsim: put netdevsim bus code into separate file Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 05/16] netdevsim: move device registration and related code to bus.c Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 06/16] netdevsim: add stub netdevsim driver implementation Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 07/16] netdevsim: use ida for bus device ids Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 08/16] netdevsim: add bus attributes to add new and delete devices Jiri Pirko
2019-04-22 19:23   ` Jakub Kicinski
2019-04-23  6:29     ` Jiri Pirko
2019-04-23 17:06       ` Jakub Kicinski
2019-04-23 19:09         ` Jiri Pirko
2019-04-22 19:23   ` Jakub Kicinski
2019-04-23  6:31     ` Jiri Pirko
2019-04-23 17:08       ` Jakub Kicinski
2019-04-20 10:29 ` [patch net-next v2 09/16] netdevsim: rename dev_init/exit() functions and make them independent on ns Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 10/16] netdevsim: merge sdev into dev Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 11/16] netdevsim: generate random switch id instead of using dev id Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 12/16] netdevsim: change debugfs tree topology Jiri Pirko
2019-04-20 10:29 ` Jiri Pirko [this message]
2019-04-20 10:29 ` [patch net-next v2 14/16] netdevsim: extend device attrs to support port addition and deletion Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 15/16] netdevsim: move netdev creation/destruction to dev probe Jiri Pirko
2019-04-22 19:31   ` Jakub Kicinski
2019-04-23  7:20     ` Jiri Pirko
2019-04-23 17:05       ` Jakub Kicinski
2019-04-23 19:14         ` Jiri Pirko
2019-04-20 10:29 ` [patch net-next v2 16/16] netdevsim: implement ndo_get_devlink_port Jiri Pirko

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=20190420102922.6001-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.