From owner-svn-src-head@freebsd.org Mon Apr 17 09:00:22 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 20B51D4183F; Mon, 17 Apr 2017 09:00:22 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D9748A5F; Mon, 17 Apr 2017 09:00:21 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3H90LGH005619; Mon, 17 Apr 2017 09:00:21 GMT (envelope-from np@FreeBSD.org) Received: (from np@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3H90K98005617; Mon, 17 Apr 2017 09:00:20 GMT (envelope-from np@FreeBSD.org) Message-Id: <201704170900.v3H90K98005617@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: np set sender to np@FreeBSD.org using -f From: Navdeep Parhar Date: Mon, 17 Apr 2017 09:00:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317041 - head/sys/dev/cxgbe X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Apr 2017 09:00:22 -0000 Author: np Date: Mon Apr 17 09:00:20 2017 New Revision: 317041 URL: https://svnweb.freebsd.org/changeset/base/317041 Log: cxgbe: Add tunables to control the number of LRO entries and the number of rx mbufs that should be presorted before LRO. There is no change in default behavior. MFC after: 1 week Sponsored by: Chelsio Communications Modified: head/sys/dev/cxgbe/adapter.h head/sys/dev/cxgbe/t4_sge.c Modified: head/sys/dev/cxgbe/adapter.h ============================================================================== --- head/sys/dev/cxgbe/adapter.h Mon Apr 17 07:27:45 2017 (r317040) +++ head/sys/dev/cxgbe/adapter.h Mon Apr 17 09:00:20 2017 (r317041) @@ -322,6 +322,7 @@ enum { IQ_HAS_FL = (1 << 1), /* iq associated with a freelist */ IQ_INTR = (1 << 2), /* iq takes direct interrupt */ IQ_LRO_ENABLED = (1 << 3), /* iq is an eth rxq with LRO enabled */ + IQ_ADJ_CREDIT = (1 << 4), /* hw is off by 1 credit for this iq */ /* iq state */ IQS_DISABLED = 0, Modified: head/sys/dev/cxgbe/t4_sge.c ============================================================================== --- head/sys/dev/cxgbe/t4_sge.c Mon Apr 17 07:27:45 2017 (r317040) +++ head/sys/dev/cxgbe/t4_sge.c Mon Apr 17 09:00:20 2017 (r317041) @@ -157,6 +157,18 @@ TUNABLE_INT("hw.cxgbe.safest_rx_cluster" static int tscale = 1; TUNABLE_INT("hw.cxgbe.tscale", &tscale); +/* + * Number of LRO entries in the lro_ctrl structure per rx queue. + */ +static int lro_entries = TCP_LRO_ENTRIES; +TUNABLE_INT("hw.cxgbe.lro_entries", &lro_entries); + +/* + * This enables presorting of frames before they're fed into tcp_lro_rx. + */ +static int lro_mbufs = 0; +TUNABLE_INT("hw.cxgbe.lro_mbufs", &lro_mbufs); + struct txpkts { u_int wr_type; /* type 0 or type 1 */ u_int npkt; /* # of packets in this work request */ @@ -1380,6 +1392,13 @@ t4_vi_intr(void *arg) t4_intr(irq->rxq); } +static inline int +sort_before_lro(struct lro_ctrl *lro) +{ + + return (lro->lro_mbuf_max != 0); +} + /* * Deals with anything and everything on the given ingress queue. */ @@ -1399,6 +1418,7 @@ service_iq(struct sge_iq *iq, int budget STAILQ_HEAD(, sge_iq) iql = STAILQ_HEAD_INITIALIZER(iql); #if defined(INET) || defined(INET6) const struct timeval lro_timeout = {0, sc->lro_timeout}; + struct lro_ctrl *lro = &rxq->lro; #endif KASSERT(iq->state == IQS_BUSY, ("%s: iq %p not BUSY", __func__, iq)); @@ -1413,6 +1433,23 @@ service_iq(struct sge_iq *iq, int budget fl_hw_cidx = 0; /* to silence gcc warning */ } +#if defined(INET) || defined(INET6) + if (iq->flags & IQ_ADJ_CREDIT) { + MPASS(sort_before_lro(lro)); + iq->flags &= ~IQ_ADJ_CREDIT; + if ((d->rsp.u.type_gen & F_RSPD_GEN) != iq->gen) { + tcp_lro_flush_all(lro); + t4_write_reg(sc, sc->sge_gts_reg, V_CIDXINC(1) | + V_INGRESSQID((u32)iq->cntxt_id) | + V_SEINTARM(iq->intr_params)); + return (0); + } + ndescs = 1; + } +#else + MPASS((iq->flags & IQ_ADJ_CREDIT) == 0); +#endif + /* * We always come back and check the descriptor ring for new indirect * interrupts and other responses after running a single handler. @@ -1524,8 +1561,9 @@ service_iq(struct sge_iq *iq, int budget #if defined(INET) || defined(INET6) if (iq->flags & IQ_LRO_ENABLED && + !sort_before_lro(lro) && sc->lro_timeout != 0) { - tcp_lro_flush_inactive(&rxq->lro, + tcp_lro_flush_inactive(lro, &lro_timeout); } #endif @@ -1565,9 +1603,14 @@ process_iql: #if defined(INET) || defined(INET6) if (iq->flags & IQ_LRO_ENABLED) { - struct lro_ctrl *lro = &rxq->lro; - - tcp_lro_flush_all(lro); + if (ndescs > 0 && lro->lro_mbuf_count > 8) { + MPASS(sort_before_lro(lro)); + /* hold back one credit and don't flush LRO state */ + iq->flags |= IQ_ADJ_CREDIT; + ndescs--; + } else { + tcp_lro_flush_all(lro); + } } #endif @@ -1856,10 +1899,14 @@ t4_eth_rx(struct sge_iq *iq, const struc } #if defined(INET) || defined(INET6) - if (iq->flags & IQ_LRO_ENABLED && - tcp_lro_rx(lro, m0, 0) == 0) { - /* queued for LRO */ - } else + if (iq->flags & IQ_LRO_ENABLED) { + if (sort_before_lro(lro)) { + tcp_lro_queue_mbuf(lro, m0); + return (0); /* queued for sort, then LRO */ + } + if (tcp_lro_rx(lro, m0, 0) == 0) + return (0); /* queued for LRO */ + } #endif ifp->if_input(ifp, m0); @@ -3050,10 +3097,10 @@ alloc_rxq(struct vi_info *vi, struct sge FL_UNLOCK(&rxq->fl); #if defined(INET) || defined(INET6) - rc = tcp_lro_init(&rxq->lro); + rc = tcp_lro_init_args(&rxq->lro, vi->ifp, lro_entries, lro_mbufs); if (rc != 0) return (rc); - rxq->lro.ifp = vi->ifp; /* also indicates LRO init'ed */ + MPASS(rxq->lro.ifp == vi->ifp); /* also indicates LRO init'ed */ if (vi->ifp->if_capenable & IFCAP_LRO) rxq->iq.flags |= IQ_LRO_ENABLED;