From owner-svn-src-stable-12@freebsd.org Tue Sep 1 20:58:24 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 54B9E37822F; Tue, 1 Sep 2020 20:58:24 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Bgztm1bj3z4G33; Tue, 1 Sep 2020 20:58:24 +0000 (UTC) (envelope-from vmaffione@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 174761F7A2; Tue, 1 Sep 2020 20:58:24 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 081KwNV3005417; Tue, 1 Sep 2020 20:58:23 GMT (envelope-from vmaffione@FreeBSD.org) Received: (from vmaffione@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 081KwNUE005416; Tue, 1 Sep 2020 20:58:23 GMT (envelope-from vmaffione@FreeBSD.org) Message-Id: <202009012058.081KwNUE005416@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: vmaffione set sender to vmaffione@FreeBSD.org using -f From: Vincenzo Maffione Date: Tue, 1 Sep 2020 20:58:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r365066 - stable/12/sys/net X-SVN-Group: stable-12 X-SVN-Commit-Author: vmaffione X-SVN-Commit-Paths: stable/12/sys/net X-SVN-Commit-Revision: 365066 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Sep 2020 20:58:24 -0000 Author: vmaffione Date: Tue Sep 1 20:58:23 2020 New Revision: 365066 URL: https://svnweb.freebsd.org/changeset/base/365066 Log: r364770 iflib: netmap: publish all the receive buffer At initialization time, the netmap RX refill function used to prepare the NIC RX ring with N-1 buffers rather than N (with N equal to the number of descriptors in the NIC RX ring). This is not how netmap is supposed to work, as it would keep kring->nr_hwcur not in sync with the NIC "next index to refill" (i.e., fl->ifl_pidx). Instead we prepare N buffers, although we still publish (with isc_rxd_flush()) only the first N-1 buffers, to avoid the NIC producer pointer to overrun the NIC consumer pointer (for NICs where this is a real issue, e.g. Intel ones). Modified: stable/12/sys/net/iflib.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/iflib.c ============================================================================== --- stable/12/sys/net/iflib.c Tue Sep 1 20:50:16 2020 (r365065) +++ stable/12/sys/net/iflib.c Tue Sep 1 20:58:23 2020 (r365066) @@ -837,7 +837,6 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring { struct netmap_adapter *na = kring->na; u_int const lim = kring->nkr_num_slots - 1; - u_int head = kring->rhead; u_int nm_i = kring->nr_hwcur; struct netmap_ring *ring = kring->ring; bus_dmamap_t *map; @@ -845,39 +844,46 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = &rxq->ifr_fl[0]; u_int nic_i_first, nic_i; - int i; + int i, n; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif /* - * Netmap requires that we leave (at least) one free slot - * in the ring, so that it can distinguish between an empty - * ring (nr_hwcur == nr_hwtail, i.e. all the buffers owned by the - * user) and a full ring (nr_hwtail == (nr_hwcur - 1) mod N, i.e. - * all the buffers owned by the kernel). - * We thus set head (the refill limit) to nr_hwcur - 1 - * at initialization. The rest of the code will then make sure - * than nr_hwtail never overcomes nr_hwcur. + * This function is used both at initialization and in rxsync. + * At initialization we need to prepare (with isc_rxd_refill()) + * all the (N) netmap buffers in the ring, in such a way to keep + * fl->ifl_pidx and kring->nr_hwcur in sync (except for + * kring->nkr_hwofs); at rxsync time, both indexes point to the + * next buffer to be refilled. + * In any case we publish (with isc_rxd_flush()) up to + * (fl->ifl_pidx - 1) % N (included), to avoid the NIC tail/prod + * pointer to overrun the head/cons pointer, although this is + * not necessary for some NICs (e.g. vmx). */ - if (__predict_false(init)) { - head = nm_prev(nm_i, lim); - } else if (nm_i == head) { - /* Nothing to do. We can leave early. */ - return (0); + if (__predict_false(init)) + n = kring->nkr_num_slots; + else { + n = kring->rhead - nm_i; + if (n == 0) + return (0); /* Nothing to do. */ + if (n < 0) + n += kring->nkr_num_slots; } + /* Start to refill from nr_hwcur, publishing n buffers. */ iru_init(&iru, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; - nic_i = netmap_idx_k2n(kring, nm_i); + nic_i = fl->ifl_pidx; + MPASS(nic_i == netmap_idx_k2n(kring, nm_i)); DBG_COUNTER_INC(fl_refills); - while (nm_i != head) { + while (n > 0) { #if IFLIB_DEBUG_COUNTERS if (++rf_count == 9) DBG_COUNTER_INC(fl_refills_large); #endif nic_i_first = nic_i; - for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) { + for (i = 0; n > 0 && i < IFLIB_MAX_RX_REFRESH; n--, i++) { struct netmap_slot *slot = &ring->slot[nm_i]; void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[i]); @@ -908,11 +914,11 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring iru.iru_count = i; ctx->isc_rxd_refill(ctx->ifc_softc, &iru); } - kring->nr_hwcur = head; + fl->ifl_pidx = nic_i; + MPASS(!init || nm_i == 0); + MPASS(nm_i == kring->rhead); + kring->nr_hwcur = nm_i; - /* The pidx argument of isc_rxd_flush() is the index of the last valid - * slot in the free list ring. We need therefore to decrement nic_i, - * similarly to what happens in iflib_fl_refill() for ifl_pidx. */ bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id,