netdevsim: Add multi-queue support
authorPeilin Ye <peilin.ye@bytedance.com>
Fri, 16 Jul 2021 01:52:45 +0000 (18:52 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 16 Jul 2021 18:17:56 +0000 (11:17 -0700)
Currently netdevsim only supports a single queue per port, which is
insufficient for testing multi-queue TC schedulers e.g. sch_mq.  Extend
the current sysfs interface so that users can create ports with multiple
queues:

$ echo "[ID] [PORT_COUNT] [NUM_QUEUES]" > /sys/bus/netdevsim/new_device

As an example, echoing "2 4 8" creates 4 ports, with 8 queues per port.
Note, this is compatible with the current interface, with default number
of queues set to 1.  For example, echoing "2 4" creates 4 ports with 1
queue per port; echoing "2" simply creates 1 port with 1 queue.

Reviewed-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/netdevsim/bus.c
drivers/net/netdevsim/netdev.c
drivers/net/netdevsim/netdevsim.h

index ccec299..ff01e5b 100644 (file)
@@ -262,29 +262,31 @@ static struct device_type nsim_bus_dev_type = {
 };
 
 static struct nsim_bus_dev *
-nsim_bus_dev_new(unsigned int id, unsigned int port_count);
+nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queues);
 
 static ssize_t
 new_device_store(struct bus_type *bus, const char *buf, size_t count)
 {
+       unsigned int id, port_count, num_queues;
        struct nsim_bus_dev *nsim_bus_dev;
-       unsigned int port_count;
-       unsigned int id;
        int err;
 
-       err = sscanf(buf, "%u %u", &id, &port_count);
+       err = sscanf(buf, "%u %u %u", &id, &port_count, &num_queues);
        switch (err) {
        case 1:
                port_count = 1;
                fallthrough;
        case 2:
+               num_queues = 1;
+               fallthrough;
+       case 3:
                if (id > INT_MAX) {
                        pr_err("Value of \"id\" is too big.\n");
                        return -EINVAL;
                }
                break;
        default:
-               pr_err("Format for adding new device is \"id port_count\" (uint uint).\n");
+               pr_err("Format for adding new device is \"id port_count num_queues\" (uint uint unit).\n");
                return -EINVAL;
        }
 
@@ -295,7 +297,7 @@ new_device_store(struct bus_type *bus, const char *buf, size_t count)
                goto err;
        }
 
-       nsim_bus_dev = nsim_bus_dev_new(id, port_count);
+       nsim_bus_dev = nsim_bus_dev_new(id, port_count, num_queues);
        if (IS_ERR(nsim_bus_dev)) {
                err = PTR_ERR(nsim_bus_dev);
                goto err;
@@ -397,7 +399,7 @@ static struct bus_type nsim_bus = {
 #define NSIM_BUS_DEV_MAX_VFS 4
 
 static struct nsim_bus_dev *
-nsim_bus_dev_new(unsigned int id, unsigned int port_count)
+nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queues)
 {
        struct nsim_bus_dev *nsim_bus_dev;
        int err;
@@ -413,6 +415,7 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count)
        nsim_bus_dev->dev.bus = &nsim_bus;
        nsim_bus_dev->dev.type = &nsim_bus_dev_type;
        nsim_bus_dev->port_count = port_count;
+       nsim_bus_dev->num_queues = num_queues;
        nsim_bus_dev->initial_net = current->nsproxy->net_ns;
        nsim_bus_dev->max_vfs = NSIM_BUS_DEV_MAX_VFS;
        mutex_init(&nsim_bus_dev->nsim_bus_reload_lock);
index c3aeb15..50572e0 100644 (file)
@@ -347,7 +347,8 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
        struct netdevsim *ns;
        int err;
 
-       dev = alloc_netdev(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup);
+       dev = alloc_netdev_mq(sizeof(*ns), "eth%d", NET_NAME_UNKNOWN, nsim_setup,
+                             nsim_dev->nsim_bus_dev->num_queues);
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
@@ -392,7 +393,8 @@ void nsim_destroy(struct netdevsim *ns)
 static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
                         struct netlink_ext_ack *extack)
 {
-       NL_SET_ERR_MSG_MOD(extack, "Please use: echo \"[ID] [PORT_COUNT]\" > /sys/bus/netdevsim/new_device");
+       NL_SET_ERR_MSG_MOD(extack,
+                          "Please use: echo \"[ID] [PORT_COUNT] [NUM_QUEUES]\" > /sys/bus/netdevsim/new_device");
        return -EOPNOTSUPP;
 }
 
index ae46295..1c20bcb 100644 (file)
@@ -352,6 +352,7 @@ struct nsim_bus_dev {
        struct device dev;
        struct list_head list;
        unsigned int port_count;
+       unsigned int num_queues; /* Number of queues for each port on this bus */
        struct net *initial_net; /* Purpose of this is to carry net pointer
                                  * during the probe time only.
                                  */