From owner-svn-src-all@freebsd.org Wed Jul 25 22:46:38 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1C0C51055EDA; Wed, 25 Jul 2018 22:46:38 +0000 (UTC) (envelope-from pkelsey@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id B914171246; Wed, 25 Jul 2018 22:46:37 +0000 (UTC) (envelope-from pkelsey@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 80E38206FE; Wed, 25 Jul 2018 22:46:37 +0000 (UTC) (envelope-from pkelsey@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6PMkbBj070202; Wed, 25 Jul 2018 22:46:37 GMT (envelope-from pkelsey@FreeBSD.org) Received: (from pkelsey@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6PMkb9j070201; Wed, 25 Jul 2018 22:46:37 GMT (envelope-from pkelsey@FreeBSD.org) Message-Id: <201807252246.w6PMkb9j070201@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pkelsey set sender to pkelsey@FreeBSD.org using -f From: Patrick Kelsey Date: Wed, 25 Jul 2018 22:46:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336727 - in head/sys/net: . altq X-SVN-Group: head X-SVN-Commit-Author: pkelsey X-SVN-Commit-Paths: in head/sys/net: . altq X-SVN-Commit-Revision: 336727 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Jul 2018 22:46:38 -0000 Author: pkelsey Date: Wed Jul 25 22:46:36 2018 New Revision: 336727 URL: https://svnweb.freebsd.org/changeset/base/336727 Log: ALTQ support for iflib. Reviewed by: jmallett, mmacy Differential Revision: https://reviews.freebsd.org/D16433 Modified: head/sys/net/altq/if_altq.h head/sys/net/iflib.c Modified: head/sys/net/altq/if_altq.h ============================================================================== --- head/sys/net/altq/if_altq.h Wed Jul 25 21:52:49 2018 (r336726) +++ head/sys/net/altq/if_altq.h Wed Jul 25 22:46:36 2018 (r336727) @@ -143,7 +143,11 @@ struct tb_regulator { #define ALTRQ_PURGE 1 /* purge all packets */ #define ALTQ_IS_READY(ifq) ((ifq)->altq_flags & ALTQF_READY) +#ifdef ALTQ #define ALTQ_IS_ENABLED(ifq) ((ifq)->altq_flags & ALTQF_ENABLED) +#else +#define ALTQ_IS_ENABLED(ifq) 0 +#endif #define ALTQ_NEEDS_CLASSIFY(ifq) ((ifq)->altq_flags & ALTQF_CLASSIFY) #define ALTQ_IS_CNDTNING(ifq) ((ifq)->altq_flags & ALTQF_CNDTNING) Modified: head/sys/net/iflib.c ============================================================================== --- head/sys/net/iflib.c Wed Jul 25 21:52:49 2018 (r336726) +++ head/sys/net/iflib.c Wed Jul 25 22:46:36 2018 (r336727) @@ -739,6 +739,10 @@ static int iflib_msix_init(if_ctx_t ctx); static int iflib_legacy_setup(if_ctx_t ctx, driver_filter_t filter, void *filterarg, int *rid, const char *str); static void iflib_txq_check_drain(iflib_txq_t txq, int budget); static uint32_t iflib_txq_can_drain(struct ifmp_ring *); +#ifdef ALTQ +static void iflib_altq_if_start(if_t ifp); +static int iflib_altq_if_transmit(if_t ifp, struct mbuf *m); +#endif static int iflib_register(if_ctx_t); static void iflib_init_locked(if_ctx_t ctx); static void iflib_add_device_sysctl_pre(if_ctx_t ctx); @@ -3775,6 +3779,10 @@ _task_fn_tx(void *context) IFDI_TX_QUEUE_INTR_ENABLE(ctx, txq->ift_id); return; } +#ifdef ALTQ + if (ALTQ_IS_ENABLED(&ifp->if_snd)) + iflib_altq_if_start(ifp); +#endif if (txq->ift_db_pending) ifmp_ring_enqueue(txq->ift_br, (void **)&txq, 1, TX_BATCH_SIZE, abdicate); else if (!abdicate) @@ -3963,8 +3971,9 @@ iflib_if_transmit(if_t ifp, struct mbuf *m) } MPASS(m->m_nextpkt == NULL); + /* ALTQ-enabled interfaces always use queue 0. */ qidx = 0; - if ((NTXQSETS(ctx) > 1) && M_HASHTYPE_GET(m)) + if ((NTXQSETS(ctx) > 1) && M_HASHTYPE_GET(m) && !ALTQ_IS_ENABLED(&ifp->if_snd)) qidx = QIDX(ctx, m); /* * XXX calculate buf_ring based on flowid (divvy up bits?) @@ -4024,7 +4033,60 @@ iflib_if_transmit(if_t ifp, struct mbuf *m) return (err); } +#ifdef ALTQ +/* + * The overall approach to integrating iflib with ALTQ is to continue to use + * the iflib mp_ring machinery between the ALTQ queue(s) and the hardware + * ring. Technically, when using ALTQ, queueing to an intermediate mp_ring + * is redundant/unnecessary, but doing so minimizes the amount of + * ALTQ-specific code required in iflib. It is assumed that the overhead of + * redundantly queueing to an intermediate mp_ring is swamped by the + * performance limitations inherent in using ALTQ. + * + * When ALTQ support is compiled in, all iflib drivers will use a transmit + * routine, iflib_altq_if_transmit(), that checks if ALTQ is enabled for the + * given interface. If ALTQ is enabled for an interface, then all + * transmitted packets for that interface will be submitted to the ALTQ + * subsystem via IFQ_ENQUEUE(). We don't use the legacy if_transmit() + * implementation because it uses IFQ_HANDOFF(), which will duplicatively + * update stats that the iflib machinery handles, and which is sensitve to + * the disused IFF_DRV_OACTIVE flag. Additionally, iflib_altq_if_start() + * will be installed as the start routine for use by ALTQ facilities that + * need to trigger queue drains on a scheduled basis. + * + */ static void +iflib_altq_if_start(if_t ifp) +{ + struct ifaltq *ifq = &ifp->if_snd; + struct mbuf *m; + + IFQ_LOCK(ifq); + IFQ_DEQUEUE_NOLOCK(ifq, m); + while (m != NULL) { + iflib_if_transmit(ifp, m); + IFQ_DEQUEUE_NOLOCK(ifq, m); + } + IFQ_UNLOCK(ifq); +} + +static int +iflib_altq_if_transmit(if_t ifp, struct mbuf *m) +{ + int err; + + if (ALTQ_IS_ENABLED(&ifp->if_snd)) { + IFQ_ENQUEUE(&ifp->if_snd, m, err); + if (err == 0) + iflib_altq_if_start(ifp); + } else + err = iflib_if_transmit(ifp, m); + + return (err); +} +#endif /* ALTQ */ + +static void iflib_if_qflush(if_t ifp) { if_ctx_t ctx = if_getsoftc(ifp); @@ -4041,6 +4103,10 @@ iflib_if_qflush(if_t ifp) ctx->ifc_flags &= ~IFC_QFLUSH; STATE_UNLOCK(ctx); + /* + * When ALTQ is enabled, this will also take care of purging the + * ALTQ queue(s). + */ if_qflush(ifp); } @@ -5165,7 +5231,12 @@ iflib_register(if_ctx_t ctx) if_setdev(ifp, dev); if_setinitfn(ifp, iflib_if_init); if_setioctlfn(ifp, iflib_if_ioctl); +#ifdef ALTQ + if_setstartfn(ifp, iflib_altq_if_start); + if_settransmitfn(ifp, iflib_altq_if_transmit); +#else if_settransmitfn(ifp, iflib_if_transmit); +#endif if_setqflushfn(ifp, iflib_if_qflush); if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);