Print this page
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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mdb/intel/modules/i40e/i40e.c
          +++ new/usr/src/cmd/mdb/intel/modules/i40e/i40e.c
↓ open down ↓ 2 lines elided ↑ open up ↑
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13      - * Copyright 2016 Joyent, Inc.
       13 + * Copyright 2018 Joyent, Inc.
  14   14   */
  15   15  
       16 +#include <mdb/mdb_ctf.h>
  16   17  #include <sys/mdb_modapi.h>
  17   18  #include "i40e_sw.h"
  18   19  
  19   20  #define RSRC_MAX        0x13
  20   21  static const char *i40e_switch_rsrc_names[] = {
  21   22          "VEBs",
  22   23          "VSIs",
  23   24          "Perfect Match MAC Addresses",
  24   25          "S-Tags",
  25   26          "Reserved",
↓ open down ↓ 64 lines elided ↑ open up ↑
  90   91                  }
  91   92  
  92   93                  mdb_printf("%-28s %-12d %-8d %-8d %d\n", name,
  93   94                      LE_16(rsrc.guaranteed), LE_16(rsrc.total), LE_16(rsrc.used),
  94   95                      LE_16(rsrc.total_unalloced));
  95   96          }
  96   97  
  97   98          return (DCMD_OK);
  98   99  }
  99  100  
      101 +typedef struct mdb_i40e_trqpair {
      102 +        uint32_t                itrq_tx_ring_size;
      103 +        uint32_t                itrq_desc_free;
      104 +        uint32_t                *itrq_desc_wbhead;
      105 +        uint32_t                itrq_desc_head;
      106 +        uint32_t                itrq_desc_tail;
      107 +        i40e_tx_desc_t          *itrq_desc_ring;
      108 +        i40e_tx_control_block_t **itrq_tcb_work_list;
      109 +} mdb_i40e_trqpair_t;
      110 +
      111 +static void
      112 +i40e_tx_ring_help()
      113 +{
      114 +        mdb_printf(
      115 +            "\t -a dump all ring entries\n"
      116 +            "\t or\n"
      117 +            "\t combine -b [start index] with -e [end index] to specify a \n"
      118 +            "\t range of ring entries to print\n");
      119 +}
      120 +
      121 +static int
      122 +i40e_tx_ring_dcmd(uintptr_t addr, uint_t flags, int argc,
      123 +    const mdb_arg_t *argv)
      124 +{
      125 +        mdb_i40e_trqpair_t trq;
      126 +        i40e_tx_desc_t *descring;
      127 +        i40e_tx_control_block_t **wklist;
      128 +        uint32_t wbhead;
      129 +        size_t ringsz, wklistsz;
      130 +        boolean_t opt_a = B_FALSE;
      131 +        char *opt_b = NULL, *opt_e = NULL;
      132 +        uint64_t begin = UINT64_MAX, end = UINT64_MAX;
      133 +
      134 +        if (!(flags & DCMD_ADDRSPEC)) {
      135 +                mdb_warn("::i40e_tx_ring does not operate globally\n");
      136 +                return (DCMD_USAGE);
      137 +        }
      138 +
      139 +        if (mdb_getopts(argc, argv,
      140 +            'a', MDB_OPT_SETBITS, B_TRUE, &opt_a,
      141 +            'b', MDB_OPT_STR, &opt_b,
      142 +            'e', MDB_OPT_STR, &opt_e, NULL) != argc)
      143 +                return (DCMD_USAGE);
      144 +
      145 +        /*
      146 +         * Verify that a legal combination of -a/-b/-e were used.
      147 +         */
      148 +        if (opt_a && (opt_b != NULL || opt_e != NULL)) {
      149 +                mdb_warn("-a and -b/-e are mutually exclusive\n");
      150 +                return (DCMD_USAGE);
      151 +        }
      152 +        if (argc > 0 && ! opt_a && (opt_b == NULL || opt_e == NULL)) {
      153 +                mdb_warn("-b/-e must both be specified\n");
      154 +                return (DCMD_USAGE);
      155 +        }
      156 +
      157 +        if (mdb_ctf_vread(&trq, "i40e_trqpair_t", "mdb_i40e_trqpair_t", addr,
      158 +            0) == -1) {
      159 +                mdb_warn("failed to read i40e_trqpair_t at %p", addr);
      160 +                return (DCMD_ERR);
      161 +        }
      162 +
      163 +        if (opt_b != NULL)
      164 +                begin = mdb_strtoull(opt_b);
      165 +        if (opt_e != NULL)
      166 +                end = mdb_strtoull(opt_e);
      167 +        if (opt_a) {
      168 +                begin = 0;
      169 +                end = trq.itrq_tx_ring_size - 1;
      170 +        }
      171 +
      172 +        /*
      173 +         * Verify that the requested range of ring entries makes sense.
      174 +         */
      175 +        if (argc > 0 && (end < begin || begin >= trq.itrq_tx_ring_size ||
      176 +            end >= trq.itrq_tx_ring_size)) {
      177 +                mdb_warn("invalid range specified\n");
      178 +                return (DCMD_USAGE);
      179 +        }
      180 +
      181 +        if (mdb_vread(&wbhead, sizeof (uint32_t),
      182 +            (uintptr_t)trq.itrq_desc_wbhead) != sizeof (uint32_t)) {
      183 +                mdb_warn("failed to read trq.itrq_desc_wbhead");
      184 +                return (DCMD_ERR);
      185 +        }
      186 +        mdb_printf("%-20s%d\n", "Ring Size:", trq.itrq_tx_ring_size);
      187 +        mdb_printf("%-20s%d\n", "Free Descriptors:", trq.itrq_desc_free);
      188 +        mdb_printf("%-20s%d\n", "Writeback Head:", wbhead);
      189 +        mdb_printf("%-20s%d\n", "Head:", trq.itrq_desc_head);
      190 +        mdb_printf("%-20s%d\n", "Tail:", trq.itrq_desc_tail);
      191 +
      192 +        /*
      193 +         * No arguments were specified, so we're done.
      194 +         */
      195 +        if (argc == 0)
      196 +                return (DCMD_OK);
      197 +
      198 +        /*
      199 +         * Allocate memory and read in the entire TX descriptor ring and
      200 +         * TCB work list.
      201 +         */
      202 +        ringsz = sizeof (i40e_tx_desc_t) * trq.itrq_tx_ring_size;
      203 +        descring = mdb_alloc(ringsz, UM_SLEEP);
      204 +        if (mdb_vread(descring, ringsz, (uintptr_t)trq.itrq_desc_ring) !=
      205 +            ringsz) {
      206 +                mdb_warn("Failed to read in TX decriptor ring\n");
      207 +                mdb_free(descring, ringsz);
      208 +                return (DCMD_ERR);
      209 +        }
      210 +        wklistsz = sizeof (i40e_tx_control_block_t *) * trq.itrq_tx_ring_size;
      211 +        wklist = mdb_alloc(wklistsz, UM_SLEEP);
      212 +        if (mdb_vread(wklist, wklistsz, (uintptr_t)trq.itrq_tcb_work_list) !=
      213 +            wklistsz) {
      214 +                mdb_warn("Failed to read in TX TCB work list\n");
      215 +                mdb_free(descring, ringsz);
      216 +                mdb_free(wklist, wklistsz);
      217 +                return (DCMD_ERR);
      218 +        }
      219 +
      220 +        mdb_printf("\n%-10s %-10s %-16s %-16s %-10s\n", "Index", "Desc Type",
      221 +            "Desc Ptr", "TCB Ptr", "Other");
      222 +        for (uint64_t i = begin; i <= end; i++) {
      223 +                const char *dtype;
      224 +                char dother[17];
      225 +                i40e_tx_desc_t *dptr;
      226 +                i40e_tx_control_block_t *tcbptr;
      227 +                uint64_t ctob;
      228 +
      229 +                dptr = &descring[i];
      230 +                tcbptr = wklist[i];
      231 +                ctob = LE_64(dptr->cmd_type_offset_bsz);
      232 +                if (ctob == 0) {
      233 +                        dtype = "FREE";
      234 +                } else {
      235 +                        switch (ctob & I40E_TXD_QW1_DTYPE_MASK) {
      236 +                        case (I40E_TX_DESC_DTYPE_CONTEXT):
      237 +                                dtype = "CONTEXT";
      238 +                                break;
      239 +                        case (I40E_TX_DESC_DTYPE_DATA):
      240 +                                dtype = "DATA";
      241 +                                break;
      242 +                        case (I40E_TX_DESC_DTYPE_FILTER_PROG):
      243 +                                dtype = "FILTER";
      244 +                                break;
      245 +                        default:
      246 +                                dtype = "UNKNOWN";
      247 +                        }
      248 +                }
      249 +                dother[0] = '\0';
      250 +                if (i == wbhead)
      251 +                        (void) strcat(dother, "WBHEAD");
      252 +
      253 +                if (i == trq.itrq_desc_head)
      254 +                        (void) strcat(dother,
      255 +                            strlen(dother) > 0 ? " HEAD" : "HEAD");
      256 +
      257 +                if (i == trq.itrq_desc_tail)
      258 +                        (void) strcat(dother,
      259 +                            strlen(dother) > 0 ? " TAIL" : "TAIL");
      260 +
      261 +                mdb_printf("%-10d %-10s %-16p %-16p %-10s\n", i, dtype, dptr,
      262 +                    tcbptr, dother);
      263 +        }
      264 +
      265 +        mdb_free(descring, ringsz);
      266 +        mdb_free(wklist, wklistsz);
      267 +        return (DCMD_OK);
      268 +}
      269 +
 100  270  static const mdb_dcmd_t i40e_dcmds[] = {
 101  271          { "i40e_switch_rsrcs", NULL, "print switch resources",
 102  272              i40e_switch_rsrcs_dcmd, NULL },
      273 +        { "i40e_tx_ring", "[-a] -b [start index] -e [end index]\n",
      274 +            "dump TX descriptor ring state", i40e_tx_ring_dcmd,
      275 +            i40e_tx_ring_help },
 103  276          { NULL }
 104  277  };
 105  278  
 106  279  static const mdb_modinfo_t i40e_modinfo = {
 107  280          MDB_API_VERSION, i40e_dcmds, NULL
 108  281  };
 109  282  
 110  283  const mdb_modinfo_t *
 111  284  _mdb_init(void)
 112  285  {
 113  286          return (&i40e_modinfo);
 114  287  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX