net: Add sysfs value to determine queue traffic class
authorAlexander Duyck <alexander.h.duyck@intel.com>
Fri, 28 Oct 2016 15:43:49 +0000 (11:43 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 31 Oct 2016 19:00:47 +0000 (15:00 -0400)
Add a sysfs attribute for a Tx queue that allows us to determine the
traffic class for a given queue.  This will allow us to more easily
determine this in the future.  It is needed as XPS will take the traffic
class for a group of queues into account in order to avoid pulling traffic
from one traffic class into another.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netdevice.h
net/core/dev.c
net/core/net-sysfs.c

index e05ab3b..d91a418 100644 (file)
@@ -1920,6 +1920,7 @@ int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc)
        return 0;
 }
 
+int netdev_txq_to_tc(struct net_device *dev, unsigned int txq);
 void netdev_reset_tc(struct net_device *dev);
 int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset);
 int netdev_set_num_tc(struct net_device *dev, u8 num_tc);
index 2d54be9..db0fdbb 100644 (file)
@@ -1948,6 +1948,23 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
        }
 }
 
+int netdev_txq_to_tc(struct net_device *dev, unsigned int txq)
+{
+       if (dev->num_tc) {
+               struct netdev_tc_txq *tc = &dev->tc_to_txq[0];
+               int i;
+
+               for (i = 0; i < TC_MAX_QUEUE; i++, tc++) {
+                       if ((txq - tc->offset) < tc->count)
+                               return i;
+               }
+
+               return -1;
+       }
+
+       return 0;
+}
+
 #ifdef CONFIG_XPS
 static DEFINE_MUTEX(xps_map_mutex);
 #define xmap_dereference(P)            \
index d4fe286..38bd9b9 100644 (file)
@@ -1024,7 +1024,6 @@ static ssize_t show_trans_timeout(struct netdev_queue *queue,
        return sprintf(buf, "%lu", trans_timeout);
 }
 
-#ifdef CONFIG_XPS
 static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
 {
        struct net_device *dev = queue->dev;
@@ -1036,6 +1035,21 @@ static unsigned int get_netdev_queue_index(struct netdev_queue *queue)
        return i;
 }
 
+static ssize_t show_traffic_class(struct netdev_queue *queue,
+                                 struct netdev_queue_attribute *attribute,
+                                 char *buf)
+{
+       struct net_device *dev = queue->dev;
+       int index = get_netdev_queue_index(queue);
+       int tc = netdev_txq_to_tc(dev, index);
+
+       if (tc < 0)
+               return -EINVAL;
+
+       return sprintf(buf, "%u\n", tc);
+}
+
+#ifdef CONFIG_XPS
 static ssize_t show_tx_maxrate(struct netdev_queue *queue,
                               struct netdev_queue_attribute *attribute,
                               char *buf)
@@ -1078,6 +1092,9 @@ static struct netdev_queue_attribute queue_tx_maxrate =
 static struct netdev_queue_attribute queue_trans_timeout =
        __ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL);
 
+static struct netdev_queue_attribute queue_traffic_class =
+       __ATTR(traffic_class, S_IRUGO, show_traffic_class, NULL);
+
 #ifdef CONFIG_BQL
 /*
  * Byte queue limits sysfs structures and functions.
@@ -1263,6 +1280,7 @@ static struct netdev_queue_attribute xps_cpus_attribute =
 
 static struct attribute *netdev_queue_default_attrs[] = {
        &queue_trans_timeout.attr,
+       &queue_traffic_class.attr,
 #ifdef CONFIG_XPS
        &xps_cpus_attribute.attr,
        &queue_tx_maxrate.attr,