Skip to content

Commit

Permalink
Drivers: hv: vmbus: add an API vmbus_hvsock_device_unregister()
Browse files Browse the repository at this point in the history
The hvsock driver needs this API to release all the resources related
to the channel.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dexuan Cui authored and Greg Kroah-Hartman committed Feb 8, 2016
1 parent 499e840 commit 85d9aa7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
33 changes: 28 additions & 5 deletions drivers/hv/channel_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
vmbus_release_relid(relid);

BUG_ON(!channel->rescind);
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));

if (channel->target_cpu != get_cpu()) {
put_cpu();
Expand All @@ -321,9 +322,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
}

if (channel->primary_channel == NULL) {
mutex_lock(&vmbus_connection.channel_mutex);
list_del(&channel->listentry);
mutex_unlock(&vmbus_connection.channel_mutex);

primary_channel = channel;
} else {
Expand Down Expand Up @@ -367,6 +366,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
bool fnew = true;
unsigned long flags;
u16 dev_type;
int ret;

/* Make sure this is a new offer */
mutex_lock(&vmbus_connection.channel_mutex);
Expand Down Expand Up @@ -449,7 +449,11 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
* binding which eventually invokes the device driver's AddDevice()
* method.
*/
if (vmbus_device_register(newchannel->device_obj) != 0) {
mutex_lock(&vmbus_connection.channel_mutex);
ret = vmbus_device_register(newchannel->device_obj);
mutex_unlock(&vmbus_connection.channel_mutex);

if (ret != 0) {
pr_err("unable to add child device object (relid %d)\n",
newchannel->offermsg.child_relid);
kfree(newchannel->device_obj);
Expand Down Expand Up @@ -725,6 +729,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
struct device *dev;

rescind = (struct vmbus_channel_rescind_offer *)hdr;

mutex_lock(&vmbus_connection.channel_mutex);
channel = relid2channel(rescind->child_relid);

if (channel == NULL) {
Expand All @@ -733,7 +739,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
* vmbus_process_offer(), we have already invoked
* vmbus_release_relid() on error.
*/
return;
goto out;
}

spin_lock_irqsave(&channel->lock, flags);
Expand All @@ -743,7 +749,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
if (channel->device_obj) {
if (channel->chn_rescind_callback) {
channel->chn_rescind_callback(channel);
return;
goto out;
}
/*
* We will have to unregister this device from the
Expand All @@ -758,8 +764,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
hv_process_channel_removal(channel,
channel->offermsg.child_relid);
}

out:
mutex_unlock(&vmbus_connection.channel_mutex);
}

void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
{
mutex_lock(&vmbus_connection.channel_mutex);

BUG_ON(!is_hvsock_channel(channel));

channel->rescind = true;
vmbus_device_unregister(channel->device_obj);

mutex_unlock(&vmbus_connection.channel_mutex);
}
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);


/*
* vmbus_onoffers_delivered -
* This is invoked when all offers have been delivered.
Expand Down
4 changes: 2 additions & 2 deletions drivers/hv/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ struct vmbus_channel *relid2channel(u32 relid)
struct list_head *cur, *tmp;
struct vmbus_channel *cur_sc;

mutex_lock(&vmbus_connection.channel_mutex);
BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));

list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
if (channel->offermsg.child_relid == relid) {
found_channel = channel;
Expand All @@ -307,7 +308,6 @@ struct vmbus_channel *relid2channel(u32 relid)
}
}
}
mutex_unlock(&vmbus_connection.channel_mutex);

return found_channel;
}
Expand Down
2 changes: 2 additions & 0 deletions include/linux/hyperv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,8 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
const char *mod_name);
void vmbus_driver_unregister(struct hv_driver *hv_driver);

void vmbus_hvsock_device_unregister(struct vmbus_channel *channel);

int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
resource_size_t min, resource_size_t max,
resource_size_t size, resource_size_t align,
Expand Down

0 comments on commit 85d9aa7

Please sign in to comment.