diff mbox

[RFC,2/4] bql: Add tracking of inflight packets

Message ID 1472601634-531498-3-git-send-email-tom@herbertland.com
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Tom Herbert Aug. 31, 2016, midnight UTC
Add two fields to netdev_queue as head_cnt and tail_cnt. head_cnt is
incremented for every sent packet in netdev_tx_sent_queue and tail_cnt
is incremented by the number of packets in netdev_tx_completed_queue.
So then the number of inflight packets for a queue is simply
queue->head_cnt - queue->tail_cnt.

Add inflight_pkts to be reported in sys-fs.

Signed-off-by: Tom Herbert <tom@herbertland.com>
---
 include/linux/netdevice.h |  4 ++++
 net/core/net-sysfs.c      | 11 +++++++++++
 2 files changed, 15 insertions(+)

Comments

Jesper Dangaard Brouer Aug. 31, 2016, 9:23 a.m. UTC | #1
On Tue, 30 Aug 2016 17:00:32 -0700
Tom Herbert <tom@herbertland.com> wrote:

> Add two fields to netdev_queue as head_cnt and tail_cnt. head_cnt is
> incremented for every sent packet in netdev_tx_sent_queue and tail_cnt
> is incremented by the number of packets in netdev_tx_completed_queue.
> So then the number of inflight packets for a queue is simply
> queue->head_cnt - queue->tail_cnt.
> 
> Add inflight_pkts to be reported in sys-fs.

I like the idea of BQL tracking inflight packets, because we could use this
to determine _when_ qdisc bulking could be beneficial (activating xmit_more).

Idea from NetDev1.1 slides[1] page 17, and experiment with BQL
byte_queue_limits/limit_max on page 18 (which would really need a pkt
count not a byte count)

[1] http://people.netfilter.org/hawk/presentations/NetDev1.1_2016/net_performance_BoF.pdf
[2] http://people.netfilter.org/hawk/presentations/NetDev1.1_2016/links.html
Eric Dumazet Aug. 31, 2016, 1:08 p.m. UTC | #2
On Tue, 2016-08-30 at 17:00 -0700, Tom Herbert wrote:
> Add two fields to netdev_queue as head_cnt and tail_cnt. head_cnt is
> incremented for every sent packet in netdev_tx_sent_queue and tail_cnt
> is incremented by the number of packets in netdev_tx_completed_queue.
> So then the number of inflight packets for a queue is simply
> queue->head_cnt - queue->tail_cnt.
> 
> Add inflight_pkts to be reported in sys-fs.
> 
> Signed-off-by: Tom Herbert <tom@herbertland.com>
> ---
>  include/linux/netdevice.h |  4 ++++
>  net/core/net-sysfs.c      | 11 +++++++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index d122be9..487d1df 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -592,6 +592,8 @@ struct netdev_queue {
>  
>  #ifdef CONFIG_BQL
>  	struct dql		dql;
> +	unsigned int		head_cnt;
> +	unsigned int		tail_cnt;
>  #endif
>  } ____cacheline_aligned_in_smp;
>  

You probably should put these fields in the appropriate cache lines of
"struct dql" : It will provide better cache behavior and fill holes.
diff mbox

Patch

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d122be9..487d1df 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -592,6 +592,8 @@  struct netdev_queue {
 
 #ifdef CONFIG_BQL
 	struct dql		dql;
+	unsigned int		head_cnt;
+	unsigned int		tail_cnt;
 #endif
 } ____cacheline_aligned_in_smp;
 
@@ -2958,6 +2960,7 @@  static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue,
 					unsigned int bytes)
 {
 #ifdef CONFIG_BQL
+	dev_queue->head_cnt++;
 	dql_queued(&dev_queue->dql, bytes);
 
 	if (likely(dql_avail(&dev_queue->dql) >= 0))
@@ -2999,6 +3002,7 @@  static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue,
 	if (unlikely(!bytes))
 		return;
 
+	dev_queue->tail_cnt += pkts;
 	dql_completed(&dev_queue->dql, bytes);
 
 	/*
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 6e4f347..5a33f6a 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1147,6 +1147,16 @@  static ssize_t bql_show_inflight(struct netdev_queue *queue,
 static struct netdev_queue_attribute bql_inflight_attribute =
 	__ATTR(inflight, S_IRUGO, bql_show_inflight, NULL);
 
+static ssize_t bql_show_inflight_pkts(struct netdev_queue *queue,
+				      struct netdev_queue_attribute *attr,
+				      char *buf)
+{
+	return sprintf(buf, "%u\n", queue->head_cnt - queue->tail_cnt);
+}
+
+static struct netdev_queue_attribute bql_inflight_pkts_attribute =
+	__ATTR(inflight_pkts, S_IRUGO, bql_show_inflight_pkts, NULL);
+
 #define BQL_ATTR(NAME, FIELD)						\
 static ssize_t bql_show_ ## NAME(struct netdev_queue *queue,		\
 				 struct netdev_queue_attribute *attr,	\
@@ -1176,6 +1186,7 @@  static struct attribute *dql_attrs[] = {
 	&bql_limit_min_attribute.attr,
 	&bql_hold_time_attribute.attr,
 	&bql_inflight_attribute.attr,
+	&bql_inflight_pkts_attribute.attr,
 	NULL
 };