PERFORCE change 118757 for review
Kip Macy
kmacy at FreeBSD.org
Tue Apr 24 22:19:27 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=118757
Change 118757 by kmacy at 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)
More information about the p4-projects
mailing list