Print this page
9994 cxgbe t4nex: Handle get_fl_payload() alloc failures
9995 cxgbe t4_devo_attach() should initialize ->sfl

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/cxgbe/t4nex/t4_sge.c
          +++ new/usr/src/uts/common/io/cxgbe/t4nex/t4_sge.c
↓ open down ↓ 767 lines elided ↑ open up ↑
 768  768                          ASSERT(iq->flags & IQ_HAS_FL);
 769  769  
 770  770                          if (CPL_RX_PKT == rss->opcode) {
 771  771                                  cpl = (void *)(rss + 1);
 772  772                                  pkt_len = be16_to_cpu(cpl->len);
 773  773  
 774  774                                  if (iq->polling && ((received_bytes + pkt_len) > budget))
 775  775                                          goto done;
 776  776  
 777  777                                  m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
 778      -                                if (m == NULL) {
 779      -                                        panic("%s: line %d.", __func__,
 780      -                                            __LINE__);
 781      -                                }
      778 +                                if (m == NULL)
      779 +                                        goto done;
 782  780  
 783  781                                  iq->intr_next = iq->intr_params;
 784  782                                  m->b_rptr += sc->sge.pktshift;
 785  783                                  if (sc->params.tp.rx_pkt_encap)
 786  784                                  /* It is enabled only in T6 config file */
 787  785                                          err_vec = G_T6_COMPR_RXERR_VEC(ntohs(cpl->err_vec));
 788  786                                  else
 789  787                                          err_vec = ntohs(cpl->err_vec);
 790  788  
 791  789                                  csum_ok = cpl->csum_calc && !err_vec;
↓ open down ↓ 9 lines elided ↑ open up ↑
 801  799                                  rxq->rxbytes += pkt_len;
 802  800                                  received_bytes += pkt_len;
 803  801  
 804  802                                  *mblk_tail = m;
 805  803                                  mblk_tail = &m->b_next;
 806  804  
 807  805                                  break;
 808  806                          }
 809  807  
 810  808                          m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
 811      -                        if (m == NULL) {
 812      -                                panic("%s: line %d.", __func__,
 813      -                                    __LINE__);
 814      -                        }
      809 +                        if (m == NULL)
      810 +                                goto done;
 815  811                          /* FALLTHROUGH */
 816  812  
 817  813                  case X_RSPD_TYPE_CPL:
 818  814                          ASSERT(rss->opcode < NUM_CPL_CMDS);
 819  815                          sc->cpl_handler[rss->opcode](iq, rss, m);
 820  816                          break;
 821  817  
 822  818                  default:
 823  819                          break;
 824  820                  }
↓ open down ↓ 29 lines elided ↑ open up ↑
 854  850  {
 855  851          struct sge_iq *q;
 856  852          struct sge_rxq *rxq = iq_to_rxq(iq);    /* Use iff iq is part of rxq */
 857  853          struct sge_fl *fl = &rxq->fl;           /* Use iff IQ_HAS_FL */
 858  854          struct adapter *sc = iq->adapter;
 859  855          struct rsp_ctrl *ctrl;
 860  856          const struct rss_header *rss;
 861  857          int ndescs = 0, limit, fl_bufs_used = 0;
 862  858          int rsp_type;
 863  859          uint32_t lq;
      860 +        int starved;
 864  861          mblk_t *m;
 865  862          STAILQ_HEAD(, sge_iq) iql = STAILQ_HEAD_INITIALIZER(iql);
 866  863  
 867  864          limit = budget ? budget : iq->qsize / 8;
 868  865  
 869  866          /*
 870  867           * We always come back and check the descriptor ring for new indirect
 871  868           * interrupts and other responses after running a single handler.
 872  869           */
 873  870          for (;;) {
↓ open down ↓ 6 lines elided ↑ open up ↑
 880  877                          lq = be32_to_cpu(ctrl->pldbuflen_qid);
 881  878                          rss = (const void *)iq->cdesc;
 882  879  
 883  880                          switch (rsp_type) {
 884  881                          case X_RSPD_TYPE_FLBUF:
 885  882  
 886  883                                  ASSERT(iq->flags & IQ_HAS_FL);
 887  884  
 888  885                                  m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
 889  886                                  if (m == NULL) {
 890      -                                        panic("%s: line %d.", __func__,
 891      -                                            __LINE__);
      887 +                                        /*
      888 +                                         * Rearm the iq with a
      889 +                                         * longer-than-default timer
      890 +                                         */
      891 +                                        t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(ndescs) |
      892 +                                                        V_INGRESSQID((u32)iq->cntxt_id) |
      893 +                                                        V_SEINTARM(V_QINTR_TIMER_IDX(SGE_NTIMERS-1)));
      894 +                                        if (fl_bufs_used > 0) {
      895 +                                                ASSERT(iq->flags & IQ_HAS_FL);
      896 +                                                FL_LOCK(fl);
      897 +                                                fl->needed += fl_bufs_used;
      898 +                                                starved = refill_fl(sc, fl, fl->cap / 8);
      899 +                                                FL_UNLOCK(fl);
      900 +                                                if (starved)
      901 +                                                        add_fl_to_sfl(sc, fl);
      902 +                                        }
      903 +                                        return (0);
 892  904                                  }
 893  905  
 894  906                          /* FALLTHRU */
 895  907                          case X_RSPD_TYPE_CPL:
 896  908  
 897  909                                  ASSERT(rss->opcode < NUM_CPL_CMDS);
 898  910                                  sc->cpl_handler[rss->opcode](iq, rss, m);
 899  911                                  break;
 900  912  
 901  913                          case X_RSPD_TYPE_INTR:
↓ open down ↓ 59 lines elided ↑ open up ↑
 961  973                  if (service_iq(q, q->qsize / 8) == 0)
 962  974                          (void) atomic_cas_uint(&q->state, IQS_BUSY, IQS_IDLE);
 963  975                  else
 964  976                          STAILQ_INSERT_TAIL(&iql, q, link);
 965  977          }
 966  978  
 967  979          t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(ndescs) |
 968  980              V_INGRESSQID((u32)iq->cntxt_id) | V_SEINTARM(iq->intr_next));
 969  981  
 970  982          if (iq->flags & IQ_HAS_FL) {
 971      -                int starved;
 972  983  
 973  984                  FL_LOCK(fl);
 974  985                  fl->needed += fl_bufs_used;
 975  986                  starved = refill_fl(sc, fl, fl->cap / 4);
 976  987                  FL_UNLOCK(fl);
 977  988                  if (starved != 0)
 978  989                          add_fl_to_sfl(sc, fl);
 979  990          }
 980  991  
 981  992          return (0);
↓ open down ↓ 264 lines elided ↑ open up ↑
1246 1257          }
1247 1258          iq->qsize = roundup(qsize, 16);         /* See FW_IQ_CMD/iqsize */
1248 1259          iq->esize = max(esize, 16);             /* See FW_IQ_CMD/iqesize */
1249 1260  }
1250 1261  
1251 1262  static inline void
1252 1263  init_fl(struct sge_fl *fl, uint16_t qsize)
1253 1264  {
1254 1265  
1255 1266          fl->qsize = qsize;
     1267 +        fl->allocb_fail = 0;
1256 1268  }
1257 1269  
1258 1270  static inline void
1259 1271  init_eq(struct adapter *sc, struct sge_eq *eq, uint16_t eqtype, uint16_t qsize,
1260 1272      uint8_t tx_chan, uint16_t iqid)
1261 1273  {
1262 1274          struct sge *s = &sc->sge;
1263 1275          uint32_t r;
1264 1276  
1265 1277          ASSERT(tx_chan < NCHAN);
↓ open down ↓ 1058 lines elided ↑ open up ↑
2324 2336   * Note that fl->cidx and fl->offset are left unchanged in case of failure.
2325 2337   */
2326 2338  static mblk_t *
2327 2339  get_fl_payload(struct adapter *sc, struct sge_fl *fl,
2328 2340                 uint32_t len_newbuf, int *fl_bufs_used)
2329 2341  {
2330 2342          struct mblk_pair frame = {0};
2331 2343          struct rxbuf *rxb;
2332 2344          mblk_t *m = NULL;
2333 2345          uint_t nbuf = 0, len, copy, n;
2334      -        uint32_t cidx, offset;
     2346 +        uint32_t cidx, offset, rcidx, roffset;
2335 2347  
2336 2348          /*
2337 2349           * The SGE won't pack a new frame into the current buffer if the entire
2338 2350           * payload doesn't fit in the remaining space.  Move on to the next buf
2339 2351           * in that case.
2340 2352           */
     2353 +        rcidx = fl->cidx;
     2354 +        roffset = fl->offset;
2341 2355          if (fl->offset > 0 && len_newbuf & F_RSPD_NEWBUF) {
2342 2356                  fl->offset = 0;
2343 2357                  if (++fl->cidx == fl->cap)
2344 2358                          fl->cidx = 0;
2345 2359                  nbuf++;
2346 2360          }
2347 2361          cidx = fl->cidx;
2348 2362          offset = fl->offset;
2349 2363  
2350 2364          len = G_RSPD_LEN(len_newbuf);   /* pktshift + payload length */
2351 2365          copy = (len <= fl->copy_threshold);
2352 2366          if (copy != 0) {
2353 2367                  frame.head = m = allocb(len, BPRI_HI);
2354      -                if (m == NULL)
     2368 +                if (m == NULL) {
     2369 +                        fl->allocb_fail++;
     2370 +                        cmn_err(CE_WARN,"%s: mbuf allocation failure "
     2371 +                                        "count = %llu", __func__,
     2372 +                                        (unsigned long long)fl->allocb_fail);
     2373 +                        fl->cidx = rcidx;
     2374 +                        fl->offset = roffset;
2355 2375                          return (NULL);
     2376 +                }
2356 2377          }
2357 2378  
2358 2379          while (len) {
2359 2380                  rxb = fl->sdesc[cidx].rxb;
2360 2381                  n = min(len, rxb->buf_size - offset);
2361 2382  
2362 2383                  (void) ddi_dma_sync(rxb->dhdl, offset, n,
2363 2384                      DDI_DMA_SYNC_FORKERNEL);
2364 2385  
2365 2386                  if (copy != 0)
2366 2387                          bcopy(rxb->va + offset, m->b_wptr, n);
2367 2388                  else {
2368 2389                          m = desballoc((unsigned char *)rxb->va + offset, n,
2369 2390                              BPRI_HI, &rxb->freefunc);
2370 2391                          if (m == NULL) {
2371      -                                freemsg(frame.head);
     2392 +                                fl->allocb_fail++;
     2393 +                                cmn_err(CE_WARN,
     2394 +                                        "%s: mbuf allocation failure "
     2395 +                                        "count = %llu", __func__,
     2396 +                                        (unsigned long long)fl->allocb_fail);
     2397 +                                if (frame.head)
     2398 +                                        freemsgchain(frame.head);
     2399 +                                fl->cidx = rcidx;
     2400 +                                fl->offset = roffset;
2372 2401                                  return (NULL);
2373 2402                          }
2374 2403                          atomic_inc_uint(&rxb->ref_cnt);
2375 2404                          if (frame.head != NULL)
2376 2405                                  frame.tail->b_cont = m;
2377 2406                          else
2378 2407                                  frame.head = m;
2379 2408                          frame.tail = m;
2380 2409                  }
2381 2410                  m->b_wptr += n;
↓ open down ↓ 1389 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX