Skip to content

Commit 822b3b2

Browse files
John Fastabenddavem330
authored andcommitted
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: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b65885d commit 822b3b2

File tree

4 files changed

+80
-12
lines changed

4 files changed

+80
-12
lines changed

Documentation/ABI/testing/sysfs-class-net-queues

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ Description:
2424
Indicates the number of transmit timeout events seen by this
2525
network interface transmit queue.
2626

27+
What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate
28+
Date: March 2015
29+
KernelVersion: 4.1
30+
Contact: netdev@vger.kernel.org
31+
Description:
32+
A Mbps max-rate set for the queue, a value of zero means disabled,
33+
default is disabled.
34+
2735
What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus
2836
Date: November 2010
2937
KernelVersion: 2.6.38

Documentation/networking/scaling.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,15 @@ best CPUs to share a given queue are probably those that share the cache
421421
with the CPU that processes transmit completions for that queue
422422
(transmit interrupts).
423423

424+
Per TX Queue rate limitation:
425+
=============================
426+
427+
These are rate-limitation mechanisms implemented by HW, where currently
428+
a max-rate attribute is supported, by setting a Mbps value to
429+
430+
/sys/class/net/<dev>/queues/tx-<n>/tx_maxrate
431+
432+
A value of zero means disabled, and this is the default.
424433

425434
Further Information
426435
===================

include/linux/netdevice.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ struct netdev_queue {
587587
#ifdef CONFIG_BQL
588588
struct dql dql;
589589
#endif
590+
unsigned long tx_maxrate;
590591
} ____cacheline_aligned_in_smp;
591592

592593
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,
10221023
* be otherwise expressed by feature flags. The check is called with
10231024
* the set of features that the stack has calculated and it returns
10241025
* those the driver believes to be appropriate.
1026+
* int (*ndo_set_tx_maxrate)(struct net_device *dev,
1027+
* int queue_index, u32 maxrate);
1028+
* Called when a user wants to set a max-rate limitation of specific
1029+
* TX queue.
10251030
*/
10261031
struct net_device_ops {
10271032
int (*ndo_init)(struct net_device *dev);
@@ -1178,6 +1183,9 @@ struct net_device_ops {
11781183
netdev_features_t (*ndo_features_check) (struct sk_buff *skb,
11791184
struct net_device *dev,
11801185
netdev_features_t features);
1186+
int (*ndo_set_tx_maxrate)(struct net_device *dev,
1187+
int queue_index,
1188+
u32 maxrate);
11811189
};
11821190

11831191
/**

net/core/net-sysfs.c

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,60 @@ static ssize_t show_trans_timeout(struct netdev_queue *queue,
951951
return sprintf(buf, "%lu", trans_timeout);
952952
}
953953

954+
#ifdef CONFIG_XPS
955+
static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue)
956+
{
957+
struct net_device *dev = queue->dev;
958+
int i;
959+
960+
for (i = 0; i < dev->num_tx_queues; i++)
961+
if (queue == &dev->_tx[i])
962+
break;
963+
964+
BUG_ON(i >= dev->num_tx_queues);
965+
966+
return i;
967+
}
968+
969+
static ssize_t show_tx_maxrate(struct netdev_queue *queue,
970+
struct netdev_queue_attribute *attribute,
971+
char *buf)
972+
{
973+
return sprintf(buf, "%lu\n", queue->tx_maxrate);
974+
}
975+
976+
static ssize_t set_tx_maxrate(struct netdev_queue *queue,
977+
struct netdev_queue_attribute *attribute,
978+
const char *buf, size_t len)
979+
{
980+
struct net_device *dev = queue->dev;
981+
int err, index = get_netdev_queue_index(queue);
982+
u32 rate = 0;
983+
984+
err = kstrtou32(buf, 10, &rate);
985+
if (err < 0)
986+
return err;
987+
988+
if (!rtnl_trylock())
989+
return restart_syscall();
990+
991+
err = -EOPNOTSUPP;
992+
if (dev->netdev_ops->ndo_set_tx_maxrate)
993+
err = dev->netdev_ops->ndo_set_tx_maxrate(dev, index, rate);
994+
995+
rtnl_unlock();
996+
if (!err) {
997+
queue->tx_maxrate = rate;
998+
return len;
999+
}
1000+
return err;
1001+
}
1002+
1003+
static struct netdev_queue_attribute queue_tx_maxrate =
1004+
__ATTR(tx_maxrate, S_IRUGO | S_IWUSR,
1005+
show_tx_maxrate, set_tx_maxrate);
1006+
#endif
1007+
9541008
static struct netdev_queue_attribute queue_trans_timeout =
9551009
__ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL);
9561010

@@ -1065,18 +1119,6 @@ static struct attribute_group dql_group = {
10651119
#endif /* CONFIG_BQL */
10661120

10671121
#ifdef CONFIG_XPS
1068-
static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
1069-
{
1070-
struct net_device *dev = queue->dev;
1071-
unsigned int i;
1072-
1073-
i = queue - dev->_tx;
1074-
BUG_ON(i >= dev->num_tx_queues);
1075-
1076-
return i;
1077-
}
1078-
1079-
10801122
static ssize_t show_xps_map(struct netdev_queue *queue,
10811123
struct netdev_queue_attribute *attribute, char *buf)
10821124
{
@@ -1153,6 +1195,7 @@ static struct attribute *netdev_queue_default_attrs[] = {
11531195
&queue_trans_timeout.attr,
11541196
#ifdef CONFIG_XPS
11551197
&xps_cpus_attribute.attr,
1198+
&queue_tx_maxrate.attr,
11561199
#endif
11571200
NULL
11581201
};

0 commit comments

Comments
 (0)