From owner-svn-src-all@freebsd.org Mon Oct 24 03:34:20 2016 Return-Path: Delivered-To: svn-src-all@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 A138DC1F536; Mon, 24 Oct 2016 03:34:20 +0000 (UTC) (envelope-from sephe@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 75DB8F9A; Mon, 24 Oct 2016 03:34:20 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9O3YJ81011371; Mon, 24 Oct 2016 03:34:19 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9O3YJk2011370; Mon, 24 Oct 2016 03:34:19 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201610240334.u9O3YJk2011370@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 03:34:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r307839 - head/sys/dev/hyperv/netvsc X-SVN-Group: head 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.23 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: Mon, 24 Oct 2016 03:34:20 -0000 Author: sephe Date: Mon Oct 24 03:34:19 2016 New Revision: 307839 URL: https://svnweb.freebsd.org/changeset/base/307839 Log: hyperv/hn: Fix chimney sending buffer leakage upon NVS sending failure. This will not happen in real world, since TX consumption of the vmbus TX bufring is limitted. Better safe than sorry. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8309 Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c ============================================================================== --- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 24 03:26:34 2016 (r307838) +++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c Mon Oct 24 03:34:19 2016 (r307839) @@ -951,6 +951,8 @@ hn_txdesc_dmamap_load(struct hn_tx_ring struct mbuf *m = *m_head; int error; + KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID, ("txd uses chim")); + error = bus_dmamap_load_mbuf_sg(txr->hn_tx_data_dtag, txd->data_dmap, m, segs, nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { @@ -974,19 +976,6 @@ hn_txdesc_dmamap_load(struct hn_tx_ring return error; } -static __inline void -hn_txdesc_dmamap_unload(struct hn_tx_ring *txr, struct hn_txdesc *txd) -{ - - if (txd->flags & HN_TXD_FLAG_DMAMAP) { - bus_dmamap_sync(txr->hn_tx_data_dtag, - txd->data_dmap, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(txr->hn_tx_data_dtag, - txd->data_dmap); - txd->flags &= ~HN_TXD_FLAG_DMAMAP; - } -} - static __inline int hn_txdesc_put(struct hn_tx_ring *txr, struct hn_txdesc *txd) { @@ -998,14 +987,25 @@ hn_txdesc_put(struct hn_tx_ring *txr, st if (atomic_fetchadd_int(&txd->refs, -1) != 1) return 0; - hn_txdesc_dmamap_unload(txr, txd); + if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) { + KASSERT((txd->flags & HN_TXD_FLAG_DMAMAP) == 0, + ("chim txd uses dmamap")); + hn_chim_free(txr->hn_sc, txd->chim_index); + txd->chim_index = HN_NVS_CHIM_IDX_INVALID; + } else if (txd->flags & HN_TXD_FLAG_DMAMAP) { + bus_dmamap_sync(txr->hn_tx_data_dtag, + txd->data_dmap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txr->hn_tx_data_dtag, + txd->data_dmap); + txd->flags &= ~HN_TXD_FLAG_DMAMAP; + } + if (txd->m != NULL) { m_freem(txd->m); txd->m = NULL; } txd->flags |= HN_TXD_FLAG_ONLIST; - #ifndef HN_USE_TXDESC_BUFRING mtx_lock_spin(&txr->hn_txlist_spin); KASSERT(txr->hn_txdesc_avail >= 0 && @@ -1046,7 +1046,9 @@ hn_txdesc_get(struct hn_tx_ring *txr) atomic_subtract_int(&txr->hn_txdesc_avail, 1); #endif KASSERT(txd->m == NULL && txd->refs == 0 && - (txd->flags & HN_TXD_FLAG_ONLIST), ("invalid txd")); + txd->chim_index == HN_NVS_CHIM_IDX_INVALID && + (txd->flags & HN_TXD_FLAG_ONLIST) && + (txd->flags & HN_TXD_FLAG_DMAMAP) == 0, ("invalid txd")); txd->flags &= ~HN_TXD_FLAG_ONLIST; txd->refs = 1; } @@ -1093,9 +1095,6 @@ hn_tx_done(struct hn_send_ctx *sndc, str struct hn_txdesc *txd = sndc->hn_cbarg; struct hn_tx_ring *txr; - if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) - hn_chim_free(sc, txd->chim_index); - txr = txd->txr; KASSERT(txr->hn_chan == chan, ("channel mismatch, on chan%u, should be chan%u", @@ -2820,6 +2819,7 @@ hn_create_tx_ring(struct hn_softc *sc, i struct hn_txdesc *txd = &txr->hn_txdesc[i]; txd->txr = txr; + txd->chim_index = HN_NVS_CHIM_IDX_INVALID; /* * Allocate and load RNDIS packet message.