Print this page
9994 cxgbe t4nex: Handle get_fl_payload() alloc failures
9995 cxgbe t4_devo_attach() should initialize ->sfl
        
*** 773,786 ****
  
                                  if (iq->polling && ((received_bytes + pkt_len) > budget))
                                          goto done;
  
                                  m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
!                                 if (m == NULL) {
!                                         panic("%s: line %d.", __func__,
!                                             __LINE__);
!                                 }
  
                                  iq->intr_next = iq->intr_params;
                                  m->b_rptr += sc->sge.pktshift;
                                  if (sc->params.tp.rx_pkt_encap)
                                  /* It is enabled only in T6 config file */
--- 773,784 ----
  
                                  if (iq->polling && ((received_bytes + pkt_len) > budget))
                                          goto done;
  
                                  m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
!                                 if (m == NULL)
!                                         goto done;
  
                                  iq->intr_next = iq->intr_params;
                                  m->b_rptr += sc->sge.pktshift;
                                  if (sc->params.tp.rx_pkt_encap)
                                  /* It is enabled only in T6 config file */
*** 806,819 ****
  
                                  break;
                          }
  
                          m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
!                         if (m == NULL) {
!                                 panic("%s: line %d.", __func__,
!                                     __LINE__);
!                         }
                          /* FALLTHROUGH */
  
                  case X_RSPD_TYPE_CPL:
                          ASSERT(rss->opcode < NUM_CPL_CMDS);
                          sc->cpl_handler[rss->opcode](iq, rss, m);
--- 804,815 ----
  
                                  break;
                          }
  
                          m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
!                         if (m == NULL)
!                                 goto done;
                          /* FALLTHROUGH */
  
                  case X_RSPD_TYPE_CPL:
                          ASSERT(rss->opcode < NUM_CPL_CMDS);
                          sc->cpl_handler[rss->opcode](iq, rss, m);
*** 859,868 ****
--- 855,865 ----
          struct rsp_ctrl *ctrl;
          const struct rss_header *rss;
          int ndescs = 0, limit, fl_bufs_used = 0;
          int rsp_type;
          uint32_t lq;
+         int starved;
          mblk_t *m;
          STAILQ_HEAD(, sge_iq) iql = STAILQ_HEAD_INITIALIZER(iql);
  
          limit = budget ? budget : iq->qsize / 8;
  
*** 885,897 ****
  
                                  ASSERT(iq->flags & IQ_HAS_FL);
  
                                  m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
                                  if (m == NULL) {
!                                         panic("%s: line %d.", __func__,
!                                             __LINE__);
                                  }
  
                          /* FALLTHRU */
                          case X_RSPD_TYPE_CPL:
  
                                  ASSERT(rss->opcode < NUM_CPL_CMDS);
--- 882,909 ----
  
                                  ASSERT(iq->flags & IQ_HAS_FL);
  
                                  m = get_fl_payload(sc, fl, lq, &fl_bufs_used);
                                  if (m == NULL) {
!                                         /*
!                                          * Rearm the iq with a
!                                          * longer-than-default timer
!                                          */
!                                         t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(ndescs) |
!                                                         V_INGRESSQID((u32)iq->cntxt_id) |
!                                                         V_SEINTARM(V_QINTR_TIMER_IDX(SGE_NTIMERS-1)));
!                                         if (fl_bufs_used > 0) {
!                                                 ASSERT(iq->flags & IQ_HAS_FL);
!                                                 FL_LOCK(fl);
!                                                 fl->needed += fl_bufs_used;
!                                                 starved = refill_fl(sc, fl, fl->cap / 8);
!                                                 FL_UNLOCK(fl);
!                                                 if (starved)
!                                                         add_fl_to_sfl(sc, fl);
                                          }
+                                         return (0);
+                                 }
  
                          /* FALLTHRU */
                          case X_RSPD_TYPE_CPL:
  
                                  ASSERT(rss->opcode < NUM_CPL_CMDS);
*** 966,976 ****
  
          t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_CIDXINC(ndescs) |
              V_INGRESSQID((u32)iq->cntxt_id) | V_SEINTARM(iq->intr_next));
  
          if (iq->flags & IQ_HAS_FL) {
-                 int starved;
  
                  FL_LOCK(fl);
                  fl->needed += fl_bufs_used;
                  starved = refill_fl(sc, fl, fl->cap / 4);
                  FL_UNLOCK(fl);
--- 978,987 ----
*** 1251,1260 ****
--- 1262,1272 ----
  static inline void
  init_fl(struct sge_fl *fl, uint16_t qsize)
  {
  
          fl->qsize = qsize;
+         fl->allocb_fail = 0;
  }
  
  static inline void
  init_eq(struct adapter *sc, struct sge_eq *eq, uint16_t eqtype, uint16_t qsize,
      uint8_t tx_chan, uint16_t iqid)
*** 2329,2345 ****
  {
          struct mblk_pair frame = {0};
          struct rxbuf *rxb;
          mblk_t *m = NULL;
          uint_t nbuf = 0, len, copy, n;
!         uint32_t cidx, offset;
  
          /*
           * The SGE won't pack a new frame into the current buffer if the entire
           * payload doesn't fit in the remaining space.  Move on to the next buf
           * in that case.
           */
          if (fl->offset > 0 && len_newbuf & F_RSPD_NEWBUF) {
                  fl->offset = 0;
                  if (++fl->cidx == fl->cap)
                          fl->cidx = 0;
                  nbuf++;
--- 2341,2359 ----
  {
          struct mblk_pair frame = {0};
          struct rxbuf *rxb;
          mblk_t *m = NULL;
          uint_t nbuf = 0, len, copy, n;
!         uint32_t cidx, offset, rcidx, roffset;
  
          /*
           * The SGE won't pack a new frame into the current buffer if the entire
           * payload doesn't fit in the remaining space.  Move on to the next buf
           * in that case.
           */
+         rcidx = fl->cidx;
+         roffset = fl->offset;
          if (fl->offset > 0 && len_newbuf & F_RSPD_NEWBUF) {
                  fl->offset = 0;
                  if (++fl->cidx == fl->cap)
                          fl->cidx = 0;
                  nbuf++;
*** 2349,2361 ****
  
          len = G_RSPD_LEN(len_newbuf);   /* pktshift + payload length */
          copy = (len <= fl->copy_threshold);
          if (copy != 0) {
                  frame.head = m = allocb(len, BPRI_HI);
!                 if (m == NULL)
                          return (NULL);
          }
  
          while (len) {
                  rxb = fl->sdesc[cidx].rxb;
                  n = min(len, rxb->buf_size - offset);
  
--- 2363,2382 ----
  
          len = G_RSPD_LEN(len_newbuf);   /* pktshift + payload length */
          copy = (len <= fl->copy_threshold);
          if (copy != 0) {
                  frame.head = m = allocb(len, BPRI_HI);
!                 if (m == NULL) {
!                         fl->allocb_fail++;
!                         cmn_err(CE_WARN,"%s: mbuf allocation failure "
!                                         "count = %llu", __func__,
!                                         (unsigned long long)fl->allocb_fail);
!                         fl->cidx = rcidx;
!                         fl->offset = roffset;
                          return (NULL);
                  }
+         }
  
          while (len) {
                  rxb = fl->sdesc[cidx].rxb;
                  n = min(len, rxb->buf_size - offset);
  
*** 2366,2376 ****
                          bcopy(rxb->va + offset, m->b_wptr, n);
                  else {
                          m = desballoc((unsigned char *)rxb->va + offset, n,
                              BPRI_HI, &rxb->freefunc);
                          if (m == NULL) {
!                                 freemsg(frame.head);
                                  return (NULL);
                          }
                          atomic_inc_uint(&rxb->ref_cnt);
                          if (frame.head != NULL)
                                  frame.tail->b_cont = m;
--- 2387,2405 ----
                          bcopy(rxb->va + offset, m->b_wptr, n);
                  else {
                          m = desballoc((unsigned char *)rxb->va + offset, n,
                              BPRI_HI, &rxb->freefunc);
                          if (m == NULL) {
!                                 fl->allocb_fail++;
!                                 cmn_err(CE_WARN,
!                                         "%s: mbuf allocation failure "
!                                         "count = %llu", __func__,
!                                         (unsigned long long)fl->allocb_fail);
!                                 if (frame.head)
!                                         freemsgchain(frame.head);
!                                 fl->cidx = rcidx;
!                                 fl->offset = roffset;
                                  return (NULL);
                          }
                          atomic_inc_uint(&rxb->ref_cnt);
                          if (frame.head != NULL)
                                  frame.tail->b_cont = m;