Commit 822b3b2e authored by John Fastabend's avatar John Fastabend Committed by David S. Miller

net: Add max rate tx queue attribute

This adds a tx_maxrate attribute to the tx queue sysfs entry allowing
for max-rate limiting. Along with DCB-ETS and BQL this provides another
knob to tune queue performance. The limit units are Mbps.

By default it is disabled. To disable the rate limitation after it
has been set for a queue, it should be set to zero.
Signed-off-by: default avatarJohn Fastabend <john.r.fastabend@intel.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b65885d2
...@@ -24,6 +24,14 @@ Description: ...@@ -24,6 +24,14 @@ Description:
Indicates the number of transmit timeout events seen by this Indicates the number of transmit timeout events seen by this
network interface transmit queue. network interface transmit queue.
What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate
Date: March 2015
KernelVersion: 4.1
Contact: netdev@vger.kernel.org
Description:
A Mbps max-rate set for the queue, a value of zero means disabled,
default is disabled.
What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus
Date: November 2010 Date: November 2010
KernelVersion: 2.6.38 KernelVersion: 2.6.38
......
...@@ -421,6 +421,15 @@ best CPUs to share a given queue are probably those that share the cache ...@@ -421,6 +421,15 @@ best CPUs to share a given queue are probably those that share the cache
with the CPU that processes transmit completions for that queue with the CPU that processes transmit completions for that queue
(transmit interrupts). (transmit interrupts).
Per TX Queue rate limitation:
=============================
These are rate-limitation mechanisms implemented by HW, where currently
a max-rate attribute is supported, by setting a Mbps value to
/sys/class/net/<dev>/queues/tx-<n>/tx_maxrate
A value of zero means disabled, and this is the default.
Further Information Further Information
=================== ===================
......
...@@ -587,6 +587,7 @@ struct netdev_queue { ...@@ -587,6 +587,7 @@ struct netdev_queue {
#ifdef CONFIG_BQL #ifdef CONFIG_BQL
struct dql dql; struct dql dql;
#endif #endif
unsigned long tx_maxrate;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
...@@ -1022,6 +1023,10 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, ...@@ -1022,6 +1023,10 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
* be otherwise expressed by feature flags. The check is called with * be otherwise expressed by feature flags. The check is called with
* the set of features that the stack has calculated and it returns * the set of features that the stack has calculated and it returns
* those the driver believes to be appropriate. * those the driver believes to be appropriate.
* int (*ndo_set_tx_maxrate)(struct net_device *dev,
* int queue_index, u32 maxrate);
* Called when a user wants to set a max-rate limitation of specific
* TX queue.
*/ */
struct net_device_ops { struct net_device_ops {
int (*ndo_init)(struct net_device *dev); int (*ndo_init)(struct net_device *dev);
...@@ -1178,6 +1183,9 @@ struct net_device_ops { ...@@ -1178,6 +1183,9 @@ struct net_device_ops {
netdev_features_t (*ndo_features_check) (struct sk_buff *skb, netdev_features_t (*ndo_features_check) (struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
netdev_features_t features); netdev_features_t features);
int (*ndo_set_tx_maxrate)(struct net_device *dev,
int queue_index,
u32 maxrate);
}; };
/** /**
......
...@@ -951,6 +951,60 @@ static ssize_t show_trans_timeout(struct netdev_queue *queue, ...@@ -951,6 +951,60 @@ static ssize_t show_trans_timeout(struct netdev_queue *queue,
return sprintf(buf, "%lu", trans_timeout); return sprintf(buf, "%lu", trans_timeout);
} }
#ifdef CONFIG_XPS
static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue)
{
struct net_device *dev = queue->dev;
int i;
for (i = 0; i < dev->num_tx_queues; i++)
if (queue == &dev->_tx[i])
break;
BUG_ON(i >= dev->num_tx_queues);
return i;
}
static ssize_t show_tx_maxrate(struct netdev_queue *queue,
struct netdev_queue_attribute *attribute,
char *buf)
{
return sprintf(buf, "%lu\n", queue->tx_maxrate);
}
static ssize_t set_tx_maxrate(struct netdev_queue *queue,
struct netdev_queue_attribute *attribute,
const char *buf, size_t len)
{
struct net_device *dev = queue->dev;
int err, index = get_netdev_queue_index(queue);
u32 rate = 0;
err = kstrtou32(buf, 10, &rate);
if (err < 0)
return err;
if (!rtnl_trylock())
return restart_syscall();
err = -EOPNOTSUPP;
if (dev->netdev_ops->ndo_set_tx_maxrate)
err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate);
rtnl_unlock();
if (!err) {
queue->tx_maxrate = rate;
return len;
}
return err;
}
static struct netdev_queue_attribute queue_tx_maxrate =
__ATTR(tx_maxrate, S_IRUGO | S_IWUSR,
show_tx_maxrate, set_tx_maxrate);
#endif
static struct netdev_queue_attribute queue_trans_timeout = static struct netdev_queue_attribute queue_trans_timeout =
__ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL); __ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL);
...@@ -1065,18 +1119,6 @@ static struct attribute_group dql_group = { ...@@ -1065,18 +1119,6 @@ static struct attribute_group dql_group = {
#endif /* CONFIG_BQL */ #endif /* CONFIG_BQL */
#ifdef CONFIG_XPS #ifdef CONFIG_XPS
static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
{
struct net_device *dev = queue->dev;
unsigned int i;
i = queue - dev->_tx;
BUG_ON(i >= dev->num_tx_queues);
return i;
}
static ssize_t show_xps_map(struct netdev_queue *queue, static ssize_t show_xps_map(struct netdev_queue *queue,
struct netdev_queue_attribute *attribute, char *buf) struct netdev_queue_attribute *attribute, char *buf)
{ {
...@@ -1153,6 +1195,7 @@ static struct attribute *netdev_queue_default_attrs[] = { ...@@ -1153,6 +1195,7 @@ static struct attribute *netdev_queue_default_attrs[] = {
&queue_trans_timeout.attr, &queue_trans_timeout.attr,
#ifdef CONFIG_XPS #ifdef CONFIG_XPS
&xps_cpus_attribute.attr, &xps_cpus_attribute.attr,
&queue_tx_maxrate.attr,
#endif #endif
NULL NULL
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment