Further cleanup reference counting of stor_device - when the device is being destroyed, we will permit incoming traffic only to drain outstanding requests. Signed-off-by: K. Y. Srinivasan <kys@xxxxxxxxxxxxx> Signed-off-by: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx> --- drivers/staging/hv/hyperv_storage.h | 3 +-- drivers/staging/hv/storvsc.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h index d946211..a1f3e27 100644 --- a/drivers/staging/hv/hyperv_storage.h +++ b/drivers/staging/hv/hyperv_storage.h @@ -287,7 +287,6 @@ struct storvsc_device { }; -/* Get the stordevice object iff exists and its refcount > 1 */ static inline struct storvsc_device *get_out_stor_device( struct hv_device *device) { @@ -296,7 +295,7 @@ static inline struct storvsc_device *get_out_stor_device( spin_lock_irqsave(&device->ext_lock, flags); stor_device = (struct storvsc_device *)device->ext; - if (stor_device && (stor_device->ref_count > 1) && + if (stor_device && (stor_device->ref_count) && !stor_device->destroy) stor_device->ref_count++; else diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index a41be2a..4d13044 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -40,9 +40,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) if (!stor_device) return NULL; - /* Set to 2 to allow both inbound and outbound traffics */ - /* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */ - stor_device->ref_count = 2; + stor_device->ref_count = 1; stor_device->destroy = false; init_waitqueue_head(&stor_device->waiting_to_drain); stor_device->device = device; @@ -51,8 +49,6 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) return stor_device; } - -/* Get the stordevice object iff exists and its refcount > 0 */ static inline struct storvsc_device *get_in_stor_device( struct hv_device *device) { @@ -61,10 +57,18 @@ static inline struct storvsc_device *get_in_stor_device( spin_lock_irqsave(&device->ext_lock, flags); stor_device = (struct storvsc_device *)device->ext; - if (stor_device && stor_device->ref_count) - stor_device->ref_count++; - else - stor_device = NULL; + if (!stor_device) + goto cleanup; + + /* + * If the device is being destroyed; allow incoming + * traffic only to cleanup outstanding requests. + */ + if (stor_device->destroy && + (atomic_read(&stor_device->num_outstanding_req) == 0)) + goto cleanup; + stor_device->ref_count++; +cleanup: spin_unlock_irqrestore(&device->ext_lock, flags); return stor_device; -- 1.7.4.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel