Patch "[PATCH 041/135] Drivers: hv: vmbus: fix rescind-offer handling for" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
[PATCH 041/135] Drivers: hv: vmbus: fix rescind-offer handling for
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
0041-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
a62048110b92194ad40236f5fd728942d9994565Mon Sep 17 00:00:00 2001
From: Dexuan Cui <[email protected]>
Date: Mon, 14 Dec 2015 16:01:49 -0800
Subject: [PATCH 041/135] Drivers: hv: vmbus: fix rescind-offer handling for
device without a driver
[ Upstream commit 34c6801e3310ad286c7bb42bc88d42926b8f99bf ]
In the path vmbus_onoffer_rescind() -> vmbus_device_unregister() -> device_unregister() -> ... -> __device_release_driver(), we can see for a device without a driver loaded: dev->driver is NULL, so dev->bus->remove(dev), namely vmbus_remove(), isn't invoked.
As a result, vmbus_remove() -> hv_process_channel_removal() isn't invoked and some cleanups(like sending a CHANNELMSG_RELID_RELEASED message to the host) aren't done.
We can demo the issue this way:
1. rmmod hv_utils;
2. disable the Heartbeat Integration Service in Hyper-V Manager and lsvmbus shows the device disappears.
3. re-enable the Heartbeat in Hyper-V Manager and modprobe hv_utils, but lsvmbus shows the device can't appear again.
This is because, the host thinks the VM hasn't released the relid, so can't re-offer the device to the VM.
We can fix the issue by moving hv_process_channel_removal() from vmbus_close_internal() to vmbus_device_release(), since the latter is always invoked on device_unregister(), whether or not the dev has a driver loaded.
--- drivers/hv/channel.c | 6 ------ drivers/hv/channel_mgmt.c | 6 +++--- drivers/hv/vmbus_drv.c | 15 +++------------ 3 files changed, 6 insertions(+), 21 deletions(-)
drivers/hv/channel.c +0 -6
@@ -563,12 +563,6 @@ static int vmbus_close_internal(struct vfree_pages ((unsigned long )channel->ringbuffer_pages,get_order (channel->ringbuffer_pagecount *PAGE_SIZE )); -/* -* If the channel has been rescinded; process device removal. -*/ -if (channel->rescind) -hv_process_channel_removal (channel, - channel->offermsg.child_relid); out:tasklet_enable (tasklet);
drivers/hv/channel_mgmt.c +3 -3
@@ -191,6 +191,8 @@ void hv_process_channel_removal(struct vif (channel ==NULL )return ; +BUG_ON (!channel->rescind); +if (channel->target_cpu !=get_cpu ()) {put_cpu (); smp_call_function_single(channel->target_cpu,
@@ -230,9 +232,7 @@ void vmbus_free_channels(void)list_for_each_entry_safe (channel, tmp, &vmbus_connection.chn_list, listentry) { -/* if we don't set rescind to true, vmbus_close_internal() -* won't invoke hv_process_channel_removal(). -*/ +/* hv_process_channel_removal() needs this */ channel->rescind = true;vmbus_device_unregister (channel->device_obj);
drivers/hv/vmbus_drv.c +3 -12
@@ -603,23 +603,11 @@ static int vmbus_remove(struct device *c {struct hv_driver *drv;struct hv_device *dev =device_to_hv_device (child_device); -u32 relid = dev->channel->offermsg.child_relid;if (child_device->driver) { drv =drv_to_hv_drv (child_device->driver);if (drv->remove) drv->remove (dev); -else { -hv_process_channel_removal (dev->channel, relid); -pr_err ("remove not set for driver %s\n" , -dev_name (child_device)); - } - }else { -/* -* We don't have a driver for this device; deal with the -* rescind message by removing the channel. -*/ -hv_process_channel_removal (dev->channel, relid); }return 0 ;
@@ -654,7 +642,10 @@ static void vmbus_shutdown(struct devicestatic void vmbus_device_release (struct device *device) {struct hv_device *hv_dev =device_to_hv_device (device); +struct vmbus_channel *channel = hv_dev->channel; +hv_process_channel_removal (channel, + channel->offermsg.child_relid);kfree (hv_dev); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/0118-clocksource-Allow-unregistering-the-watchdog.patch queue-4.4/0041-Drivers-hv-vmbus-fix-rescind-offer-handling-for-devi.patch queue-4.4/0040-Drivers-hv-vmbus-serialize-process_chn_event-and-vmb.patch