From owner-svn-src-head@FreeBSD.ORG Tue Apr 30 00:36:16 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id C2851F85; Tue, 30 Apr 2013 00:36:16 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id B4F301027; Tue, 30 Apr 2013 00:36:16 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3U0aGQ5065205; Tue, 30 Apr 2013 00:36:16 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3U0aG02065204; Tue, 30 Apr 2013 00:36:16 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201304300036.r3U0aG02065204@svn.freebsd.org> From: Neel Natu Date: Tue, 30 Apr 2013 00:36:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r250083 - head/usr.sbin/bhyve 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.14 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: Tue, 30 Apr 2013 00:36:16 -0000 Author: neel Date: Tue Apr 30 00:36:16 2013 New Revision: 250083 URL: http://svnweb.freebsd.org/changeset/base/250083 Log: Use a separate mutex for the receive path instead of overloading the softc mutex for this purpose. Reviewed by: grehan Modified: head/usr.sbin/bhyve/pci_virtio_net.c Modified: head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- head/usr.sbin/bhyve/pci_virtio_net.c Mon Apr 29 23:57:41 2013 (r250082) +++ head/usr.sbin/bhyve/pci_virtio_net.c Tue Apr 30 00:36:16 2013 (r250083) @@ -140,7 +140,6 @@ struct pci_vtnet_softc { int vsc_isr; int vsc_tapfd; int vsc_rx_ready; - int tx_in_progress; int resetting; uint32_t vsc_features; @@ -149,9 +148,14 @@ struct pci_vtnet_softc { uint64_t vsc_pfn[VTNET_MAXQ]; struct vring_hqueue vsc_hq[VTNET_MAXQ]; uint16_t vsc_msix_table_idx[VTNET_MAXQ]; + + pthread_mutex_t rx_mtx; + int rx_in_progress; + pthread_t tx_tid; pthread_mutex_t tx_mtx; pthread_cond_t tx_cond; + int tx_in_progress; }; #define vtnet_ctx(sc) ((sc)->vsc_pi->pi_vmctx) @@ -220,6 +224,38 @@ pci_vtnet_ring_reset(struct pci_vtnet_so hq->hq_cur_aidx = 0; } +/* + * If the transmit thread is active then stall until it is done. + */ +static void +pci_vtnet_txwait(struct pci_vtnet_softc *sc) +{ + + pthread_mutex_lock(&sc->tx_mtx); + while (sc->tx_in_progress) { + pthread_mutex_unlock(&sc->tx_mtx); + usleep(10000); + pthread_mutex_lock(&sc->tx_mtx); + } + pthread_mutex_unlock(&sc->tx_mtx); +} + +/* + * If the receive thread is active then stall until it is done. + */ +static void +pci_vtnet_rxwait(struct pci_vtnet_softc *sc) +{ + + pthread_mutex_lock(&sc->rx_mtx); + while (sc->rx_in_progress) { + pthread_mutex_unlock(&sc->rx_mtx); + usleep(10000); + pthread_mutex_lock(&sc->rx_mtx); + } + pthread_mutex_unlock(&sc->rx_mtx); +} + static void pci_vtnet_update_status(struct pci_vtnet_softc *sc, uint32_t value) { @@ -227,21 +263,19 @@ pci_vtnet_update_status(struct pci_vtnet if (value == 0) { DPRINTF(("vtnet: device reset requested !\n")); - /* Wait for TX thread to complete pending desc processing */ sc->resetting = 1; - pthread_mutex_lock(&sc->tx_mtx); - while (sc->tx_in_progress) { - pthread_mutex_unlock(&sc->tx_mtx); - usleep(10000); - pthread_mutex_lock(&sc->tx_mtx); - } - - pthread_mutex_unlock(&sc->tx_mtx); - + /* + * Wait for the transmit and receive threads to finish their + * processing. + */ + pci_vtnet_txwait(sc); + pci_vtnet_rxwait(sc); + + sc->vsc_rx_ready = 0; pci_vtnet_ring_reset(sc, VTNET_RXQ); pci_vtnet_ring_reset(sc, VTNET_TXQ); - sc->vsc_rx_ready = 0; + sc->resetting = 0; } @@ -303,9 +337,9 @@ pci_vtnet_tap_rx(struct pci_vtnet_softc /* * But, will be called when the rx ring hasn't yet - * been set up. + * been set up or the guest is resetting the device. */ - if (sc->vsc_rx_ready == 0) { + if (!sc->vsc_rx_ready || sc->resetting) { /* * Drop the packet and try later. */ @@ -393,9 +427,11 @@ pci_vtnet_tap_callback(int fd, enum ev_t { struct pci_vtnet_softc *sc = param; - pthread_mutex_lock(&sc->vsc_mtx); + pthread_mutex_lock(&sc->rx_mtx); + sc->rx_in_progress = 1; pci_vtnet_tap_rx(sc); - pthread_mutex_unlock(&sc->vsc_mtx); + sc->rx_in_progress = 0; + pthread_mutex_unlock(&sc->rx_mtx); } @@ -462,7 +498,6 @@ pci_vtnet_proctx(struct pci_vtnet_softc vu->vu_tlen = tlen; hq->hq_cur_aidx = aidx + 1; *hq->hq_used_idx = uidx + 1; - } static void @@ -706,21 +741,24 @@ pci_vtnet_init(struct vmctx *ctx, struct } pci_emul_alloc_bar(pi, 0, PCIBAR_IO, VTNET_REGSZ); - + + sc->resetting = 0; + + sc->rx_in_progress = 0; + pthread_mutex_init(&sc->rx_mtx, NULL); + /* * Initialize tx semaphore & spawn TX processing thread * As of now, only one thread for TX desc processing is * spawned. */ sc->tx_in_progress = 0; - sc->resetting = 0; pthread_mutex_init(&sc->tx_mtx, NULL); pthread_cond_init(&sc->tx_cond, NULL); pthread_create(&sc->tx_tid, NULL, pci_vtnet_tx_thread, (void *)sc); snprintf(tname, sizeof(tname), "%s vtnet%d tx", vmname, pi->pi_slot); pthread_set_name_np(sc->tx_tid, tname); - return (0); }