Print this page
NEX-20178 Heavy read load using 10G i40e causes network disconnect
MFV illumos-joyent@83a8d0d616db36010b59cc850d1926c0f6a30de1
OS-7457 i40e Tx freezes on zero descriptors
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
MFV illumos-joyent@0d3f2b61dcfb18edace4fd257054f6fdbe07c99c
OS-7492 i40e Tx freeze when b_cont chain exceeds 8 descriptors
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
MFV illumos-joyent@b4bede175d4c50ac1b36078a677b69388f6fb59f
OS-7577 initialize FC for i40e
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Rob Johnston <rob.johnston@joyent.com>
MFV illumos-joyent@83a8d0d616db36010b59cc850d1926c0f6a30de1
OS-7457 i40e Tx freezes on zero descriptors
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
MFV: illumos-joyent@61dc3dec4f82a3e13e94609a0a83d5f66c64e760
OS-6846 want i40e multi-group support
OS-7372 i40e_alloc_ring_mem() unwinds when it shouldn't
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Author: Ryan Zezeski <rpz@joyent.com>
MFV: illumos-joyent@757454db6669c1186f60bc625510c1b67217aae6
OS-7082 i40e: blown assert in i40e_tx_cleanup_ring()
OS-7086 i40e: add mdb dcmd to dump info on tx descriptor rings
OS-7101 i40e: add kstat to track TX DMA bind failures
Reviewed by: Ryan Zezeski <rpz@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
Author: Rob Johnston <rob.johnston@joyent.com>
MFV: illumos-joyent@9e30beee2f0c127bf41868db46257124206e28d6
OS-5225 Want Fortville TSO support
Reviewed by: Ryan Zezeski <rpz@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
Author: Rob Johnston <rob.johnston@joyent.com>
        
@@ -9,11 +9,11 @@
  * http://www.illumos.org/license/CDDL.
  */
 
 /*
  * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
  */
 
 #include "i40e_sw.h"
 
 /*
@@ -67,16 +67,11 @@
  * ---------------------
  * Hardware Arrangements
  * ---------------------
  *
  * The hardware keeps statistics at each physical function/MAC (PF) and it keeps
- * statistics on each virtual station interface (VSI). Currently we only use one
- * VSI per PF (see the i40e_main.c theory statement). The hardware has a limited
- * number of statistics units available. While every PF is guaranteed to have a
- * statistics unit, it is possible that we will run out for a given VSI. We'll
- * have to figure out an appropriate strategy here when we end up supporting
- * multiple VSIs.
+ * statistics on each virtual station interface (VSI).
  *
  * The hardware keeps these statistics as 32-bit and 48-bit counters. We are
  * required to read them and then compute the differences between them. The
  * 48-bit counters span more than one 32-bit register in the BAR. The hardware
  * suggests that to read them, we perform 64-bit reads of the lower of the two
@@ -98,14 +93,14 @@
  * isn't the most reassuring statement and we should investigate ways of
  * ensuring that if a system is active, but not actively measured, we don't lose
  * data.
  *
  * The pf kstats data is stored in the i40e_t`i40e_pf_kstat. It is backed by the
- * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstat is in
- * i40e_t`i40e_vsi_kstat and the data is backed in the i40e_t`i40e_vsi_stat. All
- * of this data is protected by the i40e_stat_lock, which should be taken last,
- * when acquiring locks.
+ * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstats are in
+ * i40e_t`i40e_vsis[idx].iv_kstats and the data is backed in the
+ * i40e_t`i40e_vsis[idx].iv_stats. All of this data is protected by the
+ * i40e_stat_lock, which should be taken last, when acquiring locks.
  */
 
 static void
 i40e_stat_get_uint48(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
     uint64_t *base, boolean_t init)
@@ -167,19 +162,19 @@
         *base = raw;
 
 }
 
 static void
-i40e_stat_vsi_update(i40e_t *i40e, boolean_t init)
+i40e_stat_vsi_update(i40e_t *i40e, uint_t idx, boolean_t init)
 {
         i40e_vsi_stats_t *ivs;
         i40e_vsi_kstats_t *ivk;
-        int id = i40e->i40e_vsi_stat_id;
+        uint16_t id = i40e->i40e_vsis[idx].iv_stats_id;
 
-        ASSERT(i40e->i40e_vsi_kstat != NULL);
-        ivs = &i40e->i40e_vsi_stat;
-        ivk = i40e->i40e_vsi_kstat->ks_data;
+        ASSERT3P(i40e->i40e_vsis[idx].iv_kstats, !=, NULL);
+        ivs = &i40e->i40e_vsis[idx].iv_stats;
+        ivk = i40e->i40e_vsis[idx].iv_kstats->ks_data;
 
         mutex_enter(&i40e->i40e_stat_lock);
 
         i40e_stat_get_uint48(i40e, I40E_GLV_GORCL(id), &ivk->ivk_rx_bytes,
             &ivs->ivs_rx_bytes, init);
@@ -229,43 +224,45 @@
 
         if (rw == KSTAT_WRITE)
                 return (EACCES);
 
         i40e = ksp->ks_private;
-        i40e_stat_vsi_update(i40e, B_FALSE);
+        for (uint_t i = 0; i < i40e->i40e_num_rx_groups; i++)
+                i40e_stat_vsi_update(i40e, i, B_FALSE);
+
         return (0);
 }
 
 void
-i40e_stat_vsi_fini(i40e_t *i40e)
+i40e_stat_vsi_fini(i40e_t *i40e, uint_t idx)
 {
-        if (i40e->i40e_vsi_kstat != NULL) {
-                kstat_delete(i40e->i40e_vsi_kstat);
-                i40e->i40e_vsi_kstat = NULL;
+        if (i40e->i40e_vsis[idx].iv_kstats != NULL) {
+                kstat_delete(i40e->i40e_vsis[idx].iv_kstats);
+                i40e->i40e_vsis[idx].iv_kstats = NULL;
         }
 }
 
 boolean_t
-i40e_stat_vsi_init(i40e_t *i40e)
+i40e_stat_vsi_init(i40e_t *i40e, uint_t idx)
 {
         kstat_t *ksp;
         i40e_vsi_kstats_t *ivk;
         char buf[64];
+        uint16_t vsi_id = i40e->i40e_vsis[idx].iv_seid;
 
-        (void) snprintf(buf, sizeof (buf), "vsi_%d", i40e->i40e_vsi_id);
+        (void) snprintf(buf, sizeof (buf), "vsi_%u", vsi_id);
 
         ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
             buf, "net", KSTAT_TYPE_NAMED,
             sizeof (i40e_vsi_kstats_t) / sizeof (kstat_named_t), 0);
 
         if (ksp == NULL) {
-                i40e_error(i40e, "Failed to create kstats for VSI %d",
-                    i40e->i40e_vsi_id);
+                i40e_error(i40e, "Failed to create kstats for VSI %u", vsi_id);
                 return (B_FALSE);
         }
 
-        i40e->i40e_vsi_kstat = ksp;
+        i40e->i40e_vsis[idx].iv_kstats = ksp;
         ivk = ksp->ks_data;
         ksp->ks_update = i40e_stat_vsi_kstat_update;
         ksp->ks_private = i40e;
 
         kstat_named_init(&ivk->ivk_rx_bytes, "rx_bytes",
@@ -289,13 +286,13 @@
         kstat_named_init(&ivk->ivk_tx_broadcast, "tx_broadcast",
             KSTAT_DATA_UINT64);
         kstat_named_init(&ivk->ivk_tx_errors, "tx_errors",
             KSTAT_DATA_UINT64);
 
-        bzero(&i40e->i40e_vsi_stat, sizeof (i40e_vsi_stats_t));
-        i40e_stat_vsi_update(i40e, B_TRUE);
-        kstat_install(i40e->i40e_vsi_kstat);
+        bzero(&i40e->i40e_vsis[idx].iv_stats, sizeof (i40e_vsi_stats_t));
+        i40e_stat_vsi_update(i40e, idx, B_TRUE);
+        kstat_install(i40e->i40e_vsis[idx].iv_kstats);
 
         return (B_TRUE);
 }
 
 static void
@@ -668,11 +665,16 @@
 }
 
 void
 i40e_stats_fini(i40e_t *i40e)
 {
-        ASSERT(i40e->i40e_vsi_kstat == NULL);
+#ifdef DEBUG
+        for (uint_t i = 0; i < i40e->i40e_num_rx_groups; i++) {
+                ASSERT3P(i40e->i40e_vsis[i].iv_kstats, ==, NULL);
+        }
+#endif
+
         if (i40e->i40e_pf_kstat != NULL) {
                 kstat_delete(i40e->i40e_pf_kstat);
                 i40e->i40e_pf_kstat = NULL;
         }
 
@@ -1228,10 +1230,16 @@
             KSTAT_DATA_UINT64);
         tsp->itxs_descriptors.value.ui64 = 0;
         kstat_named_init(&tsp->itxs_recycled, "tx_recycled",
             KSTAT_DATA_UINT64);
         tsp->itxs_recycled.value.ui64 = 0;
+        kstat_named_init(&tsp->itxs_force_copy, "tx_force_copy",
+            KSTAT_DATA_UINT64);
+        tsp->itxs_force_copy.value.ui64 = 0;
+        kstat_named_init(&tsp->itxs_tso_force_copy, "tx_tso_force_copy",
+            KSTAT_DATA_UINT64);
+        tsp->itxs_tso_force_copy.value.ui64 = 0;
 
         kstat_named_init(&tsp->itxs_hck_meoifail, "tx_hck_meoifail",
             KSTAT_DATA_UINT64);
         tsp->itxs_hck_meoifail.value.ui64 = 0;
         kstat_named_init(&tsp->itxs_hck_nol2info, "tx_hck_nol2info",
@@ -1247,10 +1255,16 @@
             KSTAT_DATA_UINT64);
         tsp->itxs_hck_badl3.value.ui64 = 0;
         kstat_named_init(&tsp->itxs_hck_badl4, "tx_hck_badl4",
             KSTAT_DATA_UINT64);
         tsp->itxs_hck_badl4.value.ui64 = 0;
+        kstat_named_init(&tsp->itxs_lso_nohck, "tx_lso_nohck",
+            KSTAT_DATA_UINT64);
+        tsp->itxs_lso_nohck.value.ui64 = 0;
+        kstat_named_init(&tsp->itxs_bind_fails, "tx_bind_fails",
+            KSTAT_DATA_UINT64);
+        tsp->itxs_bind_fails.value.ui64 = 0;
         kstat_named_init(&tsp->itxs_err_notcb, "tx_err_notcb",
             KSTAT_DATA_UINT64);
         tsp->itxs_err_notcb.value.ui64 = 0;
         kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
             KSTAT_DATA_UINT64);