From owner-svn-src-stable-12@freebsd.org Wed Jun 10 20:02:39 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 6EF1933E3EA; Wed, 10 Jun 2020 20:02:39 +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 49hyZl2FDsz4VPM; Wed, 10 Jun 2020 20:02:39 +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 2FB11C2FB; Wed, 10 Jun 2020 20:02:39 +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 05AK2ddu031515; Wed, 10 Jun 2020 20:02:39 GMT (envelope-from vmaffione@FreeBSD.org) Received: (from vmaffione@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05AK2dMV031514; Wed, 10 Jun 2020 20:02:39 GMT (envelope-from vmaffione@FreeBSD.org) Message-Id: <202006102002.05AK2dMV031514@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: vmaffione set sender to vmaffione@FreeBSD.org using -f From: Vincenzo Maffione Date: Wed, 10 Jun 2020 20:02:39 +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: r362022 - stable/12/sys/dev/virtio/network X-SVN-Group: stable-12 X-SVN-Commit-Author: vmaffione X-SVN-Commit-Paths: stable/12/sys/dev/virtio/network X-SVN-Commit-Revision: 362022 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: Wed, 10 Jun 2020 20:02:39 -0000 Author: vmaffione Date: Wed Jun 10 20:02:38 2020 New Revision: 362022 URL: https://svnweb.freebsd.org/changeset/base/362022 Log: MFC r361745 netmap: vtnet: call netmap_rx_irq() under VQ lock The netmap_rx_irq() function normally wakes up user-space threads waiting for more packets. In this case, it is not necessary to call it under the driver queue lock. However, if the interface is attached to a VALE switch, netmap_rx_irq() ends up calling rxsync on the interface (see netmap_bwrap_intr_notify()). Although concurrent rxsyncs are serialized through the kring lock (see nm_kr_tryget()), the lock acquire operation is not blocking. As a result, it may happen that netmap_rx_irq() is called on an RX ring while another instance is running, causing the second call to fail, and received packets stall in the receive VQ. We fix this issue by calling netmap_irx_irq() under the VQ lock. Modified: stable/12/sys/dev/virtio/network/if_vtnet.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/virtio/network/if_vtnet.c ============================================================================== --- stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jun 10 19:59:11 2020 (r362021) +++ stable/12/sys/dev/virtio/network/if_vtnet.c Wed Jun 10 20:02:38 2020 (r362022) @@ -1873,9 +1873,20 @@ vtnet_rx_vq_intr(void *xrxq) return; } + VTNET_RXQ_LOCK(rxq); + #ifdef DEV_NETMAP + /* + * We call netmap_rx_irq() under lock to prevent concurrent calls. + * This is not necessary to serialize the access to the RX vq, but + * rather to avoid races that may happen if this interface is + * attached to a VALE switch, which would cause received packets + * to stall in the RX queue (nm_kr_tryget() could find the kring + * busy when called from netmap_bwrap_intr_notify()). + */ nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, &more); if (nmirq != NM_IRQ_PASS) { + VTNET_RXQ_UNLOCK(rxq); if (nmirq == NM_IRQ_RESCHED) { taskqueue_enqueue(rxq->vtnrx_tq, &rxq->vtnrx_intrtask); } @@ -1883,8 +1894,6 @@ vtnet_rx_vq_intr(void *xrxq) } #endif /* DEV_NETMAP */ - VTNET_RXQ_LOCK(rxq); - again: if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq); @@ -1924,17 +1933,18 @@ vtnet_rxq_tq_intr(void *xrxq, int pending) sc = rxq->vtnrx_sc; ifp = sc->vtnet_ifp; + VTNET_RXQ_LOCK(rxq); + #ifdef DEV_NETMAP nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, &more); if (nmirq != NM_IRQ_PASS) { + VTNET_RXQ_UNLOCK(rxq); if (nmirq == NM_IRQ_RESCHED) { taskqueue_enqueue(rxq->vtnrx_tq, &rxq->vtnrx_intrtask); } return; } #endif /* DEV_NETMAP */ - - VTNET_RXQ_LOCK(rxq); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { VTNET_RXQ_UNLOCK(rxq);