Date: Tue, 24 Apr 2007 22:19:26 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 118757 for review Message-ID: <200704242219.l3OMJQHq030084@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=118757 Change 118757 by kmacy@kmacy_vt-x:opentoe_init on 2007/04/24 22:19:26 hook in ctrlq and offloadq restart tasks Affected files ... .. //depot/projects/opentoe/sys/dev/cxgb/cxgb_adapter.h#12 edit .. //depot/projects/opentoe/sys/dev/cxgb/cxgb_sge.c#16 edit Differences ... ==== //depot/projects/opentoe/sys/dev/cxgb/cxgb_adapter.h#12 (text+ko) ==== @@ -201,6 +201,7 @@ struct tx_sw_desc *sdesc; uint32_t token; bus_addr_t phys_addr; + struct task qresume_tsk; uint32_t cntxt_id; uint64_t stops; uint64_t restarts; @@ -229,7 +230,7 @@ struct sge_fl fl[SGE_RXQ_PER_SET]; struct lro_state lro; struct sge_txq txq[SGE_TXQ_PER_SET]; - unsigned long txq_stopped; /* which Tx queues are stopped */ + uint32_t txq_stopped; /* which Tx queues are stopped */ uint64_t port_stats[SGE_PSTAT_MAX]; struct port_info *port; int idx; /* qset # */ ==== //depot/projects/opentoe/sys/dev/cxgb/cxgb_sge.c#16 (text+ko) ==== @@ -1385,7 +1385,7 @@ return (0); } -#ifdef RESTART_CTRLQ + /** * restart_ctrlq - restart a suspended control queue * @qs: the queue set cotaining the control queue @@ -1393,7 +1393,7 @@ * Resumes transmission on a suspended Tx control queue. */ static void -restart_ctrlq(unsigned long data) +restart_ctrlq(void *data, int npending) { struct mbuf *m; struct sge_qset *qs = (struct sge_qset *)data; @@ -1401,8 +1401,10 @@ adapter_t *adap = qs->port->adapter; mtx_lock(&q->lock); + m = NULL; +#ifdef notyet again: reclaim_completed_tx_imm(q); - + while (q->in_use < q->size && (skb = __skb_dequeue(&q->sendq)) != NULL) { @@ -1423,12 +1425,12 @@ goto again; q->stops++; } - +#endif mtx_unlock(&q->lock); t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); } -#endif + /* * Send a management message through control queue 0 @@ -1440,172 +1442,6 @@ } /** - * t3_sge_alloc_qset - initialize an SGE queue set - * @sc: the controller softc - * @id: the queue set id - * @nports: how many Ethernet ports will be using this queue set - * @irq_vec_idx: the IRQ vector index for response queue interrupts - * @p: configuration parameters for this queue set - * @ntxq: number of Tx queues for the queue set - * @pi: port info for queue set - * - * Allocate resources and initialize an SGE queue set. A queue set - * comprises a response queue, two Rx free-buffer queues, and up to 3 - * Tx queues. The Tx queues are assigned roles in the order Ethernet - * queue, offload queue, and control queue. - */ -int -t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx, - const struct qset_params *p, int ntxq, struct port_info *pi) -{ - struct sge_qset *q = &sc->sge.qs[id]; - int i, ret = 0; - - init_qset_cntxt(q, id); - - if ((ret = alloc_ring(sc, p->fl_size, sizeof(struct rx_desc), - sizeof(struct rx_sw_desc), &q->fl[0].phys_addr, - &q->fl[0].desc, &q->fl[0].sdesc, - &q->fl[0].desc_tag, &q->fl[0].desc_map, - sc->rx_dmat, &q->fl[0].entry_tag)) != 0) { - printf("error %d from alloc ring fl0\n", ret); - goto err; - } - - if ((ret = alloc_ring(sc, p->jumbo_size, sizeof(struct rx_desc), - sizeof(struct rx_sw_desc), &q->fl[1].phys_addr, - &q->fl[1].desc, &q->fl[1].sdesc, - &q->fl[1].desc_tag, &q->fl[1].desc_map, - sc->rx_jumbo_dmat, &q->fl[1].entry_tag)) != 0) { - printf("error %d from alloc ring fl1\n", ret); - goto err; - } - - if ((ret = alloc_ring(sc, p->rspq_size, sizeof(struct rsp_desc), 0, - &q->rspq.phys_addr, &q->rspq.desc, NULL, - &q->rspq.desc_tag, &q->rspq.desc_map, - NULL, NULL)) != 0) { - printf("error %d from alloc ring rspq\n", ret); - goto err; - } - - for (i = 0; i < ntxq; ++i) { - /* - * The control queue always uses immediate data so does not - * need to keep track of any mbufs. - * XXX Placeholder for future TOE support. - */ - size_t sz = i == TXQ_CTRL ? 0 : sizeof(struct tx_sw_desc); - - if ((ret = alloc_ring(sc, p->txq_size[i], - sizeof(struct tx_desc), sz, - &q->txq[i].phys_addr, &q->txq[i].desc, - &q->txq[i].sdesc, &q->txq[i].desc_tag, - &q->txq[i].desc_map, - sc->tx_dmat, &q->txq[i].entry_tag)) != 0) { - printf("error %d from alloc ring tx %i\n", ret, i); - goto err; - } - q->txq[i].gen = 1; - q->txq[i].size = p->txq_size[i]; - mtx_init(&q->txq[i].lock, "t3 txq lock", NULL, MTX_DEF); - } - - q->fl[0].gen = q->fl[1].gen = 1; - q->fl[0].size = p->fl_size; - q->fl[1].size = p->jumbo_size; - - q->rspq.gen = 1; - q->rspq.size = p->rspq_size; - mtx_init(&q->rspq.lock, "t3 rspq lock", NULL, MTX_DEF); - - q->txq[TXQ_ETH].stop_thres = nports * - flits_to_desc(sgl_len(TX_MAX_SEGS + 1) + 3); - - q->fl[0].buf_size = MCLBYTES; - q->fl[0].zone = zone_clust; - q->fl[0].type = EXT_CLUSTER; - q->fl[1].buf_size = MJUMPAGESIZE; - q->fl[1].zone = zone_jumbop; - q->fl[1].type = EXT_JUMBOP; - - q->lro.enabled = lro_default; - - mtx_lock(&sc->sge.reg_lock); - ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx, - q->rspq.phys_addr, q->rspq.size, - q->fl[0].buf_size, 1, 0); - if (ret) { - printf("error %d from t3_sge_init_rspcntxt\n", ret); - goto err_unlock; - } - - for (i = 0; i < SGE_RXQ_PER_SET; ++i) { - ret = -t3_sge_init_flcntxt(sc, q->fl[i].cntxt_id, 0, - q->fl[i].phys_addr, q->fl[i].size, - q->fl[i].buf_size, p->cong_thres, 1, - 0); - if (ret) { - printf("error %d from t3_sge_init_flcntxt for index i=%d\n", ret, i); - goto err_unlock; - } - } - - ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_ETH].cntxt_id, USE_GTS, - SGE_CNTXT_ETH, id, q->txq[TXQ_ETH].phys_addr, - q->txq[TXQ_ETH].size, q->txq[TXQ_ETH].token, - 1, 0); - if (ret) { - printf("error %d from t3_sge_init_ecntxt\n", ret); - goto err_unlock; - } - - if (ntxq > 1) { - ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_OFLD].cntxt_id, - USE_GTS, SGE_CNTXT_OFLD, id, - q->txq[TXQ_OFLD].phys_addr, - q->txq[TXQ_OFLD].size, 0, 1, 0); - if (ret) { - printf("error %d from t3_sge_init_ecntxt\n", ret); - goto err_unlock; - } - } - - if (ntxq > 2) { - ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_CTRL].cntxt_id, 0, - SGE_CNTXT_CTRL, id, - q->txq[TXQ_CTRL].phys_addr, - q->txq[TXQ_CTRL].size, - q->txq[TXQ_CTRL].token, 1, 0); - if (ret) { - printf("error %d from t3_sge_init_ecntxt\n", ret); - goto err_unlock; - } - } - - mtx_unlock(&sc->sge.reg_lock); - t3_update_qset_coalesce(q, p); - q->port = pi; - - refill_fl(sc, &q->fl[0], q->fl[0].size); - refill_fl(sc, &q->fl[1], q->fl[1].size); - refill_rspq(sc, &q->rspq, q->rspq.size - 1); - - t3_write_reg(sc, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) | - V_NEWTIMER(q->rspq.holdoff_tmr)); - - return (0); - -err_unlock: - mtx_unlock(&sc->sge.reg_lock); -err: - t3_free_qset(sc, q); - - return (ret); -} - - -/** * free_qset - free the resources of an SGE queue set * @sc: the controller owning the queue set * @q: the queue set @@ -1717,19 +1553,15 @@ void t3_sge_stop(adapter_t *sc) { + int i; t3_set_reg_field(sc, A_SG_CONTROL, F_GLOBALENABLE, 0); -#ifdef notyet - if (!in_interrupt()) { - int i; - for (i = 0; i < SGE_QSETS; ++i) { - struct sge_qset *qs = &adap->sge.qs[i]; - - tasklet_kill(&qs->txq[TXQ_OFLD].qresume_tsk); - tasklet_kill(&qs->txq[TXQ_CTRL].qresume_tsk); - } + for (i = 0; i < SGE_QSETS; ++i) { + struct sge_qset *qs = &sc->sge.qs[i]; + + taskqueue_drain(sc->tq, &qs->txq[TXQ_OFLD].qresume_tsk); + taskqueue_drain(sc->tq, &qs->txq[TXQ_CTRL].qresume_tsk); } -#endif } @@ -1940,7 +1772,7 @@ } return NET_XMIT_SUCCESS; } -#ifdef notyet + /** * restart_offloadq - restart a suspended offload queue * @qs: the queue set cotaining the offload queue @@ -1948,17 +1780,20 @@ * Resumes transmission on a suspended Tx offload queue. */ static void -restart_offloadq(unsigned long data) +restart_offloadq(void *data, int npending) { struct mbuf *m; - struct sge_qset *qs = (struct sge_qset *)data; + struct sge_qset *qs = data; struct sge_txq *q = &qs->txq[TXQ_OFLD]; adapter_t *adap = qs->port->adapter; struct mbuf *m_vec[TX_CLEAN_MAX_DESC]; int i, cleaned; mtx_lock(&q->lock); + m = NULL; + cleaned = 0; +#ifdef notyet again: cleaned = reclaim_completed_tx(adap, q, TX_CLEAN_MAX_DESC, m_vec); while ((skb = skb_peek(&q->sendq)) != NULL) { @@ -1991,7 +1826,7 @@ write_ofld_wr(adap, skb, q, pidx, gen, ndesc, segs, nsegs); mtx_lock(&q->lock); } - +#endif mtx_unlock(&q->lock); #if USE_GTS @@ -2005,7 +1840,7 @@ m_freem_vec(m_vec[i]); } } -#endif + /** * queue_set - return the queue set a packet should use * @m: the packet @@ -2124,9 +1959,189 @@ static void restart_tx(struct sge_qset *qs) { - ; + struct adapter *sc = qs->port->adapter; + + if (isset(&qs->txq_stopped, TXQ_OFLD) && + should_restart_tx(&qs->txq[TXQ_OFLD]) && + test_and_clear_bit(TXQ_OFLD, &qs->txq_stopped)) { + qs->txq[TXQ_OFLD].restarts++; + taskqueue_enqueue(sc->tq, &qs->txq[TXQ_OFLD].qresume_tsk); + } + if (isset(&qs->txq_stopped, TXQ_CTRL) && + should_restart_tx(&qs->txq[TXQ_CTRL]) && + test_and_clear_bit(TXQ_CTRL, &qs->txq_stopped)) { + qs->txq[TXQ_CTRL].restarts++; + taskqueue_enqueue(sc->tq, &qs->txq[TXQ_CTRL].qresume_tsk); + } } +/** + * t3_sge_alloc_qset - initialize an SGE queue set + * @sc: the controller softc + * @id: the queue set id + * @nports: how many Ethernet ports will be using this queue set + * @irq_vec_idx: the IRQ vector index for response queue interrupts + * @p: configuration parameters for this queue set + * @ntxq: number of Tx queues for the queue set + * @pi: port info for queue set + * + * Allocate resources and initialize an SGE queue set. A queue set + * comprises a response queue, two Rx free-buffer queues, and up to 3 + * Tx queues. The Tx queues are assigned roles in the order Ethernet + * queue, offload queue, and control queue. + */ +int +t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx, + const struct qset_params *p, int ntxq, struct port_info *pi) +{ + struct sge_qset *q = &sc->sge.qs[id]; + int i, ret = 0; + + init_qset_cntxt(q, id); + + if ((ret = alloc_ring(sc, p->fl_size, sizeof(struct rx_desc), + sizeof(struct rx_sw_desc), &q->fl[0].phys_addr, + &q->fl[0].desc, &q->fl[0].sdesc, + &q->fl[0].desc_tag, &q->fl[0].desc_map, + sc->rx_dmat, &q->fl[0].entry_tag)) != 0) { + printf("error %d from alloc ring fl0\n", ret); + goto err; + } + + if ((ret = alloc_ring(sc, p->jumbo_size, sizeof(struct rx_desc), + sizeof(struct rx_sw_desc), &q->fl[1].phys_addr, + &q->fl[1].desc, &q->fl[1].sdesc, + &q->fl[1].desc_tag, &q->fl[1].desc_map, + sc->rx_jumbo_dmat, &q->fl[1].entry_tag)) != 0) { + printf("error %d from alloc ring fl1\n", ret); + goto err; + } + + if ((ret = alloc_ring(sc, p->rspq_size, sizeof(struct rsp_desc), 0, + &q->rspq.phys_addr, &q->rspq.desc, NULL, + &q->rspq.desc_tag, &q->rspq.desc_map, + NULL, NULL)) != 0) { + printf("error %d from alloc ring rspq\n", ret); + goto err; + } + + for (i = 0; i < ntxq; ++i) { + /* + * The control queue always uses immediate data so does not + * need to keep track of any mbufs. + * XXX Placeholder for future TOE support. + */ + size_t sz = i == TXQ_CTRL ? 0 : sizeof(struct tx_sw_desc); + + if ((ret = alloc_ring(sc, p->txq_size[i], + sizeof(struct tx_desc), sz, + &q->txq[i].phys_addr, &q->txq[i].desc, + &q->txq[i].sdesc, &q->txq[i].desc_tag, + &q->txq[i].desc_map, + sc->tx_dmat, &q->txq[i].entry_tag)) != 0) { + printf("error %d from alloc ring tx %i\n", ret, i); + goto err; + } + q->txq[i].gen = 1; + q->txq[i].size = p->txq_size[i]; + mtx_init(&q->txq[i].lock, "t3 txq lock", NULL, MTX_DEF); + } + + TASK_INIT(&q->txq[TXQ_OFLD].qresume_tsk, 0, restart_offloadq, q); + TASK_INIT(&q->txq[TXQ_CTRL].qresume_tsk, 0, restart_ctrlq, q); + + q->fl[0].gen = q->fl[1].gen = 1; + q->fl[0].size = p->fl_size; + q->fl[1].size = p->jumbo_size; + + q->rspq.gen = 1; + q->rspq.size = p->rspq_size; + mtx_init(&q->rspq.lock, "t3 rspq lock", NULL, MTX_DEF); + + q->txq[TXQ_ETH].stop_thres = nports * + flits_to_desc(sgl_len(TX_MAX_SEGS + 1) + 3); + + q->fl[0].buf_size = MCLBYTES; + q->fl[0].zone = zone_clust; + q->fl[0].type = EXT_CLUSTER; + q->fl[1].buf_size = MJUMPAGESIZE; + q->fl[1].zone = zone_jumbop; + q->fl[1].type = EXT_JUMBOP; + + q->lro.enabled = lro_default; + + mtx_lock(&sc->sge.reg_lock); + ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx, + q->rspq.phys_addr, q->rspq.size, + q->fl[0].buf_size, 1, 0); + if (ret) { + printf("error %d from t3_sge_init_rspcntxt\n", ret); + goto err_unlock; + } + + for (i = 0; i < SGE_RXQ_PER_SET; ++i) { + ret = -t3_sge_init_flcntxt(sc, q->fl[i].cntxt_id, 0, + q->fl[i].phys_addr, q->fl[i].size, + q->fl[i].buf_size, p->cong_thres, 1, + 0); + if (ret) { + printf("error %d from t3_sge_init_flcntxt for index i=%d\n", ret, i); + goto err_unlock; + } + } + + ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_ETH].cntxt_id, USE_GTS, + SGE_CNTXT_ETH, id, q->txq[TXQ_ETH].phys_addr, + q->txq[TXQ_ETH].size, q->txq[TXQ_ETH].token, + 1, 0); + if (ret) { + printf("error %d from t3_sge_init_ecntxt\n", ret); + goto err_unlock; + } + + if (ntxq > 1) { + ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_OFLD].cntxt_id, + USE_GTS, SGE_CNTXT_OFLD, id, + q->txq[TXQ_OFLD].phys_addr, + q->txq[TXQ_OFLD].size, 0, 1, 0); + if (ret) { + printf("error %d from t3_sge_init_ecntxt\n", ret); + goto err_unlock; + } + } + + if (ntxq > 2) { + ret = -t3_sge_init_ecntxt(sc, q->txq[TXQ_CTRL].cntxt_id, 0, + SGE_CNTXT_CTRL, id, + q->txq[TXQ_CTRL].phys_addr, + q->txq[TXQ_CTRL].size, + q->txq[TXQ_CTRL].token, 1, 0); + if (ret) { + printf("error %d from t3_sge_init_ecntxt\n", ret); + goto err_unlock; + } + } + + mtx_unlock(&sc->sge.reg_lock); + t3_update_qset_coalesce(q, p); + q->port = pi; + + refill_fl(sc, &q->fl[0], q->fl[0].size); + refill_fl(sc, &q->fl[1], q->fl[1].size); + refill_rspq(sc, &q->rspq, q->rspq.size - 1); + + t3_write_reg(sc, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) | + V_NEWTIMER(q->rspq.holdoff_tmr)); + + return (0); + +err_unlock: + mtx_unlock(&sc->sge.reg_lock); +err: + t3_free_qset(sc, q); + + return (ret); +} void t3_rx_eth(struct port_info *pi, struct sge_rspq *rq, struct mbuf *m, int ethpad)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704242219.l3OMJQHq030084>