]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
i40e/i40evf: change dynamic interrupt thresholds
authorJesse Brandeburg <jesse.brandeburg@intel.com>
Mon, 28 Sep 2015 18:16:53 +0000 (14:16 -0400)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 10 Mar 2016 16:33:01 +0000 (08:33 -0800)
Orabug: 22342532

The dynamic algorithm, while now working, doesn't have good
performance in 40G mode.

One part of this patch addresses the high CPU utilization of some small
streaming workloads that the driver should reduce CPU in.

It also changes the minimum ITR that the dynamic algorithm
will settle on, causing our minimum latency to go from 12us
to about 14us, when using adaptive mode.

It also changes the BULK interrupt rate to allow maximum throughput
on a 40Gb connection with a single thread of transmit, clamping
interrupt rate to 8000 for TX makes single thread traffic go too
slow.

The new ULTRA bulk setting is introduced and is used
when the Rx packet rate on this queue exceeds 40000 packets per
second.  This value of 40000 was chosen because the automatic tuning
of minimum ITR=20us means that a single queue can't quite achieve
that many packets per second from a round-robin test.

Change-ID: Icce8faa128688ca5fd2c4229bdd9726877a92ea2
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
(cherry picked from commit c56625d59726ee2dc4dfd91c8b6c22098abe1ac4)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40e/i40e_txrx.h
drivers/net/ethernet/intel/i40evf/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.h

index b595b738000de57b4003f60a4bd4328d3062ccb1..5e7553ba7daf083799513de87dcd4cacec1fbd2c 100644 (file)
@@ -828,6 +828,7 @@ void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
 static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
 {
        enum i40e_latency_range new_latency_range = rc->latency_range;
+       struct i40e_q_vector *qv = rc->ring->q_vector;
        u32 new_itr = rc->itr;
        int bytes_per_int;
        int usecs;
@@ -836,9 +837,10 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
                return false;
 
        /* simple throttlerate management
-        *   0-10MB/s   lowest (100000 ints/s)
+        *   0-10MB/s   lowest (50000 ints/s)
         *  10-20MB/s   low    (20000 ints/s)
-        *  20-1249MB/s bulk   (8000 ints/s)
+        *  20-1249MB/s bulk   (18000 ints/s)
+        *  > 40000 Rx packets per second (8000 ints/s)
         *
         * The math works out because the divisor is in 10^(-6) which
         * turns the bytes/us input value into MB/s values, but
@@ -859,24 +861,37 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
                        new_latency_range = I40E_LOWEST_LATENCY;
                break;
        case I40E_BULK_LATENCY:
-               if (bytes_per_int <= 20)
-                       new_latency_range = I40E_LOW_LATENCY;
-               break;
+       case I40E_ULTRA_LATENCY:
        default:
                if (bytes_per_int <= 20)
                        new_latency_range = I40E_LOW_LATENCY;
                break;
        }
+
+       /* this is to adjust RX more aggressively when streaming small
+        * packets.  The value of 40000 was picked as it is just beyond
+        * what the hardware can receive per second if in low latency
+        * mode.
+        */
+#define RX_ULTRA_PACKET_RATE 40000
+
+       if ((((rc->total_packets * 1000000) / usecs) > RX_ULTRA_PACKET_RATE) &&
+           (&qv->rx == rc))
+               new_latency_range = I40E_ULTRA_LATENCY;
+
        rc->latency_range = new_latency_range;
 
        switch (new_latency_range) {
        case I40E_LOWEST_LATENCY:
-               new_itr = I40E_ITR_100K;
+               new_itr = I40E_ITR_50K;
                break;
        case I40E_LOW_LATENCY:
                new_itr = I40E_ITR_20K;
                break;
        case I40E_BULK_LATENCY:
+               new_itr = I40E_ITR_18K;
+               break;
+       case I40E_ULTRA_LATENCY:
                new_itr = I40E_ITR_8K;
                break;
        default:
index 7c0ed84b296d1f5c5a93d6c6aac28cc5de16a6f3..0fe7eb77cae5eb05eb7adeccd4ab108f99dfaf1d 100644 (file)
@@ -32,7 +32,9 @@
 #define I40E_MAX_ITR               0x0FF0  /* reg uses 2 usec resolution */
 #define I40E_MIN_ITR               0x0001  /* reg uses 2 usec resolution */
 #define I40E_ITR_100K              0x0005
+#define I40E_ITR_50K               0x000A
 #define I40E_ITR_20K               0x0019
+#define I40E_ITR_18K               0x001B
 #define I40E_ITR_8K                0x003E
 #define I40E_ITR_4K                0x007A
 #define I40E_MAX_INTRL             0x3B    /* reg uses 4 usec resolution */
@@ -296,6 +298,7 @@ enum i40e_latency_range {
        I40E_LOWEST_LATENCY = 0,
        I40E_LOW_LATENCY = 1,
        I40E_BULK_LATENCY = 2,
+       I40E_ULTRA_LATENCY = 3,
 };
 
 struct i40e_ring_container {
index 82140e2d4cb6a41facb7d1b50ba97163ac14e941..018ef68b8441c2def1848cbfc4e69ae9f5781127 100644 (file)
@@ -331,6 +331,7 @@ static void i40evf_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector
 static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
 {
        enum i40e_latency_range new_latency_range = rc->latency_range;
+       struct i40e_q_vector *qv = rc->ring->q_vector;
        u32 new_itr = rc->itr;
        int bytes_per_int;
        int usecs;
@@ -339,9 +340,10 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
                return false;
 
        /* simple throttlerate management
-        *   0-10MB/s   lowest (100000 ints/s)
+        *   0-10MB/s   lowest (50000 ints/s)
         *  10-20MB/s   low    (20000 ints/s)
-        *  20-1249MB/s bulk   (8000 ints/s)
+        *  20-1249MB/s bulk   (18000 ints/s)
+        *  > 40000 Rx packets per second (8000 ints/s)
         *
         * The math works out because the divisor is in 10^(-6) which
         * turns the bytes/us input value into MB/s values, but
@@ -362,24 +364,37 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
                        new_latency_range = I40E_LOWEST_LATENCY;
                break;
        case I40E_BULK_LATENCY:
-               if (bytes_per_int <= 20)
-                       new_latency_range = I40E_LOW_LATENCY;
-               break;
+       case I40E_ULTRA_LATENCY:
        default:
                if (bytes_per_int <= 20)
                        new_latency_range = I40E_LOW_LATENCY;
                break;
        }
+
+       /* this is to adjust RX more aggressively when streaming small
+        * packets.  The value of 40000 was picked as it is just beyond
+        * what the hardware can receive per second if in low latency
+        * mode.
+        */
+#define RX_ULTRA_PACKET_RATE 40000
+
+       if ((((rc->total_packets * 1000000) / usecs) > RX_ULTRA_PACKET_RATE) &&
+           (&qv->rx == rc))
+               new_latency_range = I40E_ULTRA_LATENCY;
+
        rc->latency_range = new_latency_range;
 
        switch (new_latency_range) {
        case I40E_LOWEST_LATENCY:
-               new_itr = I40E_ITR_100K;
+               new_itr = I40E_ITR_50K;
                break;
        case I40E_LOW_LATENCY:
                new_itr = I40E_ITR_20K;
                break;
        case I40E_BULK_LATENCY:
+               new_itr = I40E_ITR_18K;
+               break;
+       case I40E_ULTRA_LATENCY:
                new_itr = I40E_ITR_8K;
                break;
        default:
index 03275eb54cc4c6dffe823e50814f43600fad7633..e2352b886b77e9c95d1bfcb38302791dec4b4f5c 100644 (file)
@@ -32,7 +32,9 @@
 #define I40E_MAX_ITR               0x0FF0  /* reg uses 2 usec resolution */
 #define I40E_MIN_ITR               0x0001  /* reg uses 2 usec resolution */
 #define I40E_ITR_100K              0x0005
+#define I40E_ITR_50K               0x000A
 #define I40E_ITR_20K               0x0019
+#define I40E_ITR_18K               0x001B
 #define I40E_ITR_8K                0x003E
 #define I40E_ITR_4K                0x007A
 #define I40E_MAX_INTRL             0x3B    /* reg uses 4 usec resolution */
@@ -291,6 +293,7 @@ enum i40e_latency_range {
        I40E_LOWEST_LATENCY = 0,
        I40E_LOW_LATENCY = 1,
        I40E_BULK_LATENCY = 2,
+       I40E_ULTRA_LATENCY = 3,
 };
 
 struct i40e_ring_container {