Linux v3.10-9080-g19d2f8e

This commit is contained in:
Justin M. Forbes 2013-07-11 16:08:40 -05:00
parent bc78224ff8
commit 9c63d892b7
11 changed files with 57 additions and 355 deletions

View File

@ -1,159 +0,0 @@
From 9f00b2e7cf241fa389733d41b615efdaa2cb0f5b Mon Sep 17 00:00:00 2001
From: Cong Wang <amwang@redhat.com>
Date: Tue, 21 May 2013 21:52:55 +0000
Subject: bridge: only expire the mdb entry when query is received
Currently we arm the expire timer when the mdb entry is added,
however, this causes problem when there is no querier sent
out after that.
So we should only arm the timer when a corresponding query is
received, as suggested by Herbert.
And he also mentioned "if there is no querier then group
subscriptions shouldn't expire. There has to be at least one querier
in the network for this thing to work. Otherwise it just degenerates
into a non-snooping switch, which is OK."
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Adam Baker <linux@baker-net.org.uk>
Signed-off-by: Cong Wang <amwang@redhat.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
(limited to 'net/bridge')
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 2475147..40bda80 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -617,8 +617,6 @@ rehash:
mp->br = br;
mp->addr = *group;
- setup_timer(&mp->timer, br_multicast_group_expired,
- (unsigned long)mp);
hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
mdb->size++;
@@ -656,7 +654,6 @@ static int br_multicast_add_group(struct net_bridge *br,
struct net_bridge_mdb_entry *mp;
struct net_bridge_port_group *p;
struct net_bridge_port_group __rcu **pp;
- unsigned long now = jiffies;
int err;
spin_lock(&br->multicast_lock);
@@ -671,7 +668,6 @@ static int br_multicast_add_group(struct net_bridge *br,
if (!port) {
mp->mglist = true;
- mod_timer(&mp->timer, now + br->multicast_membership_interval);
goto out;
}
@@ -679,7 +675,7 @@ static int br_multicast_add_group(struct net_bridge *br,
(p = mlock_dereference(*pp, br)) != NULL;
pp = &p->next) {
if (p->port == port)
- goto found;
+ goto out;
if ((unsigned long)p->port < (unsigned long)port)
break;
}
@@ -690,8 +686,6 @@ static int br_multicast_add_group(struct net_bridge *br,
rcu_assign_pointer(*pp, p);
br_mdb_notify(br->dev, port, group, RTM_NEWMDB);
-found:
- mod_timer(&p->timer, now + br->multicast_membership_interval);
out:
err = 0;
@@ -1131,6 +1125,10 @@ static int br_ip4_multicast_query(struct net_bridge *br,
if (!mp)
goto out;
+ setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp);
+ mod_timer(&mp->timer, now + br->multicast_membership_interval);
+ mp->timer_armed = true;
+
max_delay *= br->multicast_last_member_count;
if (mp->mglist &&
@@ -1205,6 +1203,10 @@ static int br_ip6_multicast_query(struct net_bridge *br,
if (!mp)
goto out;
+ setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp);
+ mod_timer(&mp->timer, now + br->multicast_membership_interval);
+ mp->timer_armed = true;
+
max_delay *= br->multicast_last_member_count;
if (mp->mglist &&
(timer_pending(&mp->timer) ?
@@ -1263,7 +1265,7 @@ static void br_multicast_leave_group(struct net_bridge *br,
call_rcu_bh(&p->rcu, br_multicast_free_pg);
br_mdb_notify(br->dev, port, group, RTM_DELMDB);
- if (!mp->ports && !mp->mglist &&
+ if (!mp->ports && !mp->mglist && mp->timer_armed &&
netif_running(br->dev))
mod_timer(&mp->timer, jiffies);
}
@@ -1275,30 +1277,12 @@ static void br_multicast_leave_group(struct net_bridge *br,
br->multicast_last_member_interval;
if (!port) {
- if (mp->mglist &&
+ if (mp->mglist && mp->timer_armed &&
(timer_pending(&mp->timer) ?
time_after(mp->timer.expires, time) :
try_to_del_timer_sync(&mp->timer) >= 0)) {
mod_timer(&mp->timer, time);
}
-
- goto out;
- }
-
- for (p = mlock_dereference(mp->ports, br);
- p != NULL;
- p = mlock_dereference(p->next, br)) {
- if (p->port != port)
- continue;
-
- if (!hlist_unhashed(&p->mglist) &&
- (timer_pending(&p->timer) ?
- time_after(p->timer.expires, time) :
- try_to_del_timer_sync(&p->timer) >= 0)) {
- mod_timer(&p->timer, time);
- }
-
- break;
}
out:
@@ -1674,6 +1658,7 @@ void br_multicast_stop(struct net_bridge *br)
hlist_for_each_entry_safe(mp, n, &mdb->mhash[i],
hlist[ver]) {
del_timer(&mp->timer);
+ mp->timer_armed = false;
call_rcu_bh(&mp->rcu, br_multicast_free_group);
}
}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index e260710..1b0ac95 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -112,6 +112,7 @@ struct net_bridge_mdb_entry
struct timer_list timer;
struct br_ip addr;
bool mglist;
+ bool timer_armed;
};
struct net_bridge_mdb_htable
--
cgit v0.9.2

View File

@ -1,57 +0,0 @@
From 6b7df111ece130fa979a0c4f58e53674c1e47d3e Mon Sep 17 00:00:00 2001
From: Cong Wang <amwang@redhat.com>
Date: Tue, 21 May 2013 21:52:56 +0000
Subject: bridge: send query as soon as leave is received
Continue sending queries when leave is received if the user marks
it as a querier.
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Adam Baker <linux@baker-net.org.uk>
Signed-off-by: Cong Wang <amwang@redhat.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
(limited to 'net/bridge')
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 40bda80..37a4676 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1250,6 +1250,32 @@ static void br_multicast_leave_group(struct net_bridge *br,
if (!mp)
goto out;
+ if (br->multicast_querier &&
+ !timer_pending(&br->multicast_querier_timer)) {
+ __br_multicast_send_query(br, port, &mp->addr);
+
+ time = jiffies + br->multicast_last_member_count *
+ br->multicast_last_member_interval;
+ mod_timer(port ? &port->multicast_query_timer :
+ &br->multicast_query_timer, time);
+
+ for (p = mlock_dereference(mp->ports, br);
+ p != NULL;
+ p = mlock_dereference(p->next, br)) {
+ if (p->port != port)
+ continue;
+
+ if (!hlist_unhashed(&p->mglist) &&
+ (timer_pending(&p->timer) ?
+ time_after(p->timer.expires, time) :
+ try_to_del_timer_sync(&p->timer) >= 0)) {
+ mod_timer(&p->timer, time);
+ }
+
+ break;
+ }
+ }
+
if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) {
struct net_bridge_port_group __rcu **pp;
--
cgit v0.9.2

View File

@ -1,13 +0,0 @@
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index d6448e3..aadb596 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -269,7 +269,7 @@ static void br_multicast_del_pg(struct net_bridge *br,
del_timer(&p->timer);
call_rcu_bh(&p->rcu, br_multicast_free_pg);
- if (!mp->ports && !mp->mglist &&
+ if (!mp->ports && !mp->mglist && mp->timer_armed &&
netif_running(br->dev))
mod_timer(&mp->timer, jiffies);

View File

@ -73,3 +73,11 @@ CONFIG_MDIO_GPIO=m
# CONFIG_CRYPTO_TEST is not set
# CONFIG_TRANSPARENT_HUGEPAGE is not set
# CONFIG_XEN is not set
# FIX ME
# CONFIG_POWER_RESET_VEXPRESS is not set
# CONFIG_VEXPRESS_CONFIG is not set
# CONFIG_DRM_RCAR_DU is not set
# CONFIG_DRM_SHMOBILE is not set
# CONFIG_MMC_DW_SOCFPGA is not set
# CONFIG_ARM_SMMU is not set

View File

@ -240,6 +240,7 @@ CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_WORK=y
# CONFIG_JBD2_DEBUG is not set
# CONFIG_KVM is not set
CONFIG_LEDS_LP55XX_COMMON=m
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_LOCKD=y
@ -465,6 +466,7 @@ CONFIG_VIDEO_V4L2=m
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO=y
CONFIG_VIRTUALIZATION=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y

View File

@ -220,6 +220,8 @@ CONFIG_SPI_DESIGNWARE=m
CONFIG_SPI_TLE62X0=m
# CONFIG_SPI_FSL_SPI is not set
CONFIG_NFC_NCI_SPI=y
# HW crypto and rng
CONFIG_CRYPTO_SHA1_ARM=m
CONFIG_CRYPTO_AES_ARM=m
@ -455,3 +457,18 @@ CONFIG_BPF_JIT=y
# CONFIG_DEBUG_LL is not set
# CONFIG_DEBUG_PINCTRL is not set
# CONFIG_ARM_DT_BL_CPUFREQ is not set
# FIX ME
# CONFIG_FB_XILINX is not set
# CONFIG_DISPLAY_ENCODER_TFP410 is not set
# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set
# CONFIG_DISPLAY_CONNECTOR_DVI is not set
# CONFIG_DISPLAY_CONNECTOR_HDMI is not set
# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set
# CONFIG_DISPLAY_PANEL_DPI is not set
# CONFIG_DISPLAY_PANEL_DSI_CM is not set
# CONFIG_DISPLAY_PANEL_SONY_ACX565AKM is not set
# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set
# CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01 is not set
# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set
# CONFIG_DISPLAY_PANEL_NEC_NL8048HL11 is not set

View File

@ -1130,6 +1130,7 @@ CONFIG_BATMAN_ADV_NC=y
# CONFIG_BATMAN_ADV_DEBUG is not set
CONFIG_OPENVSWITCH=m
CONFIG_OPENVSWITCH_GRE=y
CONFIG_VSOCKETS=m
CONFIG_NETPRIO_CGROUP=m
@ -1163,6 +1164,7 @@ CONFIG_VXLAN=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_VETH=m
CONFIG_NLMON=m
#
# ATM
@ -1235,6 +1237,9 @@ CONFIG_PCNET32=m
CONFIG_AMD8111_ETH=m
CONFIG_PCMCIA_NMCLAN=m
CONFIG_NET_VENDOR_ARC=y
CONFIG_ARC_EMAC=m
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ALX=m
CONFIG_ATL2=m
@ -1369,6 +1374,8 @@ CONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not set
CONFIG_R8169=m
CONFIG_SH_ETH=m
CONFIG_NET_VENDOR_RDC=y
CONFIG_R6040=m
@ -1443,6 +1450,7 @@ CONFIG_VITESSE_PHY=m
CONFIG_MICREL_PHY=m
CONFIG_MII=m
CONFIG_NET_CORE=y
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
@ -1559,8 +1567,14 @@ CONFIG_ATH9K_HTC=m
CONFIG_ATH9K_BTCOEX_SUPPORT=y
# CONFIG_ATH9K_HTC_DEBUGFS is not set
# CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set
CONFIG_ATH10K=m
CONFIG_ATH10K_PCI=m
# CONFIG_ATH10K_DEBUG is not set
# CONFIG_ATH10K_TRACING is not set
CONFIG_ATH10K_DEBUGFS=y
CONFIG_WIL6210=m
CONFIG_WIL6210_ISR_COR=y
# CONFIG_WIL6210_TRACING is not set
CONFIG_CARL9170=m
CONFIG_CARL9170_LEDS=y
# CONFIG_CARL9170_HWRNG is not set
@ -1604,6 +1618,9 @@ CONFIG_PCMCIA_HERMES=m
CONFIG_ORINOCO_USB=m
# CONFIG_TMD_HERMES is not set
# CONFIG_PCMCIA_SPECTRUM is not set
CONFIG_CW1200=m
CONFIG_CW1200_WLAN_SDIO=m
CONFIG_CW1200_WLAN_SPI=m
# CONFIG_HOSTAP is not set
# CONFIG_IPW2100 is not set
# CONFIG_IPW2200 is not set
@ -1740,6 +1757,7 @@ CONFIG_NFC_NCI=m
CONFIG_NFC_HCI=m
CONFIG_NFC_SHDLC=y
CONFIG_NFC_LLCP=y
CONFIG_NFC_SIM=m
#
# Near Field Communication (NFC) devices
@ -3103,6 +3121,7 @@ CONFIG_SND_HDA_CODEC_CONEXANT=y
CONFIG_SND_HDA_CODEC_CMEDIA=y
CONFIG_SND_HDA_CODEC_SI3054=y
CONFIG_SND_HDA_CODEC_HDMI=y
CONFIG_SND_HDA_I915=y
CONFIG_SND_HDA_CODEC_CA0132=y
CONFIG_SND_HDA_CODEC_CA0132_DSP=y
CONFIG_SND_HDA_GENERIC=y
@ -3655,6 +3674,7 @@ CONFIG_MFD_VIPERBOARD=m
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_CS5535 is not set
# CONFIG_MFD_STMPE is not set
@ -3799,6 +3819,7 @@ CONFIG_UFS_FS=m
CONFIG_9P_FS=m
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_FUSE_FS=m
# CONFIG_OMFS_FS is not set
CONFIG_CUSE=m
@ -3817,11 +3838,11 @@ CONFIG_NFS_SWAP=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
CONFIG_NFS_V4_2=y
NFS_V4_SECURITY_LABEL=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
CONFIG_NFS_FSCACHE=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_PNFS_OBJLAYOUT=m
@ -4651,6 +4672,7 @@ CONFIG_IMA_LSM_RULES=y
# CONFIG_EVM is not set
# CONFIG_PWM is not set
# CONFIG_PWM_PCA9685 is not set
CONFIG_LSM_MMAP_MIN_ADDR=65536
@ -4681,6 +4703,7 @@ CONFIG_IEEE802154_FAKEHARD=m
CONFIG_IEEE802154_FAKELB=m
CONFIG_MAC802154=m
CONFIG_NET_MPLS_GSO=m
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
@ -4699,6 +4722,7 @@ CONFIG_PTP_1588_CLOCK_PCH=m
CONFIG_CLEANCACHE=y
CONFIG_FRONTSWAP=y
CONFIG_ZSWAP=y
# CONFIG_MDIO_GPIO is not set
# CONFIG_KEYBOARD_GPIO is not set

View File

@ -1,25 +0,0 @@
This triggers on a MacBook Pro.
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
https://bugzilla.redhat.com/show_bug.cgi?id=948262
---
drivers/iommu/intel_irq_remapping.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index f3b8f23..a7e0ad1 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -654,8 +654,7 @@ error:
*/
if (x2apic_present)
- WARN(1, KERN_WARNING
- "Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n");
+ pr_warn("Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n");
return -1;
}
--
1.8.1.4

View File

@ -95,7 +95,7 @@ Summary: The Linux kernel
# The rc snapshot level
%define rcrev 0
# The git snapshot level
%define gitrev 3
%define gitrev 6
# Set rpm version accordingly
%define rpmversion 3.%{upstream_sublevel}.0
%endif
@ -753,9 +753,6 @@ Patch22001: selinux-apply-different-permission-to-ptrace-child.patch
#rhbz 927469
Patch23006: fix-child-thread-introspection.patch
#rhbz 948262
Patch25024: intel_iommu-Downgrade-the-warning-if-enabling-irq-remapping-fails.patch
#CVE-2013-2140 rhbz 971146 971148
Patch25031: xen-blkback-Check-device-permissions-before-allowing.patch
@ -764,12 +761,6 @@ Patch25032: cve-2013-2147-ciss-info-leak.patch
Patch25047: drm-radeon-Disable-writeback-by-default-on-ppc.patch
#rhbz 880035
Patch25053: bridge-only-expire-the-mdb-entry-when-query-is-received.patch
Patch25054: bridge-send-query-as-soon-as-leave-is-received.patch
#rhbz 980254
Patch25061: bridge-timer-fix.patch
#rhbz 977558
Patch25055: ath3k-dont-use-stack-memory-for-DMA.patch
@ -777,9 +768,6 @@ Patch25055: ath3k-dont-use-stack-memory-for-DMA.patch
Patch25056: iwl3945-better-skb-management-in-rx-path.patch
Patch25057: iwl4965-better-skb-management-in-rx-path.patch
#rhbz 976789 980643
Patch25062: vhost-net-fix-use-after-free-in-vhost_net_flush.patch
# END OF PATCH DEFINITIONS
%endif
@ -1459,9 +1447,6 @@ ApplyPatch ath9k_rx_dma_stop_check.patch
#rhbz 927469
ApplyPatch fix-child-thread-introspection.patch
#rhbz 948262
ApplyPatch intel_iommu-Downgrade-the-warning-if-enabling-irq-remapping-fails.patch
#CVE-2013-2140 rhbz 971146 971148
ApplyPatch xen-blkback-Check-device-permissions-before-allowing.patch
@ -1470,11 +1455,6 @@ ApplyPatch cve-2013-2147-ciss-info-leak.patch
ApplyPatch drm-radeon-Disable-writeback-by-default-on-ppc.patch
#rhbz 880035
ApplyPatch bridge-only-expire-the-mdb-entry-when-query-is-received.patch
ApplyPatch bridge-send-query-as-soon-as-leave-is-received.patch
ApplyPatch bridge-timer-fix.patch
#rhbz 977558
ApplyPatch ath3k-dont-use-stack-memory-for-DMA.patch
@ -1482,9 +1462,6 @@ ApplyPatch ath3k-dont-use-stack-memory-for-DMA.patch
ApplyPatch iwl3945-better-skb-management-in-rx-path.patch
ApplyPatch iwl4965-better-skb-management-in-rx-path.patch
#rhbz 976789 980643
ApplyPatch vhost-net-fix-use-after-free-in-vhost_net_flush.patch
# END OF PATCH APPLICATIONS
%endif
@ -2281,6 +2258,9 @@ fi
# ||----w |
# || ||
%changelog
* Thu Jul 11 2013 Justin M. Forbes <jforbes@redhat.com> - 3.11.0-0.rc0.git6.1
- Linux v3.10-9080-g19d2f8e
* Thu Jul 11 2013 Kyle McMartin <kyle@redhat.com>
- Enable USB on Wandboard Duallite and other i.MX based boards, patch
from Niels de Vos.

View File

@ -1,2 +1,3 @@
4f25cd5bec5f8d5a7d935b3f2ccb8481 linux-3.10.tar.xz
bafe9ce838f3bc7e98307fdbb21e714b patch-3.10-git3.xz
a60aff8b30dcfe4942586d4115582dbd patch-3.10-git6.xz

View File

@ -1,76 +0,0 @@
Date: Tue, 25 Jun 2013 17:29:46 +0300
From: "Michael S. Tsirkin" <mst@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
Asias He <asias@redhat.com>, Jason Wang <jasowang@redhat.com>,
kvm@vger.kernel.org, virtualization@lists.linux-foundation.org,
netdev@vger.kernel.org
Subject: [PATCHv2] vhost-net: fix use-after-free in vhost_net_flush
Message-ID: <20130625142946.GA17414@redhat.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11
Sender: linux-kernel-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-kernel.vger.kernel.org>
X-Mailing-List: linux-kernel@vger.kernel.org
vhost_net_ubuf_put_and_wait has a confusing name:
it will actually also free it's argument.
Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01
"vhost-net: flush outstanding DMAs on memory change"
vhost_net_flush tries to use the argument after passing it
to vhost_net_ubuf_put_and_wait, this results
in use after free.
To fix, don't free the argument in vhost_net_ubuf_put_and_wait,
add an new API for callers that want to free ubufs.
Acked-by: Asias He <asias@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
Please review, and queue for 3.10 and stable.
Changes since v1:
- no functional change, tweaked the commit message
drivers/vhost/net.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 5c77d6a..534adb0 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -149,6 +149,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
{
kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
+}
+
+static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs)
+{
+ vhost_net_ubuf_put_and_wait(ubufs);
kfree(ubufs);
}
@@ -1073,7 +1078,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
mutex_unlock(&vq->mutex);
if (oldubufs) {
- vhost_net_ubuf_put_and_wait(oldubufs);
+ vhost_net_ubuf_put_wait_and_free(oldubufs);
mutex_lock(&vq->mutex);
vhost_zerocopy_signal_used(n, vq);
mutex_unlock(&vq->mutex);
@@ -1091,7 +1096,7 @@ err_used:
vq->private_data = oldsock;
vhost_net_enable_vq(n, vq);
if (ubufs)
- vhost_net_ubuf_put_and_wait(ubufs);
+ vhost_net_ubuf_put_wait_and_free(ubufs);
err_ubufs:
fput(sock->file);
err_vq: