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