[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20140116202506.GI29522@redhat.com>
Date: Thu, 16 Jan 2014 22:25:06 +0200
From: "Michael S. Tsirkin" <mst@...hat.com>
To: Michael Dalton <mwdalton@...gle.com>
Cc: "David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org,
Eric Dumazet <edumazet@...gle.com>,
Rusty Russell <rusty@...tcorp.com.au>,
Jason Wang <jasowang@...hat.com>,
Ben Hutchings <bhutchings@...arflare.com>,
virtualization@...ts.linux-foundation.org
Subject: Re: [PATCH net-next v4 4/6] net-sysfs: add support for
device-specific rx queue sysfs attributes
On Thu, Jan 16, 2014 at 11:52:28AM -0800, Michael Dalton wrote:
> Extend existing support for netdevice receive queue sysfs attributes to
> permit a device-specific attribute group. Initial use case for this
> support will be to allow the virtio-net device to export per-receive
> queue mergeable receive buffer size.
>
> Signed-off-by: Michael Dalton <mwdalton@...gle.com>
Acked-by: Michael S. Tsirkin <mst@...hat.com>
> ---
> v3->v4: Simplify by removing loop in get_netdev_rx_queue_index.
>
> include/linux/netdevice.h | 35 +++++++++++++++++++++++++++++++----
> net/core/dev.c | 12 ++++++------
> net/core/net-sysfs.c | 33 ++++++++++++++++-----------------
> 3 files changed, 53 insertions(+), 27 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 5c88ab1..38929bc 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -668,15 +668,28 @@ extern struct rps_sock_flow_table __rcu *rps_sock_flow_table;
> bool rps_may_expire_flow(struct net_device *dev, u16 rxq_index, u32 flow_id,
> u16 filter_id);
> #endif
> +#endif /* CONFIG_RPS */
>
> /* This structure contains an instance of an RX queue. */
> struct netdev_rx_queue {
> +#ifdef CONFIG_RPS
> struct rps_map __rcu *rps_map;
> struct rps_dev_flow_table __rcu *rps_flow_table;
> +#endif
> struct kobject kobj;
> struct net_device *dev;
> } ____cacheline_aligned_in_smp;
> -#endif /* CONFIG_RPS */
> +
> +/*
> + * RX queue sysfs structures and functions.
> + */
> +struct rx_queue_attribute {
> + struct attribute attr;
> + ssize_t (*show)(struct netdev_rx_queue *queue,
> + struct rx_queue_attribute *attr, char *buf);
> + ssize_t (*store)(struct netdev_rx_queue *queue,
> + struct rx_queue_attribute *attr, const char *buf, size_t len);
> +};
>
> #ifdef CONFIG_XPS
> /*
> @@ -1313,7 +1326,7 @@ struct net_device {
> unicast) */
>
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> struct netdev_rx_queue *_rx;
>
> /* Number of RX queues allocated at register_netdev() time */
> @@ -1424,6 +1437,8 @@ struct net_device {
> struct device dev;
> /* space for optional device, statistics, and wireless sysfs groups */
> const struct attribute_group *sysfs_groups[4];
> + /* space for optional per-rx queue attributes */
> + const struct attribute_group *sysfs_rx_queue_group;
>
> /* rtnetlink link ops */
> const struct rtnl_link_ops *rtnl_link_ops;
> @@ -2374,7 +2389,7 @@ static inline bool netif_is_multiqueue(const struct net_device *dev)
>
> int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq);
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq);
> #else
> static inline int netif_set_real_num_rx_queues(struct net_device *dev,
> @@ -2393,7 +2408,7 @@ static inline int netif_copy_real_num_queues(struct net_device *to_dev,
> from_dev->real_num_tx_queues);
> if (err)
> return err;
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> return netif_set_real_num_rx_queues(to_dev,
> from_dev->real_num_rx_queues);
> #else
> @@ -2401,6 +2416,18 @@ static inline int netif_copy_real_num_queues(struct net_device *to_dev,
> #endif
> }
>
> +#ifdef CONFIG_SYSFS
> +static inline unsigned int get_netdev_rx_queue_index(
> + struct netdev_rx_queue *queue)
> +{
> + struct net_device *dev = queue->dev;
> + int index = queue - dev->_rx;
> +
> + BUG_ON(index >= dev->num_rx_queues);
> + return index;
> +}
> +#endif
> +
> #define DEFAULT_MAX_NUM_RSS_QUEUES (8)
> int netif_get_num_default_rss_queues(void);
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 20c834e..4be7931 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2080,7 +2080,7 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
> }
> EXPORT_SYMBOL(netif_set_real_num_tx_queues);
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> /**
> * netif_set_real_num_rx_queues - set actual number of RX queues used
> * @dev: Network device
> @@ -5727,7 +5727,7 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
> }
> EXPORT_SYMBOL(netif_stacked_transfer_operstate);
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> static int netif_alloc_rx_queues(struct net_device *dev)
> {
> unsigned int i, count = dev->num_rx_queues;
> @@ -6272,7 +6272,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
> return NULL;
> }
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> if (rxqs < 1) {
> pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n");
> return NULL;
> @@ -6328,7 +6328,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
> if (netif_alloc_netdev_queues(dev))
> goto free_all;
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> dev->num_rx_queues = rxqs;
> dev->real_num_rx_queues = rxqs;
> if (netif_alloc_rx_queues(dev))
> @@ -6348,7 +6348,7 @@ free_all:
> free_pcpu:
> free_percpu(dev->pcpu_refcnt);
> netif_free_tx_queues(dev);
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> kfree(dev->_rx);
> #endif
>
> @@ -6373,7 +6373,7 @@ void free_netdev(struct net_device *dev)
> release_net(dev_net(dev));
>
> netif_free_tx_queues(dev);
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> kfree(dev->_rx);
> #endif
>
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 49843bf..0193ff3 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -498,17 +498,7 @@ static struct attribute_group wireless_group = {
> #define net_class_groups NULL
> #endif /* CONFIG_SYSFS */
>
> -#ifdef CONFIG_RPS
> -/*
> - * RX queue sysfs structures and functions.
> - */
> -struct rx_queue_attribute {
> - struct attribute attr;
> - ssize_t (*show)(struct netdev_rx_queue *queue,
> - struct rx_queue_attribute *attr, char *buf);
> - ssize_t (*store)(struct netdev_rx_queue *queue,
> - struct rx_queue_attribute *attr, const char *buf, size_t len);
> -};
> +#ifdef CONFIG_SYSFS
> #define to_rx_queue_attr(_attr) container_of(_attr, \
> struct rx_queue_attribute, attr)
>
> @@ -543,6 +533,7 @@ static const struct sysfs_ops rx_queue_sysfs_ops = {
> .store = rx_queue_attr_store,
> };
>
> +#ifdef CONFIG_RPS
> static ssize_t show_rps_map(struct netdev_rx_queue *queue,
> struct rx_queue_attribute *attribute, char *buf)
> {
> @@ -718,16 +709,20 @@ static struct rx_queue_attribute rps_cpus_attribute =
> static struct rx_queue_attribute rps_dev_flow_table_cnt_attribute =
> __ATTR(rps_flow_cnt, S_IRUGO | S_IWUSR,
> show_rps_dev_flow_table_cnt, store_rps_dev_flow_table_cnt);
> +#endif /* CONFIG_RPS */
>
> static struct attribute *rx_queue_default_attrs[] = {
> +#ifdef CONFIG_RPS
> &rps_cpus_attribute.attr,
> &rps_dev_flow_table_cnt_attribute.attr,
> +#endif
> NULL
> };
>
> static void rx_queue_release(struct kobject *kobj)
> {
> struct netdev_rx_queue *queue = to_rx_queue(kobj);
> +#ifdef CONFIG_RPS
> struct rps_map *map;
> struct rps_dev_flow_table *flow_table;
>
> @@ -743,6 +738,7 @@ static void rx_queue_release(struct kobject *kobj)
> RCU_INIT_POINTER(queue->rps_flow_table, NULL);
> call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
> }
> +#endif
>
> memset(kobj, 0, sizeof(*kobj));
> dev_put(queue->dev);
> @@ -767,21 +763,27 @@ static int rx_queue_add_kobject(struct net_device *net, int index)
> kobject_put(kobj);
> return error;
> }
> + if (net->sysfs_rx_queue_group)
> + sysfs_create_group(kobj, net->sysfs_rx_queue_group);
>
> kobject_uevent(kobj, KOBJ_ADD);
> dev_hold(queue->dev);
>
> return error;
> }
> -#endif /* CONFIG_RPS */
> +#endif /* CONFIG_SYFS */
>
> int
> net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
> {
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> int i;
> int error = 0;
>
> +#ifndef CONFIG_RPS
> + if (!net->sysfs_rx_queue_group)
> + return 0;
> +#endif
> for (i = old_num; i < new_num; i++) {
> error = rx_queue_add_kobject(net, i);
> if (error) {
> @@ -1155,9 +1157,6 @@ static int register_queue_kobjects(struct net_device *net)
> NULL, &net->dev.kobj);
> if (!net->queues_kset)
> return -ENOMEM;
> -#endif
> -
> -#ifdef CONFIG_RPS
> real_rx = net->real_num_rx_queues;
> #endif
> real_tx = net->real_num_tx_queues;
> @@ -1184,7 +1183,7 @@ static void remove_queue_kobjects(struct net_device *net)
> {
> int real_rx = 0, real_tx = 0;
>
> -#ifdef CONFIG_RPS
> +#ifdef CONFIG_SYSFS
> real_rx = net->real_num_rx_queues;
> #endif
> real_tx = net->real_num_tx_queues;
> --
> 1.8.5.2
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists