lkml.org 
[lkml]   [2016]   [Jan]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V2 11/13] Drivers: hv: vmbus: add an API vmbus_hvsock_device_unregister()
    Date
    From: Dexuan Cui <decui@microsoft.com>

    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>
    ---
    drivers/hv/channel_mgmt.c | 33 ++++++++++++++++++++++++++++-----
    drivers/hv/connection.c | 4 ++--
    include/linux/hyperv.h | 2 ++
    3 files changed, 32 insertions(+), 7 deletions(-)

    diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
    index 76864c9..cf311be 100644
    --- a/drivers/hv/channel_mgmt.c
    +++ b/drivers/hv/channel_mgmt.c
    @@ -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();
    @@ -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 {
    @@ -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);
    @@ -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);
    @@ -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) {
    @@ -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);
    @@ -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
    @@ -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.
    diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
    index 3dc5a9c..deb48e6 100644
    --- a/drivers/hv/connection.c
    +++ b/drivers/hv/connection.c
    @@ -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;
    @@ -307,7 +308,6 @@ struct vmbus_channel *relid2channel(u32 relid)
    }
    }
    }
    - mutex_unlock(&vmbus_connection.channel_mutex);

    return found_channel;
    }
    diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
    index 2e54e34..c056f05 100644
    --- a/include/linux/hyperv.h
    +++ b/include/linux/hyperv.h
    @@ -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,
    --
    1.7.4.1
    \
     
     \ /
      Last update: 2016-01-28 06:21    [W:4.285 / U:0.188 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site