svn commit: r317849 - in head/sys: dev/cxgbe/tom modules/cxgbe/tom

Navdeep Parhar np at FreeBSD.org
Fri May 5 20:06:51 UTC 2017


Author: np
Date: Fri May  5 20:06:49 2017
New Revision: 317849
URL: https://svnweb.freebsd.org/changeset/base/317849

Log:
  cxgbe/t4_tom: Per-connection rate limiting for TCP sockets handled by
  the TOE.  For now this capability is always enabled in kernels with
  options RATELIMIT.  t4_tom will check if_capenable once the base driver
  gets code to support rate limiting for any socket (TOE or not).
  
  This was tested with iperf3 and netperf ToT as they already support
  SO_MAX_PACING_RATE sockopt.  There is a bug in firmwares prior to
  1.16.45.0 that affects the BSD driver only and results in rate-limiting
  at an incorrect rate.  This will resolve by itself as soon as 1.16.45.0
  or later firmware shows up in the driver.
  
  Relnotes:	Yes
  Sponsored by:	Chelsio Communications

Modified:
  head/sys/dev/cxgbe/tom/t4_cpl_io.c
  head/sys/dev/cxgbe/tom/t4_tom.c
  head/sys/dev/cxgbe/tom/t4_tom.h
  head/sys/modules/cxgbe/tom/Makefile

Modified: head/sys/dev/cxgbe/tom/t4_cpl_io.c
==============================================================================
--- head/sys/dev/cxgbe/tom/t4_cpl_io.c	Fri May  5 20:00:53 2017	(r317848)
+++ head/sys/dev/cxgbe/tom/t4_cpl_io.c	Fri May  5 20:06:49 2017	(r317849)
@@ -29,6 +29,8 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_ratelimit.h"
 
 #ifdef TCP_OFFLOAD
 #include <sys/param.h>
@@ -186,6 +188,76 @@ send_flowc_wr(struct toepcb *toep, struc
         t4_wrq_tx(sc, wr);
 }
 
+#ifdef RATELIMIT
+/*
+ * Input is Bytes/second (so_max_pacing-rate), chip counts in Kilobits/second.
+ */
+static int
+update_tx_rate_limit(struct adapter *sc, struct toepcb *toep, u_int Bps)
+{
+	int tc_idx, rc;
+	const u_int kbps = (u_int) (uint64_t)Bps * 8ULL / 1000;
+	const int port_id = toep->vi->pi->port_id;
+
+	CTR3(KTR_CXGBE, "%s: tid %u, rate %uKbps", __func__, toep->tid, kbps);
+
+	if (kbps == 0) {
+		/* unbind */
+		tc_idx = -1;
+	} else {
+		rc = t4_reserve_cl_rl_kbps(sc, port_id, kbps, &tc_idx);
+		if (rc != 0)
+			return (rc);
+		MPASS(tc_idx >= 0 && tc_idx < sc->chip_params->nsched_cls);
+	}
+
+	if (toep->tc_idx != tc_idx) {
+		struct wrqe *wr;
+		struct fw_flowc_wr *flowc;
+		int nparams = 1, flowclen, flowclen16;
+		struct ofld_tx_sdesc *txsd = &toep->txsd[toep->txsd_pidx];
+
+		flowclen = sizeof(*flowc) + nparams * sizeof(struct
+		    fw_flowc_mnemval);
+		flowclen16 = howmany(flowclen, 16);
+		if (toep->tx_credits < flowclen16 || toep->txsd_avail == 0 ||
+		    (wr = alloc_wrqe(roundup2(flowclen, 16), toep->ofld_txq)) == NULL) {
+			if (tc_idx >= 0)
+				t4_release_cl_rl_kbps(sc, port_id, tc_idx);
+			return (ENOMEM);
+		}
+
+		flowc = wrtod(wr);
+		memset(flowc, 0, wr->wr_len);
+
+		flowc->op_to_nparams = htobe32(V_FW_WR_OP(FW_FLOWC_WR) |
+		    V_FW_FLOWC_WR_NPARAMS(nparams));
+		flowc->flowid_len16 = htonl(V_FW_WR_LEN16(flowclen16) |
+		    V_FW_WR_FLOWID(toep->tid));
+
+		flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_SCHEDCLASS;
+		if (tc_idx == -1)
+			flowc->mnemval[0].val = htobe32(0xff);
+		else
+			flowc->mnemval[0].val = htobe32(tc_idx);
+
+		txsd->tx_credits = flowclen16;
+		txsd->plen = 0;
+		toep->tx_credits -= txsd->tx_credits;
+		if (__predict_false(++toep->txsd_pidx == toep->txsd_total))
+			toep->txsd_pidx = 0;
+		toep->txsd_avail--;
+		t4_wrq_tx(sc, wr);
+	}
+
+	if (toep->tc_idx >= 0)
+		t4_release_cl_rl_kbps(sc, port_id, toep->tc_idx);
+	toep->tc_idx = tc_idx;
+
+	return (0);
+}
+#endif
+
 void
 send_reset(struct adapter *sc, struct toepcb *toep, uint32_t snd_nxt)
 {
@@ -619,7 +691,7 @@ t4_push_frames(struct adapter *sc, struc
 	struct socket *so = inp->inp_socket;
 	struct sockbuf *sb = &so->so_snd;
 	int tx_credits, shove, compl, sowwakeup;
-	struct ofld_tx_sdesc *txsd = &toep->txsd[toep->txsd_pidx];
+	struct ofld_tx_sdesc *txsd;
 	bool aiotx_mbuf_seen;
 
 	INP_WLOCK_ASSERT(inp);
@@ -638,6 +710,13 @@ t4_push_frames(struct adapter *sc, struc
 	if (__predict_false(toep->flags & TPF_ABORT_SHUTDOWN))
 		return;
 
+#ifdef RATELIMIT
+	if (__predict_false(inp->inp_flags2 & INP_RATE_LIMIT_CHANGED) &&
+	    (update_tx_rate_limit(sc, toep, so->so_max_pacing_rate) == 0)) {
+		inp->inp_flags2 &= ~INP_RATE_LIMIT_CHANGED;
+	}
+#endif
+
 	/*
 	 * This function doesn't resume by itself.  Someone else must clear the
 	 * flag and call this function.
@@ -648,6 +727,7 @@ t4_push_frames(struct adapter *sc, struc
 		return;
 	}
 
+	txsd = &toep->txsd[toep->txsd_pidx];
 	do {
 		tx_credits = min(toep->tx_credits, MAX_OFLD_TX_CREDITS);
 		max_imm = max_imm_payload(tx_credits);

Modified: head/sys/dev/cxgbe/tom/t4_tom.c
==============================================================================
--- head/sys/dev/cxgbe/tom/t4_tom.c	Fri May  5 20:00:53 2017	(r317848)
+++ head/sys/dev/cxgbe/tom/t4_tom.c	Fri May  5 20:06:49 2017	(r317849)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_ratelimit.h"
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -156,6 +157,7 @@ alloc_toepcb(struct vi_info *vi, int txq
 	refcount_init(&toep->refcount, 1);
 	toep->td = sc->tom_softc;
 	toep->vi = vi;
+	toep->tc_idx = -1;
 	toep->tx_total = tx_credits;
 	toep->tx_credits = tx_credits;
 	toep->ofld_txq = &sc->sge.ofld_txq[txqid];
@@ -312,6 +314,10 @@ release_offload_resources(struct toepcb 
 	if (toep->ce)
 		release_lip(td, toep->ce);
 
+#ifdef RATELIMIT
+	if (toep->tc_idx != -1)
+		t4_release_cl_rl_kbps(sc, toep->vi->pi->port_id, toep->tc_idx);
+#endif
 	mtx_lock(&td->toep_list_lock);
 	TAILQ_REMOVE(&td->toep_list, toep, link);
 	mtx_unlock(&td->toep_list_lock);

Modified: head/sys/dev/cxgbe/tom/t4_tom.h
==============================================================================
--- head/sys/dev/cxgbe/tom/t4_tom.h	Fri May  5 20:00:53 2017	(r317848)
+++ head/sys/dev/cxgbe/tom/t4_tom.h	Fri May  5 20:06:49 2017	(r317849)
@@ -149,6 +149,7 @@ struct toepcb {
 	struct l2t_entry *l2te;	/* L2 table entry used by this connection */
 	struct clip_entry *ce;	/* CLIP table entry used by this tid */
 	int tid;		/* Connection identifier */
+	int tc_idx;		/* traffic class that this tid is bound to */
 
 	/* tx credit handling */
 	u_int tx_total;		/* total tx WR credits (in 16B units) */

Modified: head/sys/modules/cxgbe/tom/Makefile
==============================================================================
--- head/sys/modules/cxgbe/tom/Makefile	Fri May  5 20:00:53 2017	(r317848)
+++ head/sys/modules/cxgbe/tom/Makefile	Fri May  5 20:06:49 2017	(r317849)
@@ -10,6 +10,7 @@ SRCS=	bus_if.h
 SRCS+=	device_if.h
 SRCS+=	opt_inet.h
 SRCS+=	opt_inet6.h
+SRCS+=	opt_ratelimit.h
 SRCS+=	pci_if.h
 SRCS+=	t4_connect.c
 SRCS+=	t4_cpl_io.c


More information about the svn-src-head mailing list