mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
netdevsim: Add multi-queue support
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>
This commit is contained in:
parent
b83d23a2a3
commit
d4861fc6be
@ -262,29 +262,31 @@ static struct device_type nsim_bus_dev_type = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct nsim_bus_dev *
|
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
|
static ssize_t
|
||||||
new_device_store(struct bus_type *bus, const char *buf, size_t count)
|
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;
|
struct nsim_bus_dev *nsim_bus_dev;
|
||||||
unsigned int port_count;
|
|
||||||
unsigned int id;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = sscanf(buf, "%u %u", &id, &port_count);
|
err = sscanf(buf, "%u %u %u", &id, &port_count, &num_queues);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case 1:
|
case 1:
|
||||||
port_count = 1;
|
port_count = 1;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case 2:
|
case 2:
|
||||||
|
num_queues = 1;
|
||||||
|
fallthrough;
|
||||||
|
case 3:
|
||||||
if (id > INT_MAX) {
|
if (id > INT_MAX) {
|
||||||
pr_err("Value of \"id\" is too big.\n");
|
pr_err("Value of \"id\" is too big.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +297,7 @@ new_device_store(struct bus_type *bus, const char *buf, size_t count)
|
|||||||
goto err;
|
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)) {
|
if (IS_ERR(nsim_bus_dev)) {
|
||||||
err = PTR_ERR(nsim_bus_dev);
|
err = PTR_ERR(nsim_bus_dev);
|
||||||
goto err;
|
goto err;
|
||||||
@ -397,7 +399,7 @@ static struct bus_type nsim_bus = {
|
|||||||
#define NSIM_BUS_DEV_MAX_VFS 4
|
#define NSIM_BUS_DEV_MAX_VFS 4
|
||||||
|
|
||||||
static struct nsim_bus_dev *
|
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;
|
struct nsim_bus_dev *nsim_bus_dev;
|
||||||
int err;
|
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.bus = &nsim_bus;
|
||||||
nsim_bus_dev->dev.type = &nsim_bus_dev_type;
|
nsim_bus_dev->dev.type = &nsim_bus_dev_type;
|
||||||
nsim_bus_dev->port_count = port_count;
|
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->initial_net = current->nsproxy->net_ns;
|
||||||
nsim_bus_dev->max_vfs = NSIM_BUS_DEV_MAX_VFS;
|
nsim_bus_dev->max_vfs = NSIM_BUS_DEV_MAX_VFS;
|
||||||
mutex_init(&nsim_bus_dev->nsim_bus_reload_lock);
|
mutex_init(&nsim_bus_dev->nsim_bus_reload_lock);
|
||||||
|
@ -347,7 +347,8 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
|
|||||||
struct netdevsim *ns;
|
struct netdevsim *ns;
|
||||||
int err;
|
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)
|
if (!dev)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
@ -392,7 +393,8 @@ void nsim_destroy(struct netdevsim *ns)
|
|||||||
static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
|
static int nsim_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||||
struct netlink_ext_ack *extack)
|
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;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,6 +352,7 @@ struct nsim_bus_dev {
|
|||||||
struct device dev;
|
struct device dev;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
unsigned int port_count;
|
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
|
struct net *initial_net; /* Purpose of this is to carry net pointer
|
||||||
* during the probe time only.
|
* during the probe time only.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user