diff options
author | Tom Herbert <therbert@google.com> | 2011-11-28 16:33:09 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-29 12:46:19 -0500 |
commit | 114cf5802165ee93e3ab461c9c505cd94a08b800 (patch) | |
tree | 88208dddd7c1e90f5e1a840ad0ad7afcea991050 /include | |
parent | 927fbec13e40648d3c87cbb1daaac5b1fb9c8775 (diff) | |
download | lwn-114cf5802165ee93e3ab461c9c505cd94a08b800.tar.gz lwn-114cf5802165ee93e3ab461c9c505cd94a08b800.zip |
bql: Byte queue limits
Networking stack support for byte queue limits, uses dynamic queue
limits library. Byte queue limits are maintained per transmit queue,
and a dql structure has been added to netdev_queue structure for this
purpose.
Configuration of bql is in the tx-<n> sysfs directory for the queue
under the byte_queue_limits directory. Configuration includes:
limit_min, bql minimum limit
limit_max, bql maximum limit
hold_time, bql slack hold time
Also under the directory are:
limit, current byte limit
inflight, current number of bytes on the queue
Signed-off-by: Tom Herbert <therbert@google.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/netdevice.h | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9b24cc7a54d1..97edb3215a5a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -43,6 +43,7 @@ #include <linux/rculist.h> #include <linux/dmaengine.h> #include <linux/workqueue.h> +#include <linux/dynamic_queue_limits.h> #include <linux/ethtool.h> #include <net/net_namespace.h> @@ -541,7 +542,6 @@ struct netdev_queue { */ struct net_device *dev; struct Qdisc *qdisc; - unsigned long state; struct Qdisc *qdisc_sleeping; #ifdef CONFIG_SYSFS struct kobject kobj; @@ -564,6 +564,12 @@ struct netdev_queue { * (/sys/class/net/DEV/Q/trans_timeout) */ unsigned long trans_timeout; + + unsigned long state; + +#ifdef CONFIG_BQL + struct dql dql; +#endif } ____cacheline_aligned_in_smp; static inline int netdev_queue_numa_node_read(const struct netdev_queue *q) @@ -1862,6 +1868,15 @@ static inline int netif_xmit_frozen_or_stopped(const struct netdev_queue *dev_qu static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, unsigned int bytes) { +#ifdef CONFIG_BQL + dql_queued(&dev_queue->dql, bytes); + if (unlikely(dql_avail(&dev_queue->dql) < 0)) { + set_bit(__QUEUE_STATE_STACK_XOFF, &dev_queue->state); + if (unlikely(dql_avail(&dev_queue->dql) >= 0)) + clear_bit(__QUEUE_STATE_STACK_XOFF, + &dev_queue->state); + } +#endif } static inline void netdev_sent_queue(struct net_device *dev, unsigned int bytes) @@ -1872,6 +1887,18 @@ static inline void netdev_sent_queue(struct net_device *dev, unsigned int bytes) static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue, unsigned pkts, unsigned bytes) { +#ifdef CONFIG_BQL + if (likely(bytes)) { + dql_completed(&dev_queue->dql, bytes); + if (unlikely(test_bit(__QUEUE_STATE_STACK_XOFF, + &dev_queue->state) && + dql_avail(&dev_queue->dql) >= 0)) { + if (test_and_clear_bit(__QUEUE_STATE_STACK_XOFF, + &dev_queue->state)) + netif_schedule_queue(dev_queue); + } + } +#endif } static inline void netdev_completed_queue(struct net_device *dev, @@ -1882,6 +1909,9 @@ static inline void netdev_completed_queue(struct net_device *dev, static inline void netdev_tx_reset_queue(struct netdev_queue *q) { +#ifdef CONFIG_BQL + dql_reset(&q->dql); +#endif } static inline void netdev_reset_queue(struct net_device *dev_queue) |