K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 01/46] Staging: hv: storvsc: Inline free_stor_device()
Inline the code for free_stor_device() and get rid of the function. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc.c | 8 ++------ 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 827b6a3..8c62829 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -51,10 +51,6 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) return stor_device; } -static inline void free_stor_device(struct storvsc_device *device) -{ - kfree(device); -} /* Get the stordevice object iff exists and its refcount > 0 */ static inline struct storvsc_device *must_get_stor_device( @@ -394,7 +390,7 @@ int storvsc_dev_add(struct hv_device *device, /* Send it back up */ ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size); if (ret) { - free_stor_device(stor_device); + kfree(stor_device); return ret; } device_info->path_id = stor_device->path_id; @@ -422,7 +418,7 @@ int storvsc_dev_remove(struct hv_device *device) /* Close the channel */ vmbus_close(device->channel); - free_stor_device(stor_device); + kfree(stor_device); return 0; } -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 02/46] Staging: hv: storvsc: Do not aquire an unnecessary reference on stor_device
On entry into storvsc_on_io_completion() we have already acquired a reference on the stor_device; there is no need to acquire an additional reference here. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 8c62829..cd38cd6 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -232,9 +232,7 @@ static void storvsc_on_io_completion(struct hv_device *device, struct storvsc_device *stor_device; struct vstor_packet *stor_pkt; - stor_device = must_get_stor_device(device); - if (!stor_device) - return; + stor_device = (struct storvsc_device *)device->ext; stor_pkt = &request->vstor_packet; @@ -279,7 +277,6 @@ static void storvsc_on_io_completion(struct hv_device *device, wake_up(&stor_device->waiting_to_drain); - put_stor_device(device); } static void storvsc_on_receive(struct hv_device *device, -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 03/46] Staging: hv: storvsc: Rename must_get_stor_device()
In preparation for cleaning up how we manage reference counts on the stor device, clearly distinguish why we are attempting to acquire a reference. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index cd38cd6..89708b1 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -41,7 +41,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) return NULL; /* Set to 2 to allow both inbound and outbound traffics */ - /* (ie get_stor_device() and must_get_stor_device()) to proceed. */ + /* (ie get_stor_device() and get_in_stor_device()) to proceed. */ atomic_cmpxchg(&stor_device->ref_count, 0, 2); init_waitqueue_head(&stor_device->waiting_to_drain); @@ -53,7 +53,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) /* Get the stordevice object iff exists and its refcount > 0 */ -static inline struct storvsc_device *must_get_stor_device( +static inline struct storvsc_device *get_in_stor_device( struct hv_device *device) { struct storvsc_device *stor_device; @@ -305,7 +305,7 @@ static void storvsc_on_channel_callback(void *context) int ret; - stor_device = must_get_stor_device(device); + stor_device = get_in_stor_device(device); if (!stor_device) return; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 04/46] Staging: hv: storvsc: Rename get_stor_device()
In preparation for cleaning up how we manage reference counts on the stor device, clearly distinguish why we are attempting to acquire a reference. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hyperv_storage.h | 3 ++- drivers/staging/hv/storvsc.c | 8 ++++---- drivers/staging/hv/storvsc_drv.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h index a01f9a0..a224413 100644 --- a/drivers/staging/hv/hyperv_storage.h +++ b/drivers/staging/hv/hyperv_storage.h @@ -288,7 +288,8 @@ struct storvsc_device { /* Get the stordevice object iff exists and its refcount > 1 */ -static inline struct storvsc_device *get_stor_device(struct hv_device *device) +static inline struct storvsc_device *get_out_stor_device( + struct hv_device *device) { struct storvsc_device *stor_device; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 89708b1..313a3f8 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -41,7 +41,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) return NULL; /* Set to 2 to allow both inbound and outbound traffics */ - /* (ie get_stor_device() and get_in_stor_device()) to proceed. */ + /* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */ atomic_cmpxchg(&stor_device->ref_count, 0, 2); init_waitqueue_head(&stor_device->waiting_to_drain); @@ -67,7 +67,7 @@ static inline struct storvsc_device *get_in_stor_device( return stor_device; } -/* Drop ref count to 1 to effectively disable get_stor_device() */ +/* Drop ref count to 1 to effectively disable get_out_stor_device() */ static inline struct storvsc_device *release_stor_device( struct hv_device *device) { @@ -105,7 +105,7 @@ static int storvsc_channel_init(struct hv_device *device) struct vstor_packet *vstor_packet; int ret, t; - stor_device = get_stor_device(device); + stor_device = get_out_stor_device(device); if (!stor_device) return -ENODEV; @@ -427,7 +427,7 @@ int storvsc_do_io(struct hv_device *device, int ret = 0; vstor_packet = &request->vstor_packet; - stor_device = get_stor_device(device); + stor_device = get_out_stor_device(device); if (!stor_device) return -ENODEV; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index faa8d57..5b2004f 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -344,7 +344,7 @@ static int storvsc_host_reset(struct hv_device *device) int ret, t; - stor_device = get_stor_device(device); + stor_device = get_out_stor_device(device); if (!stor_device) return -ENODEV; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 05/46] Staging: hv: storvsc: Cleanup alloc_stor_device()
Cleanup alloc_stor_device(), we can set the ref_count directly. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 313a3f8..48bd8da 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -42,7 +42,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) /* Set to 2 to allow both inbound and outbound traffics */ /* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */ - atomic_cmpxchg(&stor_device->ref_count, 0, 2); + atomic_set(&stor_device->ref_count, 2); init_waitqueue_head(&stor_device->waiting_to_drain); stor_device->device = device; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 06/46] Staging: hv: storvsc: Introduce state to manage the lifecycle of stor device
Introduce state to manage the lifecycle of stor device. This would be the basis for managing the references on the stor object. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hyperv_storage.h | 2 +- drivers/staging/hv/storvsc.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h index a224413..d93bf93 100644 --- a/drivers/staging/hv/hyperv_storage.h +++ b/drivers/staging/hv/hyperv_storage.h @@ -266,7 +266,7 @@ struct storvsc_device { /* 0 indicates the device is being destroyed */ atomic_t ref_count; - + bool destroy; bool drain_notify; atomic_t num_outstanding_req; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 48bd8da..0f8c609 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -43,7 +43,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) /* Set to 2 to allow both inbound and outbound traffics */ /* (ie get_out_stor_device() and get_in_stor_device()) to proceed. */ atomic_set(&stor_device->ref_count, 2); - + stor_device->destroy = false; init_waitqueue_head(&stor_device->waiting_to_drain); stor_device->device = device; device->ext = stor_device; @@ -399,9 +399,15 @@ int storvsc_dev_add(struct hv_device *device, int storvsc_dev_remove(struct hv_device *device) { struct storvsc_device *stor_device; + unsigned long flags; + stor_device = release_stor_device(device); + spin_lock_irqsave(&device->channel->inbound_lock, flags); + stor_device->destroy = true; + spin_unlock_irqrestore(&device->channel->inbound_lock, flags); + /* * At this point, all outbound traffic should be disable. We * only allow inbound traffic (responses) to proceed so that -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 07/46] Staging: hv: storvsc: Prevent outgoing traffic when stor dev is being destroyed
Prevent outgoing traffic when stor dev is destroyed. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hyperv_storage.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h index d93bf93..1a59ca0 100644 --- a/drivers/staging/hv/hyperv_storage.h +++ b/drivers/staging/hv/hyperv_storage.h @@ -294,7 +294,8 @@ static inline struct storvsc_device *get_out_stor_device( struct storvsc_device *stor_device; stor_device = (struct storvsc_device *)device->ext; - if (stor_device && atomic_read(&stor_device->ref_count) > 1) + if (stor_device && (atomic_read(&stor_device->ref_count) > 1) && + !stor_device->destroy) atomic_inc(&stor_device->ref_count); else stor_device = NULL; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 08/46] Staging: hv: storvsc: Get rid of release_stor_device() by inlining the code
Get rid of release_stor_device() by inlining the code. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc.c | 19 ++----------------- 1 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 0f8c609..1976a34 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -67,21 +67,6 @@ static inline struct storvsc_device *get_in_stor_device( return stor_device; } -/* Drop ref count to 1 to effectively disable get_out_stor_device() */ -static inline struct storvsc_device *release_stor_device( - struct hv_device *device) -{ - struct storvsc_device *stor_device; - - stor_device = (struct storvsc_device *)device->ext; - - /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&stor_device->ref_count, 2, 1) != 2) - udelay(100); - - return stor_device; -} - /* Drop ref count to 0. No one can use stor_device object. */ static inline struct storvsc_device *final_release_stor_device( struct hv_device *device) @@ -401,8 +386,8 @@ int storvsc_dev_remove(struct hv_device *device) struct storvsc_device *stor_device; unsigned long flags; - - stor_device = release_stor_device(device); + stor_device = (struct storvsc_device *)device->ext; + atomic_dec(&stor_device->ref_count); spin_lock_irqsave(&device->channel->inbound_lock, flags); stor_device->destroy = true; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 11/46] Staging: hv: netvsc: Inline the code for free_net_device()
Inline the code for free_net_device(). Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/netvsc.c | 12 ++---------- 1 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index b6e1fb9..75c6ed7 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -49,14 +49,6 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) return net_device; } -static void free_net_device(struct netvsc_device *device) -{ - WARN_ON(atomic_read(&device->refcnt) != 0); - device->dev->ext = NULL; - kfree(device); -} - - /* Get the net device object iff exists and its refcount > 1 */ static struct netvsc_device *get_outbound_net_device(struct hv_device *device) { @@ -438,7 +430,7 @@ int netvsc_device_remove(struct hv_device *device) kfree(netvsc_packet); } - free_net_device(net_device); + kfree(net_device); return 0; } @@ -980,7 +972,7 @@ cleanup: release_outbound_net_device(device); release_inbound_net_device(device); - free_net_device(net_device); + kfree(net_device); } return ret; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 12/46] Staging: hv: netvsc: Cleanup alloc_net_device()
Cleanup alloc_net_device(); we can directly set the refcnt. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/netvsc.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 75c6ed7..7722102 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -41,7 +41,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) return NULL; /* Set to 2 to allow both inbound and outbound traffic */ - atomic_cmpxchg(&net_device->refcnt, 0, 2); + atomic_set(&net_device->refcnt, 2); net_device->dev = device; device->ext = net_device; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 13/46] Staging: hv: netvsc: Introduce state to manage the lifecycle of net device
Introduce state to manage the lifecycle of net device. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hyperv_net.h | 1 + drivers/staging/hv/netvsc.c | 6 ++++++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h index 5782fea..0b347c1 100644 --- a/drivers/staging/hv/hyperv_net.h +++ b/drivers/staging/hv/hyperv_net.h @@ -371,6 +371,7 @@ struct netvsc_device { atomic_t refcnt; atomic_t num_outstanding_sends; + bool destroy; /* * List of free preallocated hv_netvsc_packet to represent receive * packet diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 7722102..8eb4039 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -43,6 +43,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) /* Set to 2 to allow both inbound and outbound traffic */ atomic_set(&net_device->refcnt, 2); + net_device->destroy = false; net_device->dev = device; device->ext = net_device; @@ -396,6 +397,7 @@ int netvsc_device_remove(struct hv_device *device) { struct netvsc_device *net_device; struct hv_netvsc_packet *netvsc_packet, *pos; + unsigned long flags; /* Stop outbound traffic ie sends and receives completions */ net_device = release_outbound_net_device(device); @@ -404,6 +406,10 @@ int netvsc_device_remove(struct hv_device *device) return -ENODEV; } + spin_lock_irqsave(&device->channel->inbound_lock, flags); + net_device->destroy = true; + spin_unlock_irqrestore(&device->channel->inbound_lock, flags); + /* Wait for all send completions */ while (atomic_read(&net_device->num_outstanding_sends)) { dev_err(&device->device, -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 14/46] Staging: hv: netvsc: Prevent outgoing traffic when netvsc dev is destroyed
Prevent outgoing traffic when netvsc dev is destroyed. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/netvsc.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 8eb4039..67065c1 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -56,7 +56,8 @@ static struct netvsc_device *get_outbound_net_device(struct hv_device *device) struct netvsc_device *net_device; net_device = device->ext; - if (net_device && atomic_read(&net_device->refcnt) > 1) + if (net_device && (atomic_read(&net_device->refcnt) > 1) && + !net_device->destroy) atomic_inc(&net_device->refcnt); else net_device = NULL; -- 1.7.4.1
Further cleanup of the hv drivers. 1) Cleanup reference counting. 2) Handle all block devices using the storvsc driver. I have modified the implementation here based on Christoph's feedback on my earlier implementation. 3) Fix bugs. 4) Accomodate some host side scsi emulation bugs. 5) In case of scsi errors off-line the device. This patch-set further reduces the size of Hyper-V drivers - the code is about 10% smaller. This reduction is mainly because we have eliminated the blkvsc driver. Regards, K. Y
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 16/46] Staging: hv: netvsc: Get rid of release_inbound_net_device() by inlining the code
Get rid of release_inbound_net_device() by inlining the code. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/netvsc.c | 24 ++---------------------- 1 files changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index e46161d..388f083 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -88,23 +88,6 @@ static void put_net_device(struct hv_device *device) atomic_dec(&net_device->refcnt); } -static struct netvsc_device *release_inbound_net_device( - struct hv_device *device) -{ - struct netvsc_device *net_device; - - net_device = device->ext; - if (net_device == NULL) - return NULL; - - /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&net_device->refcnt, 1, 0) != 1) - udelay(100); - - device->ext = NULL; - return net_device; -} - static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) { struct nvsp_message *revoke_packet; @@ -400,9 +383,8 @@ int netvsc_device_remove(struct hv_device *device) netvsc_disconnect_vsp(net_device); - /* Stop inbound traffic ie receives and sends completions */ - net_device = release_inbound_net_device(device); - + atomic_dec(&net_device->refcnt); + device->ext = NULL; /* * Wait until the ref cnt falls to 0. * We have already stopped any new references @@ -967,8 +949,6 @@ cleanup: kfree(packet); } - release_inbound_net_device(device); - kfree(net_device); } -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 18/46] Staging: hv: storvsc: Add code to handle IDE devices using the storvsc driver
Add code to handle IDE devices using the storvsc driver. The storvsc_probe() is modified so that the storvsc driver can surface all disks presented to the guest as scsi devices using generic upper level Linux scsi drivers. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 60 ++++++++++++++++++++++++++++++++----- 1 files changed, 52 insertions(+), 8 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index ae74f50..f434200 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -59,6 +59,17 @@ struct storvsc_cmd_request { struct hv_storvsc_request request; }; +static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path) +{ + *target + dev->dev_instance.b[5] << 8 | dev->dev_instance.b[4]; + + *path + dev->dev_instance.b[3] << 24 | + dev->dev_instance.b[2] << 16 | + dev->dev_instance.b[1] << 8 | dev->dev_instance.b[0]; +} + static int storvsc_device_alloc(struct scsi_device *sdevice) { @@ -642,6 +653,20 @@ static const struct hv_vmbus_device_id id_table[] = { }; MODULE_DEVICE_TABLE(vmbus, id_table); + +/* + * This declaration is temporary; once we get the + * infrastructure in place, we will integrate with + * id_table. + */ + +static const uuid_le ide_blk_guid = { + .b = { + 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 + } +}; + /* * storvsc_probe - Add a new device for this driver */ @@ -652,6 +677,14 @@ static int storvsc_probe(struct hv_device *device) struct Scsi_Host *host; struct hv_host_device *host_dev; struct storvsc_device_info device_info; + bool dev_is_ide; + int path = 0; + int target = 0; + + if (!uuid_le_cmp(device->dev_type, ide_blk_guid)) + dev_is_ide = true; + else + dev_is_ide = false; host = scsi_host_alloc(&scsi_driver, sizeof(struct hv_host_device)); @@ -687,6 +720,9 @@ static int storvsc_probe(struct hv_device *device) return -ENODEV; } + if (dev_is_ide) + storvsc_get_ide_info(device, &target, &path); + host_dev->path = device_info.path_id; host_dev->target = device_info.target_id; @@ -699,17 +735,25 @@ static int storvsc_probe(struct hv_device *device) /* Register the HBA and start the scsi bus scan */ ret = scsi_add_host(host, &device->device); - if (ret != 0) { - - storvsc_dev_remove(device); + if (ret != 0) + goto err_out; - kmem_cache_destroy(host_dev->request_pool); - scsi_host_put(host); - return -ENODEV; + if (!dev_is_ide) { + scsi_scan_host(host); + return 0; + } + ret = scsi_add_device(host, 0, target, 0); + if (ret) { + scsi_remove_host(host); + goto err_out; } + return 0; - scsi_scan_host(host); - return ret; +err_out: + storvsc_dev_remove(device); + kmem_cache_destroy(host_dev->request_pool); + scsi_host_put(host); + return -ENODEV; } /* The one and only one */ -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 19/46] Staging: hv: storvsc: Handle IDE devices using the storvsc driver
Now, enable handling of all IDE devices by extending the storvsc device id table to handle IDE guid. As part of this cleanup Kconfig and Hyper-V Makefile to not build the IDE driver (blkvsc). Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/Kconfig | 7 ------- drivers/staging/hv/Makefile | 2 -- drivers/staging/hv/storvsc_drv.c | 21 ++++++++------------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 5e0c9f6..26b5064 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -15,13 +15,6 @@ config HYPERV_STORAGE help Select this option to enable the Hyper-V virtual storage driver. -config HYPERV_BLOCK - tristate "Microsoft Hyper-V virtual block driver" - depends on BLOCK && SCSI && (LBDAF || 64BIT) - default HYPERV - help - Select this option to enable the Hyper-V virtual block driver. - config HYPERV_NET tristate "Microsoft Hyper-V virtual network driver" depends on NET diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 3004674..bb89437 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -1,6 +1,5 @@ obj-$(CONFIG_HYPERV) += hv_vmbus.o hv_timesource.o obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o -obj-$(CONFIG_HYPERV_BLOCK) += hv_blkvsc.o obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o @@ -9,6 +8,5 @@ hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o hv_storvsc-y := storvsc_drv.o storvsc.o -hv_blkvsc-y := blkvsc_drv.o storvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o hv_utils-y := hv_util.o hv_kvp.o diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index f434200..9464f99 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -645,27 +645,22 @@ static struct scsi_host_template scsi_driver = { .dma_boundary = PAGE_SIZE-1, }; +/* + * The storvsc_probe function assumes that the IDE guid + * is the second entry. + */ static const struct hv_vmbus_device_id id_table[] = { /* SCSI guid */ { VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) }, + /* IDE guid */ + { VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) }, { }, }; MODULE_DEVICE_TABLE(vmbus, id_table); -/* - * This declaration is temporary; once we get the - * infrastructure in place, we will integrate with - * id_table. - */ - -static const uuid_le ide_blk_guid = { - .b = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } -}; /* * storvsc_probe - Add a new device for this driver @@ -681,7 +676,7 @@ static int storvsc_probe(struct hv_device *device) int path = 0; int target = 0; - if (!uuid_le_cmp(device->dev_type, ide_blk_guid)) + if (!memcmp(&device->dev_type.b, id_table[1].guid, sizeof(uuid_le))) dev_is_ide = true; else dev_is_ide = false; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 21/46] Staging: hv: storvsc: Optimize bounce buffer handling for the "write" case
Optimize bounce buffer handling for the "write" case. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 9464f99..90b91ad 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -425,17 +425,17 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) struct scsi_sense_hdr sense_hdr; struct vmscsi_request *vm_srb; + vm_srb = &request->vstor_packet.vm_srb; if (cmd_request->bounce_sgl_count) { - - /* FIXME: We can optimize on writes by just skipping this */ - copy_from_bounce_buffer(scsi_sglist(scmnd), + if (vm_srb->data_in == READ_TYPE) { + copy_from_bounce_buffer(scsi_sglist(scmnd), cmd_request->bounce_sgl, scsi_sg_count(scmnd)); - destroy_bounce_buffer(cmd_request->bounce_sgl, - cmd_request->bounce_sgl_count); + destroy_bounce_buffer(cmd_request->bounce_sgl, + cmd_request->bounce_sgl_count); + } } - vm_srb = &request->vstor_packet.vm_srb; scmnd->result = vm_srb->scsi_status; if (scmnd->result) { -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 22/46] Staging: hv: storvsc: Optimize the bounce buffer handling in the "read" case
Optimize the bounce buffer handling in the "read" case. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 90b91ad..3e00e70 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -560,12 +560,10 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >> PAGE_SHIFT; - /* - * FIXME: We can optimize on reads by just skipping - * this - */ - copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl, - scsi_sg_count(scmnd)); + if (vm_srb->data_in == WRITE_TYPE) + copy_to_bounce_buffer(sgl, + cmd_request->bounce_sgl, + scsi_sg_count(scmnd)); sgl = cmd_request->bounce_sgl; sg_count = cmd_request->bounce_sgl_count; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 24/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of storvsc.c
Cleanup storvsc_drv.c after adding the contents of storvsc.c. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 147 +++++++------------------------------- 1 files changed, 27 insertions(+), 120 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index ddb31cf..096f615 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -19,11 +19,17 @@ * Hank Janssen <hjanssen at microsoft.com> * K. Y. Srinivasan <kys at microsoft.com> */ + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/completion.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/device.h> -#include <linux/blkdev.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> @@ -37,39 +43,28 @@ #include "hyperv_storage.h" -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang <haiyangz at microsoft.com> - * Hank Janssen <hjanssen at microsoft.com> - * K. Y. Srinivasan <kys at microsoft.com> - * - */ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/completion.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/delay.h> +static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; -#include "hyperv.h" -#include "hyperv_storage.h" +module_param(storvsc_ringbuffer_size, int, S_IRUGO); +MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); + +struct hv_host_device { + struct hv_device *dev; + struct kmem_cache *request_pool; + unsigned int port; + unsigned char path; + unsigned char target; +}; + +struct storvsc_cmd_request { + struct list_head entry; + struct scsi_cmnd *cmd; + unsigned int bounce_sgl_count; + struct scatterlist *bounce_sgl; + + struct hv_storvsc_request request; +}; static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) { @@ -500,94 +495,6 @@ int storvsc_do_io(struct hv_device *device, return ret; } -/* - * The channel properties uniquely specify how the device is to be - * presented to the guest. Map this information for use by the block - * driver. For Linux guests on Hyper-V, we emulate a scsi HBA in the guest - * (storvsc_drv) and so scsi devices in the guest are handled by - * native upper level Linux drivers. Consequently, Hyper-V - * block driver, while being a generic block driver, presently does not - * deal with anything other than devices that would need to be presented - * to the guest as an IDE disk. - * - * This function maps the channel properties as embedded in the input - * parameter device_info onto information necessary to register the - * corresponding block device. - * - * Currently, there is no way to stop the emulation of the block device - * on the host side. And so, to prevent the native IDE drivers in Linux - * from taking over these devices (to be managedby Hyper-V block - * driver), we will take over if need be the major of the IDE controllers. - * - */ - -int storvsc_get_major_info(struct storvsc_device_info *device_info, - struct storvsc_major_info *major_info) -{ - static bool ide0_registered; - static bool ide1_registered; - - /* - * For now we only support IDE disks. - */ - major_info->devname = "ide"; - major_info->diskname = "hd"; - - if (device_info->path_id) { - major_info->major = 22; - if (!ide1_registered) { - major_info->do_register = true; - ide1_registered = true; - } else - major_info->do_register = false; - - if (device_info->target_id) - major_info->index = 3; - else - major_info->index = 2; - - return 0; - } else { - major_info->major = 3; - if (!ide0_registered) { - major_info->do_register = true; - ide0_registered = true; - } else - major_info->do_register = false; - - if (device_info->target_id) - major_info->index = 1; - else - major_info->index = 0; - - return 0; - } - - return -ENODEV; -} -static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; - -module_param(storvsc_ringbuffer_size, int, S_IRUGO); -MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); - -struct hv_host_device { - struct hv_device *dev; - struct kmem_cache *request_pool; - unsigned int port; - unsigned char path; - unsigned char target; -}; - -struct storvsc_cmd_request { - struct list_head entry; - struct scsi_cmnd *cmd; - - unsigned int bounce_sgl_count; - struct scatterlist *bounce_sgl; - - struct hv_storvsc_request request; -}; - static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path) { *target -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 26/46] Staging: hv: storvsc: Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h
Cleanup storvsc_drv.c after adding the contents of hyperv_storage.h. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 62 ++++++++++++++++---------------------- 1 files changed, 26 insertions(+), 36 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 4a95f8b..0bb4e0e 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -42,6 +42,12 @@ #include "hyperv.h" +#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) +static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; + +module_param(storvsc_ringbuffer_size, int, S_IRUGO); +MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); + /* to alert the user that structure sizes may be mismatched even though the */ /* protocol versions match. */ @@ -214,8 +220,6 @@ struct vstor_packet { /* Defines */ -#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) -#define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) #define STORVSC_MAX_IO_REQUESTS 128 @@ -262,13 +266,6 @@ struct storvsc_device_info { unsigned char target_id; }; -struct storvsc_major_info { - int major; - int index; - bool do_register; - char *devname; - char *diskname; -}; /* A storvsc device is a device object that contains a vmbus channel */ struct storvsc_device { @@ -294,6 +291,23 @@ struct storvsc_device { struct hv_storvsc_request reset_request; }; +struct hv_host_device { + struct hv_device *dev; + struct kmem_cache *request_pool; + unsigned int port; + unsigned char path; + unsigned char target; +}; + +struct storvsc_cmd_request { + struct list_head entry; + struct scsi_cmnd *cmd; + + unsigned int bounce_sgl_count; + struct scatterlist *bounce_sgl; + + struct hv_storvsc_request request; +}; static inline struct storvsc_device *get_out_stor_device( struct hv_device *device) @@ -317,30 +331,6 @@ static inline void storvsc_wait_to_drain(struct storvsc_device *dev) dev->drain_notify = false; } - -static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; - -module_param(storvsc_ringbuffer_size, int, S_IRUGO); -MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); - -struct hv_host_device { - struct hv_device *dev; - struct kmem_cache *request_pool; - unsigned int port; - unsigned char path; - unsigned char target; -}; - -struct storvsc_cmd_request { - struct list_head entry; - struct scsi_cmnd *cmd; - - unsigned int bounce_sgl_count; - struct scatterlist *bounce_sgl; - - struct hv_storvsc_request request; -}; - static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) { struct storvsc_device *stor_device; @@ -646,7 +636,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) return ret; } -int storvsc_dev_add(struct hv_device *device, +static int storvsc_dev_add(struct hv_device *device, void *additional_info) { struct storvsc_device *stor_device; @@ -681,7 +671,7 @@ int storvsc_dev_add(struct hv_device *device, return ret; } -int storvsc_dev_remove(struct hv_device *device) +static int storvsc_dev_remove(struct hv_device *device) { struct storvsc_device *stor_device; unsigned long flags; @@ -718,7 +708,7 @@ int storvsc_dev_remove(struct hv_device *device) return 0; } -int storvsc_do_io(struct hv_device *device, +static int storvsc_do_io(struct hv_device *device, struct hv_storvsc_request *request) { struct storvsc_device *stor_device; -- 1.7.4.1
Fix a typo in a function name. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 72ca25c..ad0f9d4 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -1130,9 +1130,9 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) /* - * storvsc_commmand_completion - Command completion processing + * storvsc_command_completion - Command completion processing */ -static void storvsc_commmand_completion(struct hv_storvsc_request *request) +static void storvsc_command_completion(struct hv_storvsc_request *request) { struct storvsc_cmd_request *cmd_request (struct storvsc_cmd_request *)request->context; @@ -1240,7 +1240,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, break; } - request->on_io_completion = storvsc_commmand_completion; + request->on_io_completion = storvsc_command_completion; request->context = cmd_request;/* scmnd; */ vm_srb->port_number = host_dev->port; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 29/46] Staging: hv: storvsc: In case of scsi errors offline the device
When we do get fatal errors from the host, offline the device since the host has already tried all possible recovery actions. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index ad0f9d4..22a1d75 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -1154,7 +1154,15 @@ static void storvsc_command_completion(struct hv_storvsc_request *request) } } - scmnd->result = vm_srb->scsi_status; + /* + * If there is an error; offline the device since all + * error recovery strategies would have already been + * deployed on the host side. + */ + if (vm_srb->srb_status == 0x4) + scmnd->result = DID_TARGET_FAILURE << 16; + else + scmnd->result = vm_srb->scsi_status; if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 30/46] Staging: hv: storvsc: No need to copy from bounce buffer in case of a failure
No need to copy from bounce buffer in case of a failure; cleanup the code accordingly. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/storvsc_drv.c | 12 ++---------- 1 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 22a1d75..d575bc9 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -1315,17 +1315,9 @@ retry_request: if (ret == -EAGAIN) { /* no more space */ - if (cmd_request->bounce_sgl_count) { - /* - * FIXME: We can optimize on writes by just skipping - * this - */ - copy_from_bounce_buffer(scsi_sglist(scmnd), - cmd_request->bounce_sgl, - scsi_sg_count(scmnd)); + if (cmd_request->bounce_sgl_count) destroy_bounce_buffer(cmd_request->bounce_sgl, - cmd_request->bounce_sgl_count); - } + cmd_request->bounce_sgl_count); kmem_cache_free(host_dev->request_pool, cmd_request); -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 31/46] Staging: hv: util: Forcefully shutdown when shutdown is requested
When the host requests a "shutdown", make sure we shutdown! Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hv_util.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index f2f456f..876d44a 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -89,7 +89,7 @@ static void shutdown_onchannelcallback(void *context) } if (execute_shutdown == true) - orderly_poweroff(false); + orderly_poweroff(true); } /* -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 32/46] Staging: hv: util: Adjust guest time in a process context
The current code was adjusting guest time in interrupt context; do this in process context since we may have to initiate cross-processor interrupts as part of setting time. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hv_util.c | 33 ++++++++++++++++++++++++++++++--- 1 files changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index 876d44a..e29a2a2 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -107,6 +107,24 @@ static inline void do_adj_guesttime(u64 hosttime) } /* + * Set the host time in a process context. + */ + +struct adj_time_work { + struct work_struct work; + u64 host_time; +}; + +static void hv_set_host_time(struct work_struct *work) +{ + struct adj_time_work *wrk; + + wrk = container_of(work, struct adj_time_work, work); + do_adj_guesttime(wrk->host_time); + kfree(wrk); +} + +/* * Synchronize time with host after reboot, restore, etc. * * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. @@ -119,17 +137,26 @@ static inline void do_adj_guesttime(u64 hosttime) */ static inline void adj_guesttime(u64 hosttime, u8 flags) { + struct adj_time_work *wrk; static s32 scnt = 50; + wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC); + if (wrk == NULL) + return; + + wrk->host_time = hosttime; if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { - do_adj_guesttime(hosttime); + INIT_WORK(&wrk->work, hv_set_host_time); + schedule_work(&wrk->work); return; } if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { scnt--; - do_adj_guesttime(hosttime); - } + INIT_WORK(&wrk->work, hv_set_host_time); + schedule_work(&wrk->work); + } else + kfree(wrk); } /* -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 33/46] Staging: hv: vmbus: Check before invoking the channel callback
When we close a channel, we set the corresponding callback function to NULL. Check before invoking the channel callback. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index a88ad70..7a3ec75 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -222,7 +222,7 @@ static void process_chn_event(u32 relid) */ channel = relid2channel(relid); - if (channel) { + if (channel && (channel->onchannel_callback != NULL)) { channel->onchannel_callback(channel->channel_callback_context); } else { pr_err("channel not found for relid - %u\n", relid); -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 35/46] Staging: hv: Fix a bug in vmbus_match()
The recent checkin that add a private pointer to hv_vmbus_device_id introduced this bug in vmbus_match; fix it. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index be62b62..51002c0 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -273,7 +273,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) for (; !is_null_guid(id_array->guid); id_array++) if (!memcmp(&id_array->guid, &hv_dev->dev_type.b, - sizeof(struct hv_vmbus_device_id))) + sizeof(uuid_le))) return 1; return 0; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 36/46] Staging: hv: vmbus: Get rid of vmbus_on_isr() by inlining the code
Get rid of vmbus_on_isr() by inlining the code. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 41 +++++++++++---------------------------- 1 files changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 51002c0..5dcc8c3 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -437,53 +437,36 @@ static void vmbus_on_msg_dpc(unsigned long data) } } -/* - * vmbus_on_isr - ISR routine - */ -static int vmbus_on_isr(void) +static irqreturn_t vmbus_isr(int irq, void *dev_id) { - int ret = 0; int cpu = smp_processor_id(); void *page_addr; struct hv_message *msg; union hv_synic_event_flags *event; + bool handled = false; page_addr = hv_context.synic_message_page[cpu]; msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; /* Check if there are actual msgs to be process */ - if (msg->header.message_type != HVMSG_NONE) - ret |= 0x1; + if (msg->header.message_type != HVMSG_NONE) { + handled = true; + tasklet_schedule(&msg_dpc); + } page_addr = hv_context.synic_event_page[cpu]; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; /* Since we are a child, we only need to check bit 0 */ - if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) - ret |= 0x2; - - return ret; -} - - -static irqreturn_t vmbus_isr(int irq, void *dev_id) -{ - int ret; - - ret = vmbus_on_isr(); - - /* Schedules a dpc if necessary */ - if (ret > 0) { - if (test_bit(0, (unsigned long *)&ret)) - tasklet_schedule(&msg_dpc); - - if (test_bit(1, (unsigned long *)&ret)) - tasklet_schedule(&event_dpc); + if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { + handled = true; + tasklet_schedule(&event_dpc); + } + if (handled) return IRQ_HANDLED; - } else { + else return IRQ_NONE; - } } /* -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 37/46] Staging: hv: vmbus: Check for events before messages
Conform to Windows specification by checking for events before messages. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 5dcc8c3..4e07d4f 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -445,15 +445,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) union hv_synic_event_flags *event; bool handled = false; - page_addr = hv_context.synic_message_page[cpu]; - msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; - - /* Check if there are actual msgs to be process */ - if (msg->header.message_type != HVMSG_NONE) { - handled = true; - tasklet_schedule(&msg_dpc); - } - page_addr = hv_context.synic_event_page[cpu]; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; @@ -463,6 +454,15 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) tasklet_schedule(&event_dpc); } + page_addr = hv_context.synic_message_page[cpu]; + msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; + + /* Check if there are actual msgs to be processed */ + if (msg->header.message_type != HVMSG_NONE) { + handled = true; + tasklet_schedule(&msg_dpc); + } + if (handled) return IRQ_HANDLED; else -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 39/46] Staging: hv: vmbus: Fixup indentation in vmbus_acpi_add()
Fixup indentation in vmbus_acpi_add(). Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 4e07d4f..d50fa89 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -678,9 +678,8 @@ static int vmbus_acpi_add(struct acpi_device *device) hv_acpi_dev = device; - result - acpi_walk_resources(device->handle, METHOD_NAME__CRS, - vmbus_walk_resources, &irq); + result = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + vmbus_walk_resources, &irq); if (ACPI_FAILURE(result)) { complete(&probe_event); -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 40/46] Staging: hv: vmbus: Get rid of some dated/redundant comments
Get rid of some dated/redundant comments in vmbus_drv.c Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 11 +---------- 1 files changed, 1 insertions(+), 10 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d50fa89..02edb11 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -391,9 +391,6 @@ static void vmbus_onmessage_work(struct work_struct *work) kfree(ctx); } -/* - * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior - */ static void vmbus_on_msg_dpc(unsigned long data) { int cpu = smp_processor_id(); @@ -490,16 +487,13 @@ static int vmbus_bus_init(int irq) return ret; } - /* Initialize the bus context */ tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0); tasklet_init(&event_dpc, vmbus_on_event, 0); - /* Now, register the bus with LDM */ ret = bus_register(&hv_bus); if (ret) return ret; - /* Get the interrupt resource */ ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, driver_name, hv_acpi_dev); @@ -588,7 +582,6 @@ struct hv_device *vmbus_child_device_create(uuid_le *type, { struct hv_device *child_device_obj; - /* Allocate the new child device */ child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL); if (!child_device_obj) { pr_err("Unable to allocate device object for child device\n"); @@ -613,12 +606,10 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) static atomic_t device_num = ATOMIC_INIT(0); - /* Set the device name. Otherwise, device_register() will fail. */ dev_set_name(&child_device_obj->device, "vmbus_0_%d", atomic_inc_return(&device_num)); - /* The new device belongs to this bus */ - child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */ + child_device_obj->device.bus = &hv_bus; child_device_obj->device.parent = &hv_acpi_dev->dev; child_device_obj->device.release = vmbus_device_release; -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
Fix a bug in error handling in vmbus_bus_init(). Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/vmbus_drv.c | 21 ++++++++++----------- 1 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 02edb11..4d1b123 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -492,7 +492,7 @@ static int vmbus_bus_init(int irq) ret = bus_register(&hv_bus); if (ret) - return ret; + goto err1; ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, driver_name, hv_acpi_dev); @@ -500,10 +500,7 @@ static int vmbus_bus_init(int irq) if (ret != 0) { pr_err("Unable to request IRQ %d\n", irq); - - bus_unregister(&hv_bus); - - return ret; + goto err2; } vector = IRQ0_VECTOR + irq; @@ -514,16 +511,18 @@ static int vmbus_bus_init(int irq) */ on_each_cpu(hv_synic_init, (void *)&vector, 1); ret = vmbus_connect(); - if (ret) { - free_irq(irq, hv_acpi_dev); - bus_unregister(&hv_bus); - return ret; - } - + if (ret) + goto err3; vmbus_request_offers(); return 0; + +err3: free_irq(irq, hv_acpi_dev); +err2: bus_unregister(&hv_bus); +err1: hv_cleanup(); + + return ret; } /** -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 42/46] Staging: hv: vmbus: Get rid of an unnecessary check in vmbus_connect()
Get rid of an unnecessary check in vmbus_connect(). Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/connection.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 6aab802..ca92ca3 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -50,10 +50,6 @@ int vmbus_connect(void) struct vmbus_channel_initiate_contact *msg; unsigned long flags; - /* Make sure we are not connecting or connected */ - if (vmbus_connection.conn_state != DISCONNECTED) - return -EISCONN; - /* Initialize the vmbus connection */ vmbus_connection.conn_state = CONNECTING; vmbus_connection.work_queue = create_workqueue("hv_vmbus_con"); -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 43/46] Staging: hv: vmbus: Fix a checkpatch warning in ring_buffer.c
Fix a checkpatch warning in ring_buffer.c Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/ring_buffer.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 9212699..70e2e66 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -34,7 +34,8 @@ /* Amount of space to write to */ -#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) +#define BYTES_AVAIL_TO_WRITE(r, w, z) \ + ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) /* -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
Fix checkpatch warnings in connection.c. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/connection.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index ca92ca3..9e99c04 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid) channel = relid2channel(relid); spin_lock_irqsave(&channel->inbound_lock, flags); - if (channel && (channel->onchannel_callback != NULL)) { + if (channel && (channel->onchannel_callback != NULL)) channel->onchannel_callback(channel->channel_callback_context); - } else { + else pr_err("channel not found for relid - %u\n", relid); - } + spin_unlock_irqrestore(&channel->inbound_lock, flags); } @@ -246,16 +246,17 @@ void vmbus_on_event(unsigned long data) if (!recv_int_page[dword]) continue; for (bit = 0; bit < 32; bit++) { - if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) { + if (sync_test_and_clear_bit(bit, + (unsigned long *)&recv_int_page[dword])) { relid = (dword << 5) + bit; - if (relid == 0) { + if (relid == 0) /* * Special case - vmbus * channel protocol msg */ continue; - } + process_chn_event(relid); } } -- 1.7.4.1
K. Y. Srinivasan
2011-Aug-27 18:31 UTC
[PATCH 45/46] Staging: hv: mousevsc: Fix checkpatch errors and warnings
Fix checkpatch errors and warnings. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/hv_mouse.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 090736a..dbb04ee 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -335,7 +335,8 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, input_device->hid_desc = kzalloc(desc->bLength, GFP_KERNEL); if (!input_device->hid_desc) { - pr_err("unable to allocate hid descriptor - size %d", desc->bLength); + pr_err("unable to allocate hid descriptor - size %d", + desc->bLength); goto cleanup; } @@ -598,12 +599,12 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) pr_info("synthhid protocol request..."); ret = vmbus_sendpacket(device->channel, request, - sizeof(struct pipe_prt_msg) - - sizeof(unsigned char) + - sizeof(struct synthhid_protocol_request), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + sizeof(struct pipe_prt_msg) - + sizeof(unsigned char) + + sizeof(struct synthhid_protocol_request), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { pr_err("unable to send synthhid protocol request."); goto cleanup; -- 1.7.4.1
Update the TODO file. Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> --- drivers/staging/hv/TODO | 24 ++++++++++++++++++++---- 1 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO index 582fd4a..23c74ed 100644 --- a/drivers/staging/hv/TODO +++ b/drivers/staging/hv/TODO @@ -1,14 +1,30 @@ TODO: - - fix remaining checkpatch warnings and errors - audit the vmbus to verify it is working properly with the driver model - - see if the vmbus can be merged with the other virtual busses - in the kernel + + STATUS (July 19, 2011): + All outstanding issues (known to us) with regards + to conforming to Linux Driver Model have been addressed. + - audit the network driver - checking for carrier inside open is wrong, network device API confusion?? + + STATUS (July 19, 2011): + The network driver has been reviewed by the community. + We have addressed the various issues that were raised in this + review. + - audit the block driver - audit the scsi driver + STATUS (July 19, 2011): + One of the longstanding comment on this body of code + has been to merge the block and scsi driver. This has been done + and patches have been submitted. We have also addressed all the + review comments on this body of code. + + Please send patches for this code to Greg Kroah-Hartman <gregkh at suse.de>, -Hank Janssen <hjanssen at microsoft.com>, and Haiyang Zhang <haiyangz at microsoft.com>. +Hank Janssen <hjanssen at microsoft.com>, and Haiyang Zhang <haiyangz at microsoft.com>, +K. Y. Srinivasan <kys at microsoft.com>. -- 1.7.4.1
Joe Perches
2011-Aug-28 06:56 UTC
[PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
On Sat, 2011-08-27 at 11:31 -0700, K. Y. Srinivasan wrote:> Fix checkpatch warnings in connection.c.[]> diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c[]> @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid) > channel = relid2channel(relid); > > spin_lock_irqsave(&channel->inbound_lock, flags); > - if (channel && (channel->onchannel_callback != NULL)) { > + if (channel && (channel->onchannel_callback != NULL))Useless test for channel or bad placement for spin_lock. channel has already been dereferenced by the spin_lock.
On Sat, Aug 27, 2011 at 11:31:34AM -0700, K. Y. Srinivasan wrote:> The recent checkin that add a private pointer to hv_vmbus_device_id > introduced this bug in vmbus_match; fix it. > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > --- > drivers/staging/hv/vmbus_drv.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c > index be62b62..51002c0 100644 > --- a/drivers/staging/hv/vmbus_drv.c > +++ b/drivers/staging/hv/vmbus_drv.c > @@ -273,7 +273,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) > > for (; !is_null_guid(id_array->guid); id_array++) > if (!memcmp(&id_array->guid, &hv_dev->dev_type.b, > - sizeof(struct hv_vmbus_device_id))) > + sizeof(uuid_le)))Ick, sorry about this, it was my fault. greg k-h
Greg KH
2011-Aug-29 18:05 UTC
[PATCH 37/46] Staging: hv: vmbus: Check for events before messages
On Sat, Aug 27, 2011 at 11:31:36AM -0700, K. Y. Srinivasan wrote:> Conform to Windows specification by checking for events before messages.What specification? Care to provide a comment in the code that you are doing this in this explicit order because of some rule that the hypervisor imposes on us? thanks, greg k-h
Greg KH
2011-Aug-29 18:08 UTC
[PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
On Sat, Aug 27, 2011 at 11:31:40AM -0700, K. Y. Srinivasan wrote:> Fix a bug in error handling in vmbus_bus_init(). > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > --- > drivers/staging/hv/vmbus_drv.c | 21 ++++++++++----------- > 1 files changed, 10 insertions(+), 11 deletions(-) > > diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c > index 02edb11..4d1b123 100644 > --- a/drivers/staging/hv/vmbus_drv.c > +++ b/drivers/staging/hv/vmbus_drv.c > @@ -492,7 +492,7 @@ static int vmbus_bus_init(int irq) > > ret = bus_register(&hv_bus); > if (ret) > - return ret; > + goto err1; > > ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, > driver_name, hv_acpi_dev); > @@ -500,10 +500,7 @@ static int vmbus_bus_init(int irq) > if (ret != 0) { > pr_err("Unable to request IRQ %d\n", > irq); > - > - bus_unregister(&hv_bus); > - > - return ret; > + goto err2; > } > > vector = IRQ0_VECTOR + irq; > @@ -514,16 +511,18 @@ static int vmbus_bus_init(int irq) > */ > on_each_cpu(hv_synic_init, (void *)&vector, 1); > ret = vmbus_connect(); > - if (ret) { > - free_irq(irq, hv_acpi_dev); > - bus_unregister(&hv_bus); > - return ret; > - } > - > + if (ret) > + goto err3; > > vmbus_request_offers(); > > return 0; > + > +err3: free_irq(irq, hv_acpi_dev); > +err2: bus_unregister(&hv_bus); > +err1: hv_cleanup();The traditional way to write this is: err3: free_irq(irq, hv_acpi_dev); err2: bus_unregister(&hv_bus); err1: hv_cleanup(); Care to fix this up and resend it? thanks, greg k-h
On Sat, Aug 27, 2011 at 11:31:14AM -0700, K. Y. Srinivasan wrote:> Further cleanup of the hv drivers. > > 1) Cleanup reference counting. > > 2) Handle all block devices using the storvsc driver. I have modified > the implementation here based on Christoph's feedback on my earlier > implementation. > > 3) Fix bugs. > > 4) Accomodate some host side scsi emulation bugs. > > 5) In case of scsi errors off-line the device. > > This patch-set further reduces the size of Hyper-V drivers - the code is > about 10% smaller. This reduction is mainly because we have eliminated the > blkvsc driver.If my tracking is correct, I applied everything in this series except the following patches [PATCH 37/46] Staging: hv: vmbus: Check for events before messages [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init() [PATCH 46/46] Staging: hv: Update the TODO file Please fix up patches 37 and 41 and resend, and for 46, that should be totally different as mentioned, but you might want to send a patch that at the least adds your name to the file at the bottom, as you wanted. Also note that the MAINTAINERS file should also be adjusted to match. thanks, greg k-h
On Sat, Aug 27, K. Y. Srinivasan wrote:> 2) Handle all block devices using the storvsc driver. I have modified > the implementation here based on Christoph's feedback on my earlier > implementation.The upgrade path from hv_blkvsc to hv_storvsc is difficult. hv_storvsc does not provide the vmbus:hv_block modalias, so mkinitrd does not know what module to choose when mkinitrd is called in a previous kernel (like sles11sp1). In a guest with both SCSI and IDE controllers the IDE disks are discovered first, so the SCSI drives will also change their names. Thats not a problem for data partitions because they could be mounted by UUID or LABEL in fstab. But its difficult to adjust /boot/grub/device.map for example because the old IDE drives do not provide an identifier. What is the best way to make sure the rename from hd* to sd* in such config files is done correctly? Is it safe to assume that all drives with a class_id of 32412632-86cb-44a2-9b5c50d1417354f5 are connected to IDE ports? localhost:~ # head /sys/bus/vmbus/devices/vmbus_0_{1,2,3,10,11}/class_id ==> /sys/bus/vmbus/devices/vmbus_0_1/class_id <={32412632-86cb-44a2-9b5c50d1417354f5} ==> /sys/bus/vmbus/devices/vmbus_0_2/class_id <={32412632-86cb-44a2-9b5c50d1417354f5} ==> /sys/bus/vmbus/devices/vmbus_0_3/class_id <={32412632-86cb-44a2-9b5c50d1417354f5} ==> /sys/bus/vmbus/devices/vmbus_0_10/class_id <={ba6163d9-04a1-4d29-b60572e2ffb1dc7f} ==> /sys/bus/vmbus/devices/vmbus_0_11/class_id <={ba6163d9-04a1-4d29-b60572e2ffb1dc7f} In my test system, the IDE drives are now discovered twice, once by hv_storvsc and once by libata: localhost:~ # lsscsi [0:0:0:0] disk Msft Virtual Disk 1.0 /dev/sda [1:0:1:0] disk Msft Virtual Disk 1.0 /dev/sdb [2:0:1:0] disk Msft Virtual Disk 1.0 /dev/sdc [3:0:0:0] disk Msft Virtual Disk 1.0 /dev/sdd [3:0:0:1] disk Msft Virtual Disk 1.0 /dev/sde [4:0:0:0] disk Msft Virtual Disk 1.0 /dev/sdf [4:0:0:1] disk Msft Virtual Disk 1.0 /dev/sdg [5:0:0:0] disk ATA Virtual HD 1.1. /dev/sdh [5:0:1:0] disk ATA Virtual HD 1.1. /dev/sdi [6:0:0:0] cd/dvd Msft Virtual CD/ROM 1.0 /dev/sr0 [6:0:1:0] disk ATA Virtual HD 1.1. /dev/sdj localhost:~ # blkid /dev/sda1: UUID="47aebbfb-13ee-49cc-b1e7-bc0c243fe3c0" TYPE="swap" /dev/sda2: UUID="ed5a182b-da28-42f2-acff-5649a8fae247" TYPE="ext3" /dev/sdh1: UUID="47aebbfb-13ee-49cc-b1e7-bc0c243fe3c0" TYPE="swap" /dev/sdh2: UUID="ed5a182b-da28-42f2-acff-5649a8fae247" TYPE="ext3" sda/sdh was hda. Olaf
KY Srinivasan
2011-Aug-30 17:03 UTC
[PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in connection.c
> -----Original Message----- > From: Joe Perches [mailto:joe at perches.com] > Sent: Sunday, August 28, 2011 2:57 AM > To: KY Srinivasan > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org; Haiyang Zhang > Subject: Re: [PATCH 44/46] Staging: hv: vmbus: Fix checkpatch warnings in > connection.c > > On Sat, 2011-08-27 at 11:31 -0700, K. Y. Srinivasan wrote: > > Fix checkpatch warnings in connection.c. > [] > > diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c > [] > > @@ -220,11 +220,11 @@ static void process_chn_event(u32 relid) > > channel = relid2channel(relid); > > > > spin_lock_irqsave(&channel->inbound_lock, flags); > > - if (channel && (channel->onchannel_callback != NULL)) { > > + if (channel && (channel->onchannel_callback != NULL)) > > Useless test for channel or bad placement for spin_lock. > channel has already been dereferenced by the spin_lock. > >Thanks Joe. I will fix this up. Regards, K. Y
KY Srinivasan
2011-Aug-30 17:06 UTC
[PATCH 37/46] Staging: hv: vmbus: Check for events before messages
> -----Original Message----- > From: Greg KH [mailto:greg at kroah.com] > Sent: Monday, August 29, 2011 2:05 PM > To: KY Srinivasan > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org; Haiyang Zhang > Subject: Re: [PATCH 37/46] Staging: hv: vmbus: Check for events before > messages > > On Sat, Aug 27, 2011 at 11:31:36AM -0700, K. Y. Srinivasan wrote: > > Conform to Windows specification by checking for events before messages. > > What specification? > > Care to provide a comment in the code that you are doing this in this > explicit order because of some rule that the hypervisor imposes on us?I am not sure if this is documented anywhere (publicly). In talking to Windows guys, they suggested this is the order in which it is done on Windows guests and suggested I should do the same. I will see if there is some public documentation that specifies this. Regards, K. Y> > thanks, > > greg k-h
KY Srinivasan
2011-Aug-30 17:07 UTC
[PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in vmbus_bus_init()
> -----Original Message----- > From: Greg KH [mailto:greg at kroah.com] > Sent: Monday, August 29, 2011 2:09 PM > To: KY Srinivasan > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org; Haiyang Zhang > Subject: Re: [PATCH 41/46] Staging: hv: vmbus: Fix a bug in error handling in > vmbus_bus_init() > > On Sat, Aug 27, 2011 at 11:31:40AM -0700, K. Y. Srinivasan wrote: > > Fix a bug in error handling in vmbus_bus_init(). > > > > Signed-off-by: K. Y. Srinivasan <kys at microsoft.com> > > Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com> > > --- > > drivers/staging/hv/vmbus_drv.c | 21 ++++++++++----------- > > 1 files changed, 10 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c > > index 02edb11..4d1b123 100644 > > --- a/drivers/staging/hv/vmbus_drv.c > > +++ b/drivers/staging/hv/vmbus_drv.c > > @@ -492,7 +492,7 @@ static int vmbus_bus_init(int irq) > > > > ret = bus_register(&hv_bus); > > if (ret) > > - return ret; > > + goto err1; > > > > ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, > > driver_name, hv_acpi_dev); > > @@ -500,10 +500,7 @@ static int vmbus_bus_init(int irq) > > if (ret != 0) { > > pr_err("Unable to request IRQ %d\n", > > irq); > > - > > - bus_unregister(&hv_bus); > > - > > - return ret; > > + goto err2; > > } > > > > vector = IRQ0_VECTOR + irq; > > @@ -514,16 +511,18 @@ static int vmbus_bus_init(int irq) > > */ > > on_each_cpu(hv_synic_init, (void *)&vector, 1); > > ret = vmbus_connect(); > > - if (ret) { > > - free_irq(irq, hv_acpi_dev); > > - bus_unregister(&hv_bus); > > - return ret; > > - } > > - > > + if (ret) > > + goto err3; > > > > vmbus_request_offers(); > > > > return 0; > > + > > +err3: free_irq(irq, hv_acpi_dev); > > +err2: bus_unregister(&hv_bus); > > +err1: hv_cleanup(); > > The traditional way to write this is: > > err3: > free_irq(irq, hv_acpi_dev); > err2: > bus_unregister(&hv_bus); > err1: > hv_cleanup(); > > Care to fix this up and resend it?Will do. Regards, K. Y
> -----Original Message----- > From: Olaf Hering [mailto:olaf at aepfle.de] > Sent: Tuesday, August 30, 2011 8:49 AM > To: KY Srinivasan > Cc: gregkh at suse.de; linux-kernel at vger.kernel.org; > devel at linuxdriverproject.org; virtualization at lists.osdl.org > Subject: Re: [PATCH 0000/0046] Staging: hv: Driver cleanup > > On Sat, Aug 27, K. Y. Srinivasan wrote: > > > 2) Handle all block devices using the storvsc driver. I have modified > > the implementation here based on Christoph's feedback on my earlier > > implementation. > > The upgrade path from hv_blkvsc to hv_storvsc is difficult. > > hv_storvsc does not provide the vmbus:hv_block modalias, so mkinitrd > does not know what module to choose when mkinitrd is called in a > previous kernel (like sles11sp1). > > > In a guest with both SCSI and IDE controllers the IDE disks are > discovered first, so the SCSI drives will also change their names. > Thats not a problem for data partitions because they could be mounted by > UUID or LABEL in fstab. > But its difficult to adjust /boot/grub/device.map for example because > the old IDE drives do not provide an identifier. What is the best way > to make sure the rename from hd* to sd* in such config files is done > correctly? Is it safe to assume that all drives with a class_id of > 32412632-86cb-44a2-9b5c50d1417354f5 are connected to IDE ports?The class_id is invariant as we are returning the guid of the device under class_id. So, if you see a IDE guid under class_id, you can be sure (a) it is an ide device and (b) it is a device managed via the PV drivers.> > localhost:~ # head /sys/bus/vmbus/devices/vmbus_0_{1,2,3,10,11}/class_id > ==> /sys/bus/vmbus/devices/vmbus_0_1/class_id <=> {32412632-86cb-44a2-9b5c50d1417354f5} > > ==> /sys/bus/vmbus/devices/vmbus_0_2/class_id <=> {32412632-86cb-44a2-9b5c50d1417354f5} > > ==> /sys/bus/vmbus/devices/vmbus_0_3/class_id <=> {32412632-86cb-44a2-9b5c50d1417354f5} > > ==> /sys/bus/vmbus/devices/vmbus_0_10/class_id <=> {ba6163d9-04a1-4d29-b60572e2ffb1dc7f} > > ==> /sys/bus/vmbus/devices/vmbus_0_11/class_id <=> {ba6163d9-04a1-4d29-b60572e2ffb1dc7f} > > > In my test system, the IDE drives are now discovered twice, once by > hv_storvsc and once by libata:This is a known (old problem). The way this was handled earlier was to have the modprobe rules in place to setup a dependency that would force the load of the hyper-v driver (blk / stor) ahead of the native driver and if the load of the PV driver succeeded, we would not load the native driver. In sles11 sp1, we had a rule for loading blkvsc. With the merge of blkvsc and storvsc, the only change we need to make is to have storvsc in the rule (instaed of blkvsc). Regards, K. Y