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;