Drivers: hv: vmbus: Introduce a function to remove a rescinded offer

In response to a rescind message, we need to remove the channel and the
corresponding device. Cleanup this code path by factoring out the code
to remove a channel.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
K. Y. Srinivasan
2015-02-28 11:18:17 -08:00
committed by Greg Kroah-Hartman
parent d15a0301c4
commit ed6cfcc5fd
4 changed files with 50 additions and 20 deletions

View File

@@ -207,33 +207,21 @@ static void percpu_channel_deq(void *arg)
list_del(&channel->percpu_list);
}
/*
* vmbus_process_rescind_offer -
* Rescind the offer by initiating a device removal
*/
static void vmbus_process_rescind_offer(struct work_struct *work)
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
{
struct vmbus_channel *channel = container_of(work,
struct vmbus_channel,
work);
struct vmbus_channel_relid_released msg;
unsigned long flags;
struct vmbus_channel *primary_channel;
struct vmbus_channel_relid_released msg;
struct device *dev;
if (channel->device_obj) {
dev = get_device(&channel->device_obj->device);
if (dev) {
vmbus_device_unregister(channel->device_obj);
put_device(dev);
}
}
memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
msg.child_relid = channel->offermsg.child_relid;
msg.child_relid = relid;
msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
if (channel == NULL)
return;
if (channel->target_cpu != get_cpu()) {
put_cpu();
smp_call_function_single(channel->target_cpu,
@@ -256,6 +244,29 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
free_channel(channel);
}
/*
* vmbus_process_rescind_offer -
* Rescind the offer by initiating a device removal
*/
static void vmbus_process_rescind_offer(struct work_struct *work)
{
struct vmbus_channel *channel = container_of(work,
struct vmbus_channel,
work);
struct device *dev;
if (channel->device_obj) {
dev = get_device(&channel->device_obj->device);
if (dev) {
vmbus_device_unregister(channel->device_obj);
put_device(dev);
}
} else {
hv_process_channel_removal(channel,
channel->offermsg.child_relid);
}
}
void vmbus_free_channels(void)
{
struct vmbus_channel *channel;