diff mbox

[V3,4/4] scsi: storvsc: Tighten up the interrupt path

Message ID 1450038512-19252-4-git-send-email-kys@microsoft.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

KY Srinivasan Dec. 13, 2015, 8:28 p.m. UTC
On the interrupt path, we repeatedly establish the pointer to the
storvsc_device. Fix this.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Tested-by: Alex Ng <alexng@microsoft.com>
---
 drivers/scsi/storvsc_drv.c |   23 ++++++++---------------
 1 files changed, 8 insertions(+), 15 deletions(-)

Comments

Hannes Reinecke Dec. 18, 2015, 8:51 a.m. UTC | #1
On 12/13/2015 09:28 PM, K. Y. Srinivasan wrote:
> On the interrupt path, we repeatedly establish the pointer to the
> storvsc_device. Fix this.
>
> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> Reviewed-by: Long Li <longli@microsoft.com>
> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> Tested-by: Alex Ng <alexng@microsoft.com>
> ---
>   drivers/scsi/storvsc_drv.c |   23 ++++++++---------------
>   1 files changed, 8 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
> index d6ca4f2..b68aebe 100644
> --- a/drivers/scsi/storvsc_drv.c
> +++ b/drivers/scsi/storvsc_drv.c
> @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
>   }
>
>
> -static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
> +static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
> +				       struct storvsc_device *stor_dev)
>   {
>   	struct scsi_cmnd *scmnd = cmd_request->cmd;
> -	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
>   	struct scsi_sense_hdr sense_hdr;
>   	struct vmscsi_request *vm_srb;
>   	struct Scsi_Host *host;
> -	struct storvsc_device *stor_dev;
> -	struct hv_device *dev = host_dev->dev;
>   	u32 payload_sz = cmd_request->payload_sz;
>   	void *payload = cmd_request->payload;
>
> -	stor_dev = get_in_stor_device(dev);
>   	host = stor_dev->host;
>
>   	vm_srb = &cmd_request->vstor_packet.vm_srb;
> @@ -987,14 +984,13 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
>   		kfree(payload);
>   }
>
> -static void storvsc_on_io_completion(struct hv_device *device,
> +static void storvsc_on_io_completion(struct storvsc_device *stor_device,
>   				  struct vstor_packet *vstor_packet,
>   				  struct storvsc_cmd_request *request)
>   {
> -	struct storvsc_device *stor_device;
>   	struct vstor_packet *stor_pkt;
> +	struct hv_device *device = stor_device->device;
>
> -	stor_device = hv_get_drvdata(device);
>   	stor_pkt = &request->vstor_packet;
>
>   	/*
> @@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct hv_device *device,
>   	stor_pkt->vm_srb.data_transfer_length =
>   	vstor_packet->vm_srb.data_transfer_length;
>
> -	storvsc_command_completion(request);
> +	storvsc_command_completion(request, stor_device);
>
>   	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
>   		stor_device->drain_notify)
> @@ -1058,21 +1054,19 @@ static void storvsc_on_io_completion(struct hv_device *device,
>
>   }
>
> -static void storvsc_on_receive(struct hv_device *device,
> +static void storvsc_on_receive(struct storvsc_device *stor_device,
>   			     struct vstor_packet *vstor_packet,
>   			     struct storvsc_cmd_request *request)
>   {
>   	struct storvsc_scan_work *work;
> -	struct storvsc_device *stor_device;
>
>   	switch (vstor_packet->operation) {
>   	case VSTOR_OPERATION_COMPLETE_IO:
> -		storvsc_on_io_completion(device, vstor_packet, request);
> +		storvsc_on_io_completion(stor_device, vstor_packet, request);
>   		break;
>
>   	case VSTOR_OPERATION_REMOVE_DEVICE:
>   	case VSTOR_OPERATION_ENUMERATE_BUS:
> -		stor_device = get_in_stor_device(device);
>   		work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
>   		if (!work)
>   			return;
> @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct hv_device *device,
>   		break;
>
>   	case VSTOR_OPERATION_FCHBA_DATA:
> -		stor_device = get_in_stor_device(device);
>   		cache_wwn(stor_device, vstor_packet);
>   #ifdef CONFIG_SCSI_FC_ATTRS
>   		fc_host_node_name(stor_device->host) = stor_device->node_name;
> @@ -1133,7 +1126,7 @@ static void storvsc_on_channel_callback(void *context)
>   					vmscsi_size_delta));
>   				complete(&request->wait_event);
>   			} else {
> -				storvsc_on_receive(device,
> +				storvsc_on_receive(stor_device,
>   						(struct vstor_packet *)packet,
>   						request);
>   			}
>
Hmm. I would've thought the compiler optimizes this away. Have you 
checked whether it actually makes a difference in the assembler output?

Cheers,

Hannes
KY Srinivasan Dec. 18, 2015, 4:20 p.m. UTC | #2
> -----Original Message-----
> From: Hannes Reinecke [mailto:hare@suse.de]
> Sent: Friday, December 18, 2015 12:52 AM
> To: KY Srinivasan <kys@microsoft.com>; gregkh@linuxfoundation.org; linux-
> kernel@vger.kernel.org; devel@linuxdriverproject.org; ohering@suse.com;
> jbottomley@parallels.com; hch@infradead.org; linux-scsi@vger.kernel.org;
> apw@canonical.com; vkuznets@redhat.com; jasowang@redhat.com;
> martin.petersen@oracle.com
> Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt path
> 
> On 12/13/2015 09:28 PM, K. Y. Srinivasan wrote:
> > On the interrupt path, we repeatedly establish the pointer to the
> > storvsc_device. Fix this.
> >
> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > Reviewed-by: Long Li <longli@microsoft.com>
> > Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> > Tested-by: Alex Ng <alexng@microsoft.com>
> > ---
> >   drivers/scsi/storvsc_drv.c |   23 ++++++++---------------
> >   1 files changed, 8 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
> > index d6ca4f2..b68aebe 100644
> > --- a/drivers/scsi/storvsc_drv.c
> > +++ b/drivers/scsi/storvsc_drv.c
> > @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct
> vmscsi_request *vm_srb,
> >   }
> >
> >
> > -static void storvsc_command_completion(struct storvsc_cmd_request
> *cmd_request)
> > +static void storvsc_command_completion(struct storvsc_cmd_request
> *cmd_request,
> > +				       struct storvsc_device *stor_dev)
> >   {
> >   	struct scsi_cmnd *scmnd = cmd_request->cmd;
> > -	struct hv_host_device *host_dev = shost_priv(scmnd->device-
> >host);
> >   	struct scsi_sense_hdr sense_hdr;
> >   	struct vmscsi_request *vm_srb;
> >   	struct Scsi_Host *host;
> > -	struct storvsc_device *stor_dev;
> > -	struct hv_device *dev = host_dev->dev;
> >   	u32 payload_sz = cmd_request->payload_sz;
> >   	void *payload = cmd_request->payload;
> >
> > -	stor_dev = get_in_stor_device(dev);
> >   	host = stor_dev->host;
> >
> >   	vm_srb = &cmd_request->vstor_packet.vm_srb;
> > @@ -987,14 +984,13 @@ static void storvsc_command_completion(struct
> storvsc_cmd_request *cmd_request)
> >   		kfree(payload);
> >   }
> >
> > -static void storvsc_on_io_completion(struct hv_device *device,
> > +static void storvsc_on_io_completion(struct storvsc_device *stor_device,
> >   				  struct vstor_packet *vstor_packet,
> >   				  struct storvsc_cmd_request *request)
> >   {
> > -	struct storvsc_device *stor_device;
> >   	struct vstor_packet *stor_pkt;
> > +	struct hv_device *device = stor_device->device;
> >
> > -	stor_device = hv_get_drvdata(device);
> >   	stor_pkt = &request->vstor_packet;
> >
> >   	/*
> > @@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct
> hv_device *device,
> >   	stor_pkt->vm_srb.data_transfer_length =
> >   	vstor_packet->vm_srb.data_transfer_length;
> >
> > -	storvsc_command_completion(request);
> > +	storvsc_command_completion(request, stor_device);
> >
> >   	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
> >   		stor_device->drain_notify)
> > @@ -1058,21 +1054,19 @@ static void storvsc_on_io_completion(struct
> hv_device *device,
> >
> >   }
> >
> > -static void storvsc_on_receive(struct hv_device *device,
> > +static void storvsc_on_receive(struct storvsc_device *stor_device,
> >   			     struct vstor_packet *vstor_packet,
> >   			     struct storvsc_cmd_request *request)
> >   {
> >   	struct storvsc_scan_work *work;
> > -	struct storvsc_device *stor_device;
> >
> >   	switch (vstor_packet->operation) {
> >   	case VSTOR_OPERATION_COMPLETE_IO:
> > -		storvsc_on_io_completion(device, vstor_packet, request);
> > +		storvsc_on_io_completion(stor_device, vstor_packet,
> request);
> >   		break;
> >
> >   	case VSTOR_OPERATION_REMOVE_DEVICE:
> >   	case VSTOR_OPERATION_ENUMERATE_BUS:
> > -		stor_device = get_in_stor_device(device);
> >   		work = kmalloc(sizeof(struct storvsc_scan_work),
> GFP_ATOMIC);
> >   		if (!work)
> >   			return;
> > @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct hv_device
> *device,
> >   		break;
> >
> >   	case VSTOR_OPERATION_FCHBA_DATA:
> > -		stor_device = get_in_stor_device(device);
> >   		cache_wwn(stor_device, vstor_packet);
> >   #ifdef CONFIG_SCSI_FC_ATTRS
> >   		fc_host_node_name(stor_device->host) = stor_device-
> >node_name;
> > @@ -1133,7 +1126,7 @@ static void storvsc_on_channel_callback(void
> *context)
> >   					vmscsi_size_delta));
> >   				complete(&request->wait_event);
> >   			} else {
> > -				storvsc_on_receive(device,
> > +				storvsc_on_receive(stor_device,
> >   						(struct vstor_packet
> *)packet,
> >   						request);
> >   			}
> >
> Hmm. I would've thought the compiler optimizes this away. Have you
> checked whether it actually makes a difference in the assembler output?

I have not checked the assembler output. It was easy enough to fix the source.

K. Y
> 
> Cheers,
> 
> Hannes
> --
> Dr. Hannes Reinecke		               zSeries & Storage
> hare@suse.de			               +49 911 74053 688
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
> HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
James Bottomley Dec. 18, 2015, 4:48 p.m. UTC | #3
On Fri, 2015-12-18 at 16:20 +0000, KY Srinivasan wrote:
> 
> > -----Original Message-----
> > From: Hannes Reinecke [mailto:hare@suse.de]
> > Sent: Friday, December 18, 2015 12:52 AM
> > To: KY Srinivasan <kys@microsoft.com>; gregkh@linuxfoundation.org;
> > linux-
> > kernel@vger.kernel.org; devel@linuxdriverproject.org; 
> > ohering@suse.com;
> > jbottomley@parallels.com; hch@infradead.org; 
> > linux-scsi@vger.kernel.org;
> > apw@canonical.com; vkuznets@redhat.com; jasowang@redhat.com;
> > martin.petersen@oracle.com
> > Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt
> > path
> > 
> > On 12/13/2015 09:28 PM, K. Y. Srinivasan wrote:
> > > On the interrupt path, we repeatedly establish the pointer to the
> > > storvsc_device. Fix this.
> > > 
> > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > Reviewed-by: Long Li <longli@microsoft.com>
> > > Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> > > Tested-by: Alex Ng <alexng@microsoft.com>
> > > ---
> > >   drivers/scsi/storvsc_drv.c |   23 ++++++++---------------
> > >   1 files changed, 8 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/drivers/scsi/storvsc_drv.c
> > > b/drivers/scsi/storvsc_drv.c
> > > index d6ca4f2..b68aebe 100644
> > > --- a/drivers/scsi/storvsc_drv.c
> > > +++ b/drivers/scsi/storvsc_drv.c
> > > @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct
> > vmscsi_request *vm_srb,
> > >   }
> > > 
> > > 
> > > -static void storvsc_command_completion(struct
> > > storvsc_cmd_request
> > *cmd_request)
> > > +static void storvsc_command_completion(struct
> > > storvsc_cmd_request
> > *cmd_request,
> > > +				       struct storvsc_device
> > > *stor_dev)
> > >   {
> > >   	struct scsi_cmnd *scmnd = cmd_request->cmd;
> > > -	struct hv_host_device *host_dev = shost_priv(scmnd
> > > ->device-
> > > host);
> > >   	struct scsi_sense_hdr sense_hdr;
> > >   	struct vmscsi_request *vm_srb;
> > >   	struct Scsi_Host *host;
> > > -	struct storvsc_device *stor_dev;
> > > -	struct hv_device *dev = host_dev->dev;
> > >   	u32 payload_sz = cmd_request->payload_sz;
> > >   	void *payload = cmd_request->payload;
> > > 
> > > -	stor_dev = get_in_stor_device(dev);
> > >   	host = stor_dev->host;
> > > 
> > >   	vm_srb = &cmd_request->vstor_packet.vm_srb;
> > > @@ -987,14 +984,13 @@ static void
> > > storvsc_command_completion(struct
> > storvsc_cmd_request *cmd_request)
> > >   		kfree(payload);
> > >   }
> > > 
> > > -static void storvsc_on_io_completion(struct hv_device *device,
> > > +static void storvsc_on_io_completion(struct storvsc_device
> > > *stor_device,
> > >   				  struct vstor_packet
> > > *vstor_packet,
> > >   				  struct storvsc_cmd_request
> > > *request)
> > >   {
> > > -	struct storvsc_device *stor_device;
> > >   	struct vstor_packet *stor_pkt;
> > > +	struct hv_device *device = stor_device->device;
> > > 
> > > -	stor_device = hv_get_drvdata(device);
> > >   	stor_pkt = &request->vstor_packet;
> > > 
> > >   	/*
> > > @@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct
> > hv_device *device,
> > >   	stor_pkt->vm_srb.data_transfer_length =
> > >   	vstor_packet->vm_srb.data_transfer_length;
> > > 
> > > -	storvsc_command_completion(request);
> > > +	storvsc_command_completion(request, stor_device);
> > > 
> > >   	if (atomic_dec_and_test(&stor_device
> > > ->num_outstanding_req) &&
> > >   		stor_device->drain_notify)
> > > @@ -1058,21 +1054,19 @@ static void
> > > storvsc_on_io_completion(struct
> > hv_device *device,
> > > 
> > >   }
> > > 
> > > -static void storvsc_on_receive(struct hv_device *device,
> > > +static void storvsc_on_receive(struct storvsc_device
> > > *stor_device,
> > >   			     struct vstor_packet *vstor_packet,
> > >   			     struct storvsc_cmd_request
> > > *request)
> > >   {
> > >   	struct storvsc_scan_work *work;
> > > -	struct storvsc_device *stor_device;
> > > 
> > >   	switch (vstor_packet->operation) {
> > >   	case VSTOR_OPERATION_COMPLETE_IO:
> > > -		storvsc_on_io_completion(device, vstor_packet,
> > > request);
> > > +		storvsc_on_io_completion(stor_device,
> > > vstor_packet,
> > request);
> > >   		break;
> > > 
> > >   	case VSTOR_OPERATION_REMOVE_DEVICE:
> > >   	case VSTOR_OPERATION_ENUMERATE_BUS:
> > > -		stor_device = get_in_stor_device(device);
> > >   		work = kmalloc(sizeof(struct
> > > storvsc_scan_work),
> > GFP_ATOMIC);
> > >   		if (!work)
> > >   			return;
> > > @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct
> > > hv_device
> > *device,
> > >   		break;
> > > 
> > >   	case VSTOR_OPERATION_FCHBA_DATA:
> > > -		stor_device = get_in_stor_device(device);
> > >   		cache_wwn(stor_device, vstor_packet);
> > >   #ifdef CONFIG_SCSI_FC_ATTRS
> > >   		fc_host_node_name(stor_device->host) =
> > > stor_device-
> > > node_name;
> > > @@ -1133,7 +1126,7 @@ static void
> > > storvsc_on_channel_callback(void
> > *context)
> > >   					vmscsi_size_delta));
> > >   				complete(&request->wait_event);
> > >   			} else {
> > > -				storvsc_on_receive(device,
> > > +				storvsc_on_receive(stor_device,
> > >   						(struct
> > > vstor_packet
> > *)packet,
> > >   						request);
> > >   			}
> > > 
> > Hmm. I would've thought the compiler optimizes this away. Have you
> > checked whether it actually makes a difference in the assembler
> > output?
> 
> I have not checked the assembler output. It was easy enough to fix 
> the source.

Could you?  You're making what you describe as an optimisation but
there are two reasons why this might not be so.  The first is that the
compiler is entitled to inline static functions.  If it did, likely it
picked up the optmisation anyway as Hannes suggested.  However, the
other reason this might not be an optimisation (assuming the compiler
doesn't inline the function) is you're passing an argument which can be
offset computed.  On all architectures, you have a fixed number of
registers for passing function arguments, then we have to use the
stack.  Using the stack comes in far more expensive than computing an
offset to an existing pointer.  Even if you're still in registers, the
offset now has to be computed and stored and the compiler loses track
of the relation.

The bottom line is that adding an extra argument for a value which can
be offset computed is rarely a win.

James


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
KY Srinivasan Dec. 19, 2015, 2:28 a.m. UTC | #4
> -----Original Message-----

> From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com]

> Sent: Friday, December 18, 2015 8:48 AM

> To: KY Srinivasan <kys@microsoft.com>; Hannes Reinecke <hare@suse.de>;

> gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;

> devel@linuxdriverproject.org; ohering@suse.com;

> jbottomley@parallels.com; hch@infradead.org; linux-scsi@vger.kernel.org;

> apw@canonical.com; vkuznets@redhat.com; jasowang@redhat.com;

> martin.petersen@oracle.com

> Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt path

> 

> On Fri, 2015-12-18 at 16:20 +0000, KY Srinivasan wrote:

> >

> > > -----Original Message-----

> > > From: Hannes Reinecke [mailto:hare@suse.de]

> > > Sent: Friday, December 18, 2015 12:52 AM

> > > To: KY Srinivasan <kys@microsoft.com>; gregkh@linuxfoundation.org;

> > > linux-

> > > kernel@vger.kernel.org; devel@linuxdriverproject.org;

> > > ohering@suse.com;

> > > jbottomley@parallels.com; hch@infradead.org;

> > > linux-scsi@vger.kernel.org;

> > > apw@canonical.com; vkuznets@redhat.com; jasowang@redhat.com;

> > > martin.petersen@oracle.com

> > > Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt

> > > path

> > >

> > > On 12/13/2015 09:28 PM, K. Y. Srinivasan wrote:

> > > > On the interrupt path, we repeatedly establish the pointer to the

> > > > storvsc_device. Fix this.

> > > >

> > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>

> > > > Reviewed-by: Long Li <longli@microsoft.com>

> > > > Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

> > > > Tested-by: Alex Ng <alexng@microsoft.com>

> > > > ---

> > > >   drivers/scsi/storvsc_drv.c |   23 ++++++++---------------

> > > >   1 files changed, 8 insertions(+), 15 deletions(-)

> > > >

> > > > diff --git a/drivers/scsi/storvsc_drv.c

> > > > b/drivers/scsi/storvsc_drv.c

> > > > index d6ca4f2..b68aebe 100644

> > > > --- a/drivers/scsi/storvsc_drv.c

> > > > +++ b/drivers/scsi/storvsc_drv.c

> > > > @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct

> > > vmscsi_request *vm_srb,

> > > >   }

> > > >

> > > >

> > > > -static void storvsc_command_completion(struct

> > > > storvsc_cmd_request

> > > *cmd_request)

> > > > +static void storvsc_command_completion(struct

> > > > storvsc_cmd_request

> > > *cmd_request,

> > > > +				       struct storvsc_device

> > > > *stor_dev)

> > > >   {

> > > >   	struct scsi_cmnd *scmnd = cmd_request->cmd;

> > > > -	struct hv_host_device *host_dev = shost_priv(scmnd

> > > > ->device-

> > > > host);

> > > >   	struct scsi_sense_hdr sense_hdr;

> > > >   	struct vmscsi_request *vm_srb;

> > > >   	struct Scsi_Host *host;

> > > > -	struct storvsc_device *stor_dev;

> > > > -	struct hv_device *dev = host_dev->dev;

> > > >   	u32 payload_sz = cmd_request->payload_sz;

> > > >   	void *payload = cmd_request->payload;

> > > >

> > > > -	stor_dev = get_in_stor_device(dev);

> > > >   	host = stor_dev->host;

> > > >

> > > >   	vm_srb = &cmd_request->vstor_packet.vm_srb;

> > > > @@ -987,14 +984,13 @@ static void

> > > > storvsc_command_completion(struct

> > > storvsc_cmd_request *cmd_request)

> > > >   		kfree(payload);

> > > >   }

> > > >

> > > > -static void storvsc_on_io_completion(struct hv_device *device,

> > > > +static void storvsc_on_io_completion(struct storvsc_device

> > > > *stor_device,

> > > >   				  struct vstor_packet

> > > > *vstor_packet,

> > > >   				  struct storvsc_cmd_request

> > > > *request)

> > > >   {

> > > > -	struct storvsc_device *stor_device;

> > > >   	struct vstor_packet *stor_pkt;

> > > > +	struct hv_device *device = stor_device->device;

> > > >

> > > > -	stor_device = hv_get_drvdata(device);

> > > >   	stor_pkt = &request->vstor_packet;

> > > >

> > > >   	/*

> > > > @@ -1049,7 +1045,7 @@ static void storvsc_on_io_completion(struct

> > > hv_device *device,

> > > >   	stor_pkt->vm_srb.data_transfer_length =

> > > >   	vstor_packet->vm_srb.data_transfer_length;

> > > >

> > > > -	storvsc_command_completion(request);

> > > > +	storvsc_command_completion(request, stor_device);

> > > >

> > > >   	if (atomic_dec_and_test(&stor_device

> > > > ->num_outstanding_req) &&

> > > >   		stor_device->drain_notify)

> > > > @@ -1058,21 +1054,19 @@ static void

> > > > storvsc_on_io_completion(struct

> > > hv_device *device,

> > > >

> > > >   }

> > > >

> > > > -static void storvsc_on_receive(struct hv_device *device,

> > > > +static void storvsc_on_receive(struct storvsc_device

> > > > *stor_device,

> > > >   			     struct vstor_packet *vstor_packet,

> > > >   			     struct storvsc_cmd_request

> > > > *request)

> > > >   {

> > > >   	struct storvsc_scan_work *work;

> > > > -	struct storvsc_device *stor_device;

> > > >

> > > >   	switch (vstor_packet->operation) {

> > > >   	case VSTOR_OPERATION_COMPLETE_IO:

> > > > -		storvsc_on_io_completion(device, vstor_packet,

> > > > request);

> > > > +		storvsc_on_io_completion(stor_device,

> > > > vstor_packet,

> > > request);

> > > >   		break;

> > > >

> > > >   	case VSTOR_OPERATION_REMOVE_DEVICE:

> > > >   	case VSTOR_OPERATION_ENUMERATE_BUS:

> > > > -		stor_device = get_in_stor_device(device);

> > > >   		work = kmalloc(sizeof(struct

> > > > storvsc_scan_work),

> > > GFP_ATOMIC);

> > > >   		if (!work)

> > > >   			return;

> > > > @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct

> > > > hv_device

> > > *device,

> > > >   		break;

> > > >

> > > >   	case VSTOR_OPERATION_FCHBA_DATA:

> > > > -		stor_device = get_in_stor_device(device);

> > > >   		cache_wwn(stor_device, vstor_packet);

> > > >   #ifdef CONFIG_SCSI_FC_ATTRS

> > > >   		fc_host_node_name(stor_device->host) =

> > > > stor_device-

> > > > node_name;

> > > > @@ -1133,7 +1126,7 @@ static void

> > > > storvsc_on_channel_callback(void

> > > *context)

> > > >   					vmscsi_size_delta));

> > > >   				complete(&request->wait_event);

> > > >   			} else {

> > > > -				storvsc_on_receive(device,

> > > > +				storvsc_on_receive(stor_device,

> > > >   						(struct

> > > > vstor_packet

> > > *)packet,

> > > >   						request);

> > > >   			}

> > > >

> > > Hmm. I would've thought the compiler optimizes this away. Have you

> > > checked whether it actually makes a difference in the assembler

> > > output?

> >

> > I have not checked the assembler output. It was easy enough to fix

> > the source.

> 

> Could you?  You're making what you describe as an optimisation but

> there are two reasons why this might not be so.  The first is that the

> compiler is entitled to inline static functions.  If it did, likely it

> picked up the optmisation anyway as Hannes suggested.  However, the

> other reason this might not be an optimisation (assuming the compiler

> doesn't inline the function) is you're passing an argument which can be

> offset computed.  On all architectures, you have a fixed number of

> registers for passing function arguments, then we have to use the

> stack.  Using the stack comes in far more expensive than computing an

> offset to an existing pointer.  Even if you're still in registers, the

> offset now has to be computed and stored and the compiler loses track

> of the relation.

> 

> The bottom line is that adding an extra argument for a value which can

> be offset computed is rarely a win.


James,
When I did this, I was mostly concerned about the cost of reestablishing state that was
already known. So, even with the function being in-lined, I felt the cost of reestablishing
state that was already known is unnecessary. In this particular case, I did not change the
number of arguments that were being passed; I just changed the type of one of them -
instead of passing struct hv_device *, I am now passing struct storvsc_device *. In the
current code, we are using struct hv_device * to establish a pointer to struct storvsc_device *
via the function get_in_stor_device(). This pattern currently exists in the call chain from the
interrupt handler - storvsc_on_channel_callback().

While the compiler is smart enough to inline both get_in_stor_device() as well as many of the static
functions in the call chain from storvsc_on_channel_callback(), looking at the assembled code,
the compiler is repeatedly inlining the call to get_in_stor_device() and this clearly is less than optimal.

Regards,

K. Y
Hannes Reinecke Dec. 21, 2015, 7:42 a.m. UTC | #5
On 12/19/2015 03:28 AM, KY Srinivasan wrote:
>
[ .. ]
>>
>> Could you?  You're making what you describe as an optimisation but
>> there are two reasons why this might not be so.  The first is that the
>> compiler is entitled to inline static functions.  If it did, likely it
>> picked up the optmisation anyway as Hannes suggested.  However, the
>> other reason this might not be an optimisation (assuming the compiler
>> doesn't inline the function) is you're passing an argument which can be
>> offset computed.  On all architectures, you have a fixed number of
>> registers for passing function arguments, then we have to use the
>> stack.  Using the stack comes in far more expensive than computing an
>> offset to an existing pointer.  Even if you're still in registers, the
>> offset now has to be computed and stored and the compiler loses track
>> of the relation.
>>
>> The bottom line is that adding an extra argument for a value which can
>> be offset computed is rarely a win.
>
> James,
> When I did this, I was mostly concerned about the cost of reestablishing state that was
> already known. So, even with the function being in-lined, I felt the cost of reestablishing
> state that was already known is unnecessary. In this particular case, I did not change the
> number of arguments that were being passed; I just changed the type of one of them -
> instead of passing struct hv_device *, I am now passing struct storvsc_device *. In the
> current code, we are using struct hv_device * to establish a pointer to struct storvsc_device *
> via the function get_in_stor_device(). This pattern currently exists in the call chain from the
> interrupt handler - storvsc_on_channel_callback().
>
> While the compiler is smart enough to inline both get_in_stor_device() as well as many of the static
> functions in the call chain from storvsc_on_channel_callback(), looking at the assembled code,
> the compiler is repeatedly inlining the call to get_in_stor_device() and this clearly is less than optimal.
>
Which means you actually checked the compiler output, and it made a 
difference.

That's all I wanted to know, as it's not immediately clear from the 
patch.

So:

Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
James Bottomley Dec. 21, 2015, 4:28 p.m. UTC | #6
On Sat, 2015-12-19 at 02:28 +0000, KY Srinivasan wrote:
> 
> > -----Original Message-----
> > From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com
> > ]
> > Sent: Friday, December 18, 2015 8:48 AM
> > To: KY Srinivasan <kys@microsoft.com>; Hannes Reinecke <
> > hare@suse.de>;
> > gregkh@linuxfoundation.org; linux-kernel@vger.kernel.org;
> > devel@linuxdriverproject.org; ohering@suse.com;
> > jbottomley@parallels.com; hch@infradead.org; 
> > linux-scsi@vger.kernel.org;
> > apw@canonical.com; vkuznets@redhat.com; jasowang@redhat.com;
> > martin.petersen@oracle.com
> > Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the interrupt
> > path
> > 
> > On Fri, 2015-12-18 at 16:20 +0000, KY Srinivasan wrote:
> > > 
> > > > -----Original Message-----
> > > > From: Hannes Reinecke [mailto:hare@suse.de]
> > > > Sent: Friday, December 18, 2015 12:52 AM
> > > > To: KY Srinivasan <kys@microsoft.com>; 
> > > > gregkh@linuxfoundation.org;
> > > > linux-
> > > > kernel@vger.kernel.org; devel@linuxdriverproject.org;
> > > > ohering@suse.com;
> > > > jbottomley@parallels.com; hch@infradead.org;
> > > > linux-scsi@vger.kernel.org;
> > > > apw@canonical.com; vkuznets@redhat.com; jasowang@redhat.com;
> > > > martin.petersen@oracle.com
> > > > Subject: Re: [PATCH V3 4/4] scsi: storvsc: Tighten up the
> > > > interrupt
> > > > path
> > > > 
> > > > On 12/13/2015 09:28 PM, K. Y. Srinivasan wrote:
> > > > > On the interrupt path, we repeatedly establish the pointer to
> > > > > the
> > > > > storvsc_device. Fix this.
> > > > > 
> > > > > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > > > > Reviewed-by: Long Li <longli@microsoft.com>
> > > > > Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> > > > > Tested-by: Alex Ng <alexng@microsoft.com>
> > > > > ---
> > > > >   drivers/scsi/storvsc_drv.c |   23 ++++++++---------------
> > > > >   1 files changed, 8 insertions(+), 15 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/scsi/storvsc_drv.c
> > > > > b/drivers/scsi/storvsc_drv.c
> > > > > index d6ca4f2..b68aebe 100644
> > > > > --- a/drivers/scsi/storvsc_drv.c
> > > > > +++ b/drivers/scsi/storvsc_drv.c
> > > > > @@ -945,19 +945,16 @@ static void storvsc_handle_error(struct
> > > > vmscsi_request *vm_srb,
> > > > >   }
> > > > > 
> > > > > 
> > > > > -static void storvsc_command_completion(struct
> > > > > storvsc_cmd_request
> > > > *cmd_request)
> > > > > +static void storvsc_command_completion(struct
> > > > > storvsc_cmd_request
> > > > *cmd_request,
> > > > > +				       struct storvsc_device
> > > > > *stor_dev)
> > > > >   {
> > > > >   	struct scsi_cmnd *scmnd = cmd_request->cmd;
> > > > > -	struct hv_host_device *host_dev = shost_priv(scmnd
> > > > > ->device-
> > > > > host);
> > > > >   	struct scsi_sense_hdr sense_hdr;
> > > > >   	struct vmscsi_request *vm_srb;
> > > > >   	struct Scsi_Host *host;
> > > > > -	struct storvsc_device *stor_dev;
> > > > > -	struct hv_device *dev = host_dev->dev;
> > > > >   	u32 payload_sz = cmd_request->payload_sz;
> > > > >   	void *payload = cmd_request->payload;
> > > > > 
> > > > > -	stor_dev = get_in_stor_device(dev);
> > > > >   	host = stor_dev->host;
> > > > > 
> > > > >   	vm_srb = &cmd_request->vstor_packet.vm_srb;
> > > > > @@ -987,14 +984,13 @@ static void
> > > > > storvsc_command_completion(struct
> > > > storvsc_cmd_request *cmd_request)
> > > > >   		kfree(payload);
> > > > >   }
> > > > > 
> > > > > -static void storvsc_on_io_completion(struct hv_device
> > > > > *device,
> > > > > +static void storvsc_on_io_completion(struct storvsc_device
> > > > > *stor_device,
> > > > >   				  struct vstor_packet
> > > > > *vstor_packet,
> > > > >   				  struct
> > > > > storvsc_cmd_request
> > > > > *request)
> > > > >   {
> > > > > -	struct storvsc_device *stor_device;
> > > > >   	struct vstor_packet *stor_pkt;
> > > > > +	struct hv_device *device = stor_device->device;
> > > > > 
> > > > > -	stor_device = hv_get_drvdata(device);
> > > > >   	stor_pkt = &request->vstor_packet;
> > > > > 
> > > > >   	/*
> > > > > @@ -1049,7 +1045,7 @@ static void
> > > > > storvsc_on_io_completion(struct
> > > > hv_device *device,
> > > > >   	stor_pkt->vm_srb.data_transfer_length =
> > > > >   	vstor_packet->vm_srb.data_transfer_length;
> > > > > 
> > > > > -	storvsc_command_completion(request);
> > > > > +	storvsc_command_completion(request, stor_device);
> > > > > 
> > > > >   	if (atomic_dec_and_test(&stor_device
> > > > > ->num_outstanding_req) &&
> > > > >   		stor_device->drain_notify)
> > > > > @@ -1058,21 +1054,19 @@ static void
> > > > > storvsc_on_io_completion(struct
> > > > hv_device *device,
> > > > > 
> > > > >   }
> > > > > 
> > > > > -static void storvsc_on_receive(struct hv_device *device,
> > > > > +static void storvsc_on_receive(struct storvsc_device
> > > > > *stor_device,
> > > > >   			     struct vstor_packet
> > > > > *vstor_packet,
> > > > >   			     struct storvsc_cmd_request
> > > > > *request)
> > > > >   {
> > > > >   	struct storvsc_scan_work *work;
> > > > > -	struct storvsc_device *stor_device;
> > > > > 
> > > > >   	switch (vstor_packet->operation) {
> > > > >   	case VSTOR_OPERATION_COMPLETE_IO:
> > > > > -		storvsc_on_io_completion(device,
> > > > > vstor_packet,
> > > > > request);
> > > > > +		storvsc_on_io_completion(stor_device,
> > > > > vstor_packet,
> > > > request);
> > > > >   		break;
> > > > > 
> > > > >   	case VSTOR_OPERATION_REMOVE_DEVICE:
> > > > >   	case VSTOR_OPERATION_ENUMERATE_BUS:
> > > > > -		stor_device = get_in_stor_device(device);
> > > > >   		work = kmalloc(sizeof(struct
> > > > > storvsc_scan_work),
> > > > GFP_ATOMIC);
> > > > >   		if (!work)
> > > > >   			return;
> > > > > @@ -1083,7 +1077,6 @@ static void storvsc_on_receive(struct
> > > > > hv_device
> > > > *device,
> > > > >   		break;
> > > > > 
> > > > >   	case VSTOR_OPERATION_FCHBA_DATA:
> > > > > -		stor_device = get_in_stor_device(device);
> > > > >   		cache_wwn(stor_device, vstor_packet);
> > > > >   #ifdef CONFIG_SCSI_FC_ATTRS
> > > > >   		fc_host_node_name(stor_device->host) =
> > > > > stor_device-
> > > > > node_name;
> > > > > @@ -1133,7 +1126,7 @@ static void
> > > > > storvsc_on_channel_callback(void
> > > > *context)
> > > > >   					vmscsi_size_delta))
> > > > > ;
> > > > >   				complete(&request
> > > > > ->wait_event);
> > > > >   			} else {
> > > > > -				storvsc_on_receive(device,
> > > > > +				storvsc_on_receive(stor_devi
> > > > > ce,
> > > > >   						(struct
> > > > > vstor_packet
> > > > *)packet,
> > > > >   						request);
> > > > >   			}
> > > > > 
> > > > Hmm. I would've thought the compiler optimizes this away. Have
> > > > you
> > > > checked whether it actually makes a difference in the assembler
> > > > output?
> > > 
> > > I have not checked the assembler output. It was easy enough to
> > > fix
> > > the source.
> > 
> > Could you?  You're making what you describe as an optimisation but
> > there are two reasons why this might not be so.  The first is that
> > the
> > compiler is entitled to inline static functions.  If it did, likely
> > it
> > picked up the optmisation anyway as Hannes suggested.  However, the
> > other reason this might not be an optimisation (assuming the
> > compiler
> > doesn't inline the function) is you're passing an argument which
> > can be
> > offset computed.  On all architectures, you have a fixed number of
> > registers for passing function arguments, then we have to use the
> > stack.  Using the stack comes in far more expensive than computing
> > an
> > offset to an existing pointer.  Even if you're still in registers,
> > the
> > offset now has to be computed and stored and the compiler loses
> > track
> > of the relation.
> > 
> > The bottom line is that adding an extra argument for a value which
> > can
> > be offset computed is rarely a win.
> 
> James,
> When I did this, I was mostly concerned about the cost of
> reestablishing state that was
> already known. So, even with the function being in-lined, I felt the
> cost of reestablishing
> state that was already known is unnecessary. In this particular case,
> I did not change the
> number of arguments that were being passed; I just changed the type
> of one of them -
> instead of passing struct hv_device *, I am now passing struct
> storvsc_device *. In the
> current code, we are using struct hv_device * to establish a pointer
> to struct storvsc_device *
> via the function get_in_stor_device(). This pattern currently exists
> in the call chain from the
> interrupt handler - storvsc_on_channel_callback().
> 
> While the compiler is smart enough to inline both
> get_in_stor_device() as well as many of the static
> functions in the call chain from storvsc_on_channel_callback(),
> looking at the assembled code,
> the compiler is repeatedly inlining the call to get_in_stor_device() 
> and this clearly is less than optimal.

OK, so the reason for the recomputation is the destruction condition
check which is evaluated every time you call it?  Perhaps what you
simply want is an __get_in_stor_device() that does the offset
mathematics without the destruction check.  It's doing exactly what
passing the additional parameter does: the calling function is taking
on the burden of verifying they've got a device which is still valid.

I'm not making this a hard requirement for reviewing the code: you have
arguments to spare in the functions, so I don't think it matters which
way this is done.  I do, however, think it makes consumers of the stor
device think about why they're using it and whether they actually need
the destruct check.

James


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
KY Srinivasan Dec. 21, 2015, 7:40 p.m. UTC | #7
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogSmFtZXMgQm90dG9tbGV5
IFttYWlsdG86SmFtZXMuQm90dG9tbGV5QEhhbnNlblBhcnRuZXJzaGlwLmNvbV0NCj4gU2VudDog
TW9uZGF5LCBEZWNlbWJlciAyMSwgMjAxNSA4OjI4IEFNDQo+IFRvOiBLWSBTcmluaXZhc2FuIDxr
eXNAbWljcm9zb2Z0LmNvbT47IEhhbm5lcyBSZWluZWNrZSA8aGFyZUBzdXNlLmRlPjsNCj4gZ3Jl
Z2toQGxpbnV4Zm91bmRhdGlvbi5vcmc7IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7DQo+
IGRldmVsQGxpbnV4ZHJpdmVycHJvamVjdC5vcmc7IG9oZXJpbmdAc3VzZS5jb207DQo+IGpib3R0
b21sZXlAcGFyYWxsZWxzLmNvbTsgaGNoQGluZnJhZGVhZC5vcmc7IGxpbnV4LXNjc2lAdmdlci5r
ZXJuZWwub3JnOw0KPiBhcHdAY2Fub25pY2FsLmNvbTsgdmt1em5ldHNAcmVkaGF0LmNvbTsgamFz
b3dhbmdAcmVkaGF0LmNvbTsNCj4gbWFydGluLnBldGVyc2VuQG9yYWNsZS5jb20NCj4gU3ViamVj
dDogUmU6IFtQQVRDSCBWMyA0LzRdIHNjc2k6IHN0b3J2c2M6IFRpZ2h0ZW4gdXAgdGhlIGludGVy
cnVwdCBwYXRoDQo+IA0KPiBPbiBTYXQsIDIwMTUtMTItMTkgYXQgMDI6MjggKzAwMDAsIEtZIFNy
aW5pdmFzYW4gd3JvdGU6DQo+ID4NCj4gPiA+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+
ID4gPiBGcm9tOiBKYW1lcyBCb3R0b21sZXkNCj4gW21haWx0bzpKYW1lcy5Cb3R0b21sZXlASGFu
c2VuUGFydG5lcnNoaXAuY29tDQo+ID4gPiBdDQo+ID4gPiBTZW50OiBGcmlkYXksIERlY2VtYmVy
IDE4LCAyMDE1IDg6NDggQU0NCj4gPiA+IFRvOiBLWSBTcmluaXZhc2FuIDxreXNAbWljcm9zb2Z0
LmNvbT47IEhhbm5lcyBSZWluZWNrZSA8DQo+ID4gPiBoYXJlQHN1c2UuZGU+Ow0KPiA+ID4gZ3Jl
Z2toQGxpbnV4Zm91bmRhdGlvbi5vcmc7IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7DQo+
ID4gPiBkZXZlbEBsaW51eGRyaXZlcnByb2plY3Qub3JnOyBvaGVyaW5nQHN1c2UuY29tOw0KPiA+
ID4gamJvdHRvbWxleUBwYXJhbGxlbHMuY29tOyBoY2hAaW5mcmFkZWFkLm9yZzsNCj4gPiA+IGxp
bnV4LXNjc2lAdmdlci5rZXJuZWwub3JnOw0KPiA+ID4gYXB3QGNhbm9uaWNhbC5jb207IHZrdXpu
ZXRzQHJlZGhhdC5jb207IGphc293YW5nQHJlZGhhdC5jb207DQo+ID4gPiBtYXJ0aW4ucGV0ZXJz
ZW5Ab3JhY2xlLmNvbQ0KPiA+ID4gU3ViamVjdDogUmU6IFtQQVRDSCBWMyA0LzRdIHNjc2k6IHN0
b3J2c2M6IFRpZ2h0ZW4gdXAgdGhlIGludGVycnVwdA0KPiA+ID4gcGF0aA0KPiA+ID4NCj4gPiA+
IE9uIEZyaSwgMjAxNS0xMi0xOCBhdCAxNjoyMCArMDAwMCwgS1kgU3Jpbml2YXNhbiB3cm90ZToN
Cj4gPiA+ID4NCj4gPiA+ID4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+ID4gPiA+
IEZyb206IEhhbm5lcyBSZWluZWNrZSBbbWFpbHRvOmhhcmVAc3VzZS5kZV0NCj4gPiA+ID4gPiBT
ZW50OiBGcmlkYXksIERlY2VtYmVyIDE4LCAyMDE1IDEyOjUyIEFNDQo+ID4gPiA+ID4gVG86IEtZ
IFNyaW5pdmFzYW4gPGt5c0BtaWNyb3NvZnQuY29tPjsNCj4gPiA+ID4gPiBncmVna2hAbGludXhm
b3VuZGF0aW9uLm9yZzsNCj4gPiA+ID4gPiBsaW51eC0NCj4gPiA+ID4gPiBrZXJuZWxAdmdlci5r
ZXJuZWwub3JnOyBkZXZlbEBsaW51eGRyaXZlcnByb2plY3Qub3JnOw0KPiA+ID4gPiA+IG9oZXJp
bmdAc3VzZS5jb207DQo+ID4gPiA+ID4gamJvdHRvbWxleUBwYXJhbGxlbHMuY29tOyBoY2hAaW5m
cmFkZWFkLm9yZzsNCj4gPiA+ID4gPiBsaW51eC1zY3NpQHZnZXIua2VybmVsLm9yZzsNCj4gPiA+
ID4gPiBhcHdAY2Fub25pY2FsLmNvbTsgdmt1em5ldHNAcmVkaGF0LmNvbTsgamFzb3dhbmdAcmVk
aGF0LmNvbTsNCj4gPiA+ID4gPiBtYXJ0aW4ucGV0ZXJzZW5Ab3JhY2xlLmNvbQ0KPiA+ID4gPiA+
IFN1YmplY3Q6IFJlOiBbUEFUQ0ggVjMgNC80XSBzY3NpOiBzdG9ydnNjOiBUaWdodGVuIHVwIHRo
ZQ0KPiA+ID4gPiA+IGludGVycnVwdA0KPiA+ID4gPiA+IHBhdGgNCj4gPiA+ID4gPg0KPiA+ID4g
PiA+IE9uIDEyLzEzLzIwMTUgMDk6MjggUE0sIEsuIFkuIFNyaW5pdmFzYW4gd3JvdGU6DQo+ID4g
PiA+ID4gPiBPbiB0aGUgaW50ZXJydXB0IHBhdGgsIHdlIHJlcGVhdGVkbHkgZXN0YWJsaXNoIHRo
ZSBwb2ludGVyIHRvDQo+ID4gPiA+ID4gPiB0aGUNCj4gPiA+ID4gPiA+IHN0b3J2c2NfZGV2aWNl
LiBGaXggdGhpcy4NCj4gPiA+ID4gPiA+DQo+ID4gPiA+ID4gPiBTaWduZWQtb2ZmLWJ5OiBLLiBZ
LiBTcmluaXZhc2FuIDxreXNAbWljcm9zb2Z0LmNvbT4NCj4gPiA+ID4gPiA+IFJldmlld2VkLWJ5
OiBMb25nIExpIDxsb25nbGlAbWljcm9zb2Z0LmNvbT4NCj4gPiA+ID4gPiA+IFJldmlld2VkLWJ5
OiBKb2hhbm5lcyBUaHVtc2hpcm4gPGp0aHVtc2hpcm5Ac3VzZS5kZT4NCj4gPiA+ID4gPiA+IFRl
c3RlZC1ieTogQWxleCBOZyA8YWxleG5nQG1pY3Jvc29mdC5jb20+DQo+ID4gPiA+ID4gPiAtLS0N
Cj4gPiA+ID4gPiA+ICAgZHJpdmVycy9zY3NpL3N0b3J2c2NfZHJ2LmMgfCAgIDIzICsrKysrKysr
LS0tLS0tLS0tLS0tLS0tDQo+ID4gPiA+ID4gPiAgIDEgZmlsZXMgY2hhbmdlZCwgOCBpbnNlcnRp
b25zKCspLCAxNSBkZWxldGlvbnMoLSkNCj4gPiA+ID4gPiA+DQo+ID4gPiA+ID4gPiBkaWZmIC0t
Z2l0IGEvZHJpdmVycy9zY3NpL3N0b3J2c2NfZHJ2LmMNCj4gPiA+ID4gPiA+IGIvZHJpdmVycy9z
Y3NpL3N0b3J2c2NfZHJ2LmMNCj4gPiA+ID4gPiA+IGluZGV4IGQ2Y2E0ZjIuLmI2OGFlYmUgMTAw
NjQ0DQo+ID4gPiA+ID4gPiAtLS0gYS9kcml2ZXJzL3Njc2kvc3RvcnZzY19kcnYuYw0KPiA+ID4g
PiA+ID4gKysrIGIvZHJpdmVycy9zY3NpL3N0b3J2c2NfZHJ2LmMNCj4gPiA+ID4gPiA+IEBAIC05
NDUsMTkgKzk0NSwxNiBAQCBzdGF0aWMgdm9pZCBzdG9ydnNjX2hhbmRsZV9lcnJvcihzdHJ1Y3QN
Cj4gPiA+ID4gPiB2bXNjc2lfcmVxdWVzdCAqdm1fc3JiLA0KPiA+ID4gPiA+ID4gICB9DQo+ID4g
PiA+ID4gPg0KPiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+IC1zdGF0aWMgdm9pZCBzdG9ydnNjX2Nv
bW1hbmRfY29tcGxldGlvbihzdHJ1Y3QNCj4gPiA+ID4gPiA+IHN0b3J2c2NfY21kX3JlcXVlc3QN
Cj4gPiA+ID4gPiAqY21kX3JlcXVlc3QpDQo+ID4gPiA+ID4gPiArc3RhdGljIHZvaWQgc3RvcnZz
Y19jb21tYW5kX2NvbXBsZXRpb24oc3RydWN0DQo+ID4gPiA+ID4gPiBzdG9ydnNjX2NtZF9yZXF1
ZXN0DQo+ID4gPiA+ID4gKmNtZF9yZXF1ZXN0LA0KPiA+ID4gPiA+ID4gKwkJCQkgICAgICAgc3Ry
dWN0IHN0b3J2c2NfZGV2aWNlDQo+ID4gPiA+ID4gPiAqc3Rvcl9kZXYpDQo+ID4gPiA+ID4gPiAg
IHsNCj4gPiA+ID4gPiA+ICAgCXN0cnVjdCBzY3NpX2NtbmQgKnNjbW5kID0gY21kX3JlcXVlc3Qt
PmNtZDsNCj4gPiA+ID4gPiA+IC0Jc3RydWN0IGh2X2hvc3RfZGV2aWNlICpob3N0X2RldiA9IHNo
b3N0X3ByaXYoc2NtbmQNCj4gPiA+ID4gPiA+IC0+ZGV2aWNlLQ0KPiA+ID4gPiA+ID4gaG9zdCk7
DQo+ID4gPiA+ID4gPiAgIAlzdHJ1Y3Qgc2NzaV9zZW5zZV9oZHIgc2Vuc2VfaGRyOw0KPiA+ID4g
PiA+ID4gICAJc3RydWN0IHZtc2NzaV9yZXF1ZXN0ICp2bV9zcmI7DQo+ID4gPiA+ID4gPiAgIAlz
dHJ1Y3QgU2NzaV9Ib3N0ICpob3N0Ow0KPiA+ID4gPiA+ID4gLQlzdHJ1Y3Qgc3RvcnZzY19kZXZp
Y2UgKnN0b3JfZGV2Ow0KPiA+ID4gPiA+ID4gLQlzdHJ1Y3QgaHZfZGV2aWNlICpkZXYgPSBob3N0
X2Rldi0+ZGV2Ow0KPiA+ID4gPiA+ID4gICAJdTMyIHBheWxvYWRfc3ogPSBjbWRfcmVxdWVzdC0+
cGF5bG9hZF9zejsNCj4gPiA+ID4gPiA+ICAgCXZvaWQgKnBheWxvYWQgPSBjbWRfcmVxdWVzdC0+
cGF5bG9hZDsNCj4gPiA+ID4gPiA+DQo+ID4gPiA+ID4gPiAtCXN0b3JfZGV2ID0gZ2V0X2luX3N0
b3JfZGV2aWNlKGRldik7DQo+ID4gPiA+ID4gPiAgIAlob3N0ID0gc3Rvcl9kZXYtPmhvc3Q7DQo+
ID4gPiA+ID4gPg0KPiA+ID4gPiA+ID4gICAJdm1fc3JiID0gJmNtZF9yZXF1ZXN0LT52c3Rvcl9w
YWNrZXQudm1fc3JiOw0KPiA+ID4gPiA+ID4gQEAgLTk4NywxNCArOTg0LDEzIEBAIHN0YXRpYyB2
b2lkDQo+ID4gPiA+ID4gPiBzdG9ydnNjX2NvbW1hbmRfY29tcGxldGlvbihzdHJ1Y3QNCj4gPiA+
ID4gPiBzdG9ydnNjX2NtZF9yZXF1ZXN0ICpjbWRfcmVxdWVzdCkNCj4gPiA+ID4gPiA+ICAgCQlr
ZnJlZShwYXlsb2FkKTsNCj4gPiA+ID4gPiA+ICAgfQ0KPiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+
IC1zdGF0aWMgdm9pZCBzdG9ydnNjX29uX2lvX2NvbXBsZXRpb24oc3RydWN0IGh2X2RldmljZQ0K
PiA+ID4gPiA+ID4gKmRldmljZSwNCj4gPiA+ID4gPiA+ICtzdGF0aWMgdm9pZCBzdG9ydnNjX29u
X2lvX2NvbXBsZXRpb24oc3RydWN0IHN0b3J2c2NfZGV2aWNlDQo+ID4gPiA+ID4gPiAqc3Rvcl9k
ZXZpY2UsDQo+ID4gPiA+ID4gPiAgIAkJCQkgIHN0cnVjdCB2c3Rvcl9wYWNrZXQNCj4gPiA+ID4g
PiA+ICp2c3Rvcl9wYWNrZXQsDQo+ID4gPiA+ID4gPiAgIAkJCQkgIHN0cnVjdA0KPiA+ID4gPiA+
ID4gc3RvcnZzY19jbWRfcmVxdWVzdA0KPiA+ID4gPiA+ID4gKnJlcXVlc3QpDQo+ID4gPiA+ID4g
PiAgIHsNCj4gPiA+ID4gPiA+IC0Jc3RydWN0IHN0b3J2c2NfZGV2aWNlICpzdG9yX2RldmljZTsN
Cj4gPiA+ID4gPiA+ICAgCXN0cnVjdCB2c3Rvcl9wYWNrZXQgKnN0b3JfcGt0Ow0KPiA+ID4gPiA+
ID4gKwlzdHJ1Y3QgaHZfZGV2aWNlICpkZXZpY2UgPSBzdG9yX2RldmljZS0+ZGV2aWNlOw0KPiA+
ID4gPiA+ID4NCj4gPiA+ID4gPiA+IC0Jc3Rvcl9kZXZpY2UgPSBodl9nZXRfZHJ2ZGF0YShkZXZp
Y2UpOw0KPiA+ID4gPiA+ID4gICAJc3Rvcl9wa3QgPSAmcmVxdWVzdC0+dnN0b3JfcGFja2V0Ow0K
PiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+ICAgCS8qDQo+ID4gPiA+ID4gPiBAQCAtMTA0OSw3ICsx
MDQ1LDcgQEAgc3RhdGljIHZvaWQNCj4gPiA+ID4gPiA+IHN0b3J2c2Nfb25faW9fY29tcGxldGlv
bihzdHJ1Y3QNCj4gPiA+ID4gPiBodl9kZXZpY2UgKmRldmljZSwNCj4gPiA+ID4gPiA+ICAgCXN0
b3JfcGt0LT52bV9zcmIuZGF0YV90cmFuc2Zlcl9sZW5ndGggPQ0KPiA+ID4gPiA+ID4gICAJdnN0
b3JfcGFja2V0LT52bV9zcmIuZGF0YV90cmFuc2Zlcl9sZW5ndGg7DQo+ID4gPiA+ID4gPg0KPiA+
ID4gPiA+ID4gLQlzdG9ydnNjX2NvbW1hbmRfY29tcGxldGlvbihyZXF1ZXN0KTsNCj4gPiA+ID4g
PiA+ICsJc3RvcnZzY19jb21tYW5kX2NvbXBsZXRpb24ocmVxdWVzdCwgc3Rvcl9kZXZpY2UpOw0K
PiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+ICAgCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZzdG9y
X2RldmljZQ0KPiA+ID4gPiA+ID4gLT5udW1fb3V0c3RhbmRpbmdfcmVxKSAmJg0KPiA+ID4gPiA+
ID4gICAJCXN0b3JfZGV2aWNlLT5kcmFpbl9ub3RpZnkpDQo+ID4gPiA+ID4gPiBAQCAtMTA1OCwy
MSArMTA1NCwxOSBAQCBzdGF0aWMgdm9pZA0KPiA+ID4gPiA+ID4gc3RvcnZzY19vbl9pb19jb21w
bGV0aW9uKHN0cnVjdA0KPiA+ID4gPiA+IGh2X2RldmljZSAqZGV2aWNlLA0KPiA+ID4gPiA+ID4N
Cj4gPiA+ID4gPiA+ICAgfQ0KPiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+IC1zdGF0aWMgdm9pZCBz
dG9ydnNjX29uX3JlY2VpdmUoc3RydWN0IGh2X2RldmljZSAqZGV2aWNlLA0KPiA+ID4gPiA+ID4g
K3N0YXRpYyB2b2lkIHN0b3J2c2Nfb25fcmVjZWl2ZShzdHJ1Y3Qgc3RvcnZzY19kZXZpY2UNCj4g
PiA+ID4gPiA+ICpzdG9yX2RldmljZSwNCj4gPiA+ID4gPiA+ICAgCQkJICAgICBzdHJ1Y3QgdnN0
b3JfcGFja2V0DQo+ID4gPiA+ID4gPiAqdnN0b3JfcGFja2V0LA0KPiA+ID4gPiA+ID4gICAJCQkg
ICAgIHN0cnVjdCBzdG9ydnNjX2NtZF9yZXF1ZXN0DQo+ID4gPiA+ID4gPiAqcmVxdWVzdCkNCj4g
PiA+ID4gPiA+ICAgew0KPiA+ID4gPiA+ID4gICAJc3RydWN0IHN0b3J2c2Nfc2Nhbl93b3JrICp3
b3JrOw0KPiA+ID4gPiA+ID4gLQlzdHJ1Y3Qgc3RvcnZzY19kZXZpY2UgKnN0b3JfZGV2aWNlOw0K
PiA+ID4gPiA+ID4NCj4gPiA+ID4gPiA+ICAgCXN3aXRjaCAodnN0b3JfcGFja2V0LT5vcGVyYXRp
b24pIHsNCj4gPiA+ID4gPiA+ICAgCWNhc2UgVlNUT1JfT1BFUkFUSU9OX0NPTVBMRVRFX0lPOg0K
PiA+ID4gPiA+ID4gLQkJc3RvcnZzY19vbl9pb19jb21wbGV0aW9uKGRldmljZSwNCj4gPiA+ID4g
PiA+IHZzdG9yX3BhY2tldCwNCj4gPiA+ID4gPiA+IHJlcXVlc3QpOw0KPiA+ID4gPiA+ID4gKwkJ
c3RvcnZzY19vbl9pb19jb21wbGV0aW9uKHN0b3JfZGV2aWNlLA0KPiA+ID4gPiA+ID4gdnN0b3Jf
cGFja2V0LA0KPiA+ID4gPiA+IHJlcXVlc3QpOw0KPiA+ID4gPiA+ID4gICAJCWJyZWFrOw0KPiA+
ID4gPiA+ID4NCj4gPiA+ID4gPiA+ICAgCWNhc2UgVlNUT1JfT1BFUkFUSU9OX1JFTU9WRV9ERVZJ
Q0U6DQo+ID4gPiA+ID4gPiAgIAljYXNlIFZTVE9SX09QRVJBVElPTl9FTlVNRVJBVEVfQlVTOg0K
PiA+ID4gPiA+ID4gLQkJc3Rvcl9kZXZpY2UgPSBnZXRfaW5fc3Rvcl9kZXZpY2UoZGV2aWNlKTsN
Cj4gPiA+ID4gPiA+ICAgCQl3b3JrID0ga21hbGxvYyhzaXplb2Yoc3RydWN0DQo+ID4gPiA+ID4g
PiBzdG9ydnNjX3NjYW5fd29yayksDQo+ID4gPiA+ID4gR0ZQX0FUT01JQyk7DQo+ID4gPiA+ID4g
PiAgIAkJaWYgKCF3b3JrKQ0KPiA+ID4gPiA+ID4gICAJCQlyZXR1cm47DQo+ID4gPiA+ID4gPiBA
QCAtMTA4Myw3ICsxMDc3LDYgQEAgc3RhdGljIHZvaWQgc3RvcnZzY19vbl9yZWNlaXZlKHN0cnVj
dA0KPiA+ID4gPiA+ID4gaHZfZGV2aWNlDQo+ID4gPiA+ID4gKmRldmljZSwNCj4gPiA+ID4gPiA+
ICAgCQlicmVhazsNCj4gPiA+ID4gPiA+DQo+ID4gPiA+ID4gPiAgIAljYXNlIFZTVE9SX09QRVJB
VElPTl9GQ0hCQV9EQVRBOg0KPiA+ID4gPiA+ID4gLQkJc3Rvcl9kZXZpY2UgPSBnZXRfaW5fc3Rv
cl9kZXZpY2UoZGV2aWNlKTsNCj4gPiA+ID4gPiA+ICAgCQljYWNoZV93d24oc3Rvcl9kZXZpY2Us
IHZzdG9yX3BhY2tldCk7DQo+ID4gPiA+ID4gPiAgICNpZmRlZiBDT05GSUdfU0NTSV9GQ19BVFRS
Uw0KPiA+ID4gPiA+ID4gICAJCWZjX2hvc3Rfbm9kZV9uYW1lKHN0b3JfZGV2aWNlLT5ob3N0KSA9
DQo+ID4gPiA+ID4gPiBzdG9yX2RldmljZS0NCj4gPiA+ID4gPiA+IG5vZGVfbmFtZTsNCj4gPiA+
ID4gPiA+IEBAIC0xMTMzLDcgKzExMjYsNyBAQCBzdGF0aWMgdm9pZA0KPiA+ID4gPiA+ID4gc3Rv
cnZzY19vbl9jaGFubmVsX2NhbGxiYWNrKHZvaWQNCj4gPiA+ID4gPiAqY29udGV4dCkNCj4gPiA+
ID4gPiA+ICAgCQkJCQl2bXNjc2lfc2l6ZV9kZWx0YSkpDQo+ID4gPiA+ID4gPiA7DQo+ID4gPiA+
ID4gPiAgIAkJCQljb21wbGV0ZSgmcmVxdWVzdA0KPiA+ID4gPiA+ID4gLT53YWl0X2V2ZW50KTsN
Cj4gPiA+ID4gPiA+ICAgCQkJfSBlbHNlIHsNCj4gPiA+ID4gPiA+IC0JCQkJc3RvcnZzY19vbl9y
ZWNlaXZlKGRldmljZSwNCj4gPiA+ID4gPiA+ICsJCQkJc3RvcnZzY19vbl9yZWNlaXZlKHN0b3Jf
ZGV2aQ0KPiA+ID4gPiA+ID4gY2UsDQo+ID4gPiA+ID4gPiAgIAkJCQkJCShzdHJ1Y3QNCj4gPiA+
ID4gPiA+IHZzdG9yX3BhY2tldA0KPiA+ID4gPiA+ICopcGFja2V0LA0KPiA+ID4gPiA+ID4gICAJ
CQkJCQlyZXF1ZXN0KTsNCj4gPiA+ID4gPiA+ICAgCQkJfQ0KPiA+ID4gPiA+ID4NCj4gPiA+ID4g
PiBIbW0uIEkgd291bGQndmUgdGhvdWdodCB0aGUgY29tcGlsZXIgb3B0aW1pemVzIHRoaXMgYXdh
eS4gSGF2ZQ0KPiA+ID4gPiA+IHlvdQ0KPiA+ID4gPiA+IGNoZWNrZWQgd2hldGhlciBpdCBhY3R1
YWxseSBtYWtlcyBhIGRpZmZlcmVuY2UgaW4gdGhlIGFzc2VtYmxlcg0KPiA+ID4gPiA+IG91dHB1
dD8NCj4gPiA+ID4NCj4gPiA+ID4gSSBoYXZlIG5vdCBjaGVja2VkIHRoZSBhc3NlbWJsZXIgb3V0
cHV0LiBJdCB3YXMgZWFzeSBlbm91Z2ggdG8NCj4gPiA+ID4gZml4DQo+ID4gPiA+IHRoZSBzb3Vy
Y2UuDQo+ID4gPg0KPiA+ID4gQ291bGQgeW91PyAgWW91J3JlIG1ha2luZyB3aGF0IHlvdSBkZXNj
cmliZSBhcyBhbiBvcHRpbWlzYXRpb24gYnV0DQo+ID4gPiB0aGVyZSBhcmUgdHdvIHJlYXNvbnMg
d2h5IHRoaXMgbWlnaHQgbm90IGJlIHNvLiAgVGhlIGZpcnN0IGlzIHRoYXQNCj4gPiA+IHRoZQ0K
PiA+ID4gY29tcGlsZXIgaXMgZW50aXRsZWQgdG8gaW5saW5lIHN0YXRpYyBmdW5jdGlvbnMuICBJ
ZiBpdCBkaWQsIGxpa2VseQ0KPiA+ID4gaXQNCj4gPiA+IHBpY2tlZCB1cCB0aGUgb3B0bWlzYXRp
b24gYW55d2F5IGFzIEhhbm5lcyBzdWdnZXN0ZWQuICBIb3dldmVyLCB0aGUNCj4gPiA+IG90aGVy
IHJlYXNvbiB0aGlzIG1pZ2h0IG5vdCBiZSBhbiBvcHRpbWlzYXRpb24gKGFzc3VtaW5nIHRoZQ0K
PiA+ID4gY29tcGlsZXINCj4gPiA+IGRvZXNuJ3QgaW5saW5lIHRoZSBmdW5jdGlvbikgaXMgeW91
J3JlIHBhc3NpbmcgYW4gYXJndW1lbnQgd2hpY2gNCj4gPiA+IGNhbiBiZQ0KPiA+ID4gb2Zmc2V0
IGNvbXB1dGVkLiAgT24gYWxsIGFyY2hpdGVjdHVyZXMsIHlvdSBoYXZlIGEgZml4ZWQgbnVtYmVy
IG9mDQo+ID4gPiByZWdpc3RlcnMgZm9yIHBhc3NpbmcgZnVuY3Rpb24gYXJndW1lbnRzLCB0aGVu
IHdlIGhhdmUgdG8gdXNlIHRoZQ0KPiA+ID4gc3RhY2suICBVc2luZyB0aGUgc3RhY2sgY29tZXMg
aW4gZmFyIG1vcmUgZXhwZW5zaXZlIHRoYW4gY29tcHV0aW5nDQo+ID4gPiBhbg0KPiA+ID4gb2Zm
c2V0IHRvIGFuIGV4aXN0aW5nIHBvaW50ZXIuICBFdmVuIGlmIHlvdSdyZSBzdGlsbCBpbiByZWdp
c3RlcnMsDQo+ID4gPiB0aGUNCj4gPiA+IG9mZnNldCBub3cgaGFzIHRvIGJlIGNvbXB1dGVkIGFu
ZCBzdG9yZWQgYW5kIHRoZSBjb21waWxlciBsb3Nlcw0KPiA+ID4gdHJhY2sNCj4gPiA+IG9mIHRo
ZSByZWxhdGlvbi4NCj4gPiA+DQo+ID4gPiBUaGUgYm90dG9tIGxpbmUgaXMgdGhhdCBhZGRpbmcg
YW4gZXh0cmEgYXJndW1lbnQgZm9yIGEgdmFsdWUgd2hpY2gNCj4gPiA+IGNhbg0KPiA+ID4gYmUg
b2Zmc2V0IGNvbXB1dGVkIGlzIHJhcmVseSBhIHdpbi4NCj4gPg0KPiA+IEphbWVzLA0KPiA+IFdo
ZW4gSSBkaWQgdGhpcywgSSB3YXMgbW9zdGx5IGNvbmNlcm5lZCBhYm91dCB0aGUgY29zdCBvZg0K
PiA+IHJlZXN0YWJsaXNoaW5nIHN0YXRlIHRoYXQgd2FzDQo+ID4gYWxyZWFkeSBrbm93bi4gU28s
IGV2ZW4gd2l0aCB0aGUgZnVuY3Rpb24gYmVpbmcgaW4tbGluZWQsIEkgZmVsdCB0aGUNCj4gPiBj
b3N0IG9mIHJlZXN0YWJsaXNoaW5nDQo+ID4gc3RhdGUgdGhhdCB3YXMgYWxyZWFkeSBrbm93biBp
cyB1bm5lY2Vzc2FyeS4gSW4gdGhpcyBwYXJ0aWN1bGFyIGNhc2UsDQo+ID4gSSBkaWQgbm90IGNo
YW5nZSB0aGUNCj4gPiBudW1iZXIgb2YgYXJndW1lbnRzIHRoYXQgd2VyZSBiZWluZyBwYXNzZWQ7
IEkganVzdCBjaGFuZ2VkIHRoZSB0eXBlDQo+ID4gb2Ygb25lIG9mIHRoZW0gLQ0KPiA+IGluc3Rl
YWQgb2YgcGFzc2luZyBzdHJ1Y3QgaHZfZGV2aWNlICosIEkgYW0gbm93IHBhc3Npbmcgc3RydWN0
DQo+ID4gc3RvcnZzY19kZXZpY2UgKi4gSW4gdGhlDQo+ID4gY3VycmVudCBjb2RlLCB3ZSBhcmUg
dXNpbmcgc3RydWN0IGh2X2RldmljZSAqIHRvIGVzdGFibGlzaCBhIHBvaW50ZXINCj4gPiB0byBz
dHJ1Y3Qgc3RvcnZzY19kZXZpY2UgKg0KPiA+IHZpYSB0aGUgZnVuY3Rpb24gZ2V0X2luX3N0b3Jf
ZGV2aWNlKCkuIFRoaXMgcGF0dGVybiBjdXJyZW50bHkgZXhpc3RzDQo+ID4gaW4gdGhlIGNhbGwg
Y2hhaW4gZnJvbSB0aGUNCj4gPiBpbnRlcnJ1cHQgaGFuZGxlciAtIHN0b3J2c2Nfb25fY2hhbm5l
bF9jYWxsYmFjaygpLg0KPiA+DQo+ID4gV2hpbGUgdGhlIGNvbXBpbGVyIGlzIHNtYXJ0IGVub3Vn
aCB0byBpbmxpbmUgYm90aA0KPiA+IGdldF9pbl9zdG9yX2RldmljZSgpIGFzIHdlbGwgYXMgbWFu
eSBvZiB0aGUgc3RhdGljDQo+ID4gZnVuY3Rpb25zIGluIHRoZSBjYWxsIGNoYWluIGZyb20gc3Rv
cnZzY19vbl9jaGFubmVsX2NhbGxiYWNrKCksDQo+ID4gbG9va2luZyBhdCB0aGUgYXNzZW1ibGVk
IGNvZGUsDQo+ID4gdGhlIGNvbXBpbGVyIGlzIHJlcGVhdGVkbHkgaW5saW5pbmcgdGhlIGNhbGwg
dG8gZ2V0X2luX3N0b3JfZGV2aWNlKCkNCj4gPiBhbmQgdGhpcyBjbGVhcmx5IGlzIGxlc3MgdGhh
biBvcHRpbWFsLg0KPiANCj4gT0ssIHNvIHRoZSByZWFzb24gZm9yIHRoZSByZWNvbXB1dGF0aW9u
IGlzIHRoZSBkZXN0cnVjdGlvbiBjb25kaXRpb24NCj4gY2hlY2sgd2hpY2ggaXMgZXZhbHVhdGVk
IGV2ZXJ5IHRpbWUgeW91IGNhbGwgaXQ/ICBQZXJoYXBzIHdoYXQgeW91DQo+IHNpbXBseSB3YW50
IGlzIGFuIF9fZ2V0X2luX3N0b3JfZGV2aWNlKCkgdGhhdCBkb2VzIHRoZSBvZmZzZXQNCj4gbWF0
aGVtYXRpY3Mgd2l0aG91dCB0aGUgZGVzdHJ1Y3Rpb24gY2hlY2suICBJdCdzIGRvaW5nIGV4YWN0
bHkgd2hhdA0KPiBwYXNzaW5nIHRoZSBhZGRpdGlvbmFsIHBhcmFtZXRlciBkb2VzOiB0aGUgY2Fs
bGluZyBmdW5jdGlvbiBpcyB0YWtpbmcNCj4gb24gdGhlIGJ1cmRlbiBvZiB2ZXJpZnlpbmcgdGhl
eSd2ZSBnb3QgYSBkZXZpY2Ugd2hpY2ggaXMgc3RpbGwgdmFsaWQuDQo+IA0KPiBJJ20gbm90IG1h
a2luZyB0aGlzIGEgaGFyZCByZXF1aXJlbWVudCBmb3IgcmV2aWV3aW5nIHRoZSBjb2RlOiB5b3Ug
aGF2ZQ0KPiBhcmd1bWVudHMgdG8gc3BhcmUgaW4gdGhlIGZ1bmN0aW9ucywgc28gSSBkb24ndCB0
aGluayBpdCBtYXR0ZXJzIHdoaWNoDQo+IHdheSB0aGlzIGlzIGRvbmUuDQoNCkFncmVlZC4NCg0K
PiAgSSBkbywgaG93ZXZlciwgdGhpbmsgaXQgbWFrZXMgY29uc3VtZXJzIG9mIHRoZSBzdG9yDQo+
IGRldmljZSB0aGluayBhYm91dCB3aHkgdGhleSdyZSB1c2luZyBpdCBhbmQgd2hldGhlciB0aGV5
IGFjdHVhbGx5IG5lZWQNCj4gdGhlIGRlc3RydWN0IGNoZWNrLg0KDQpUaGVyZSBpcyBoaWdoZXIg
bGV2ZWwgc2VyaWFsaXphdGlvbiB0aGF0IG1ha2VzIHRoZSBkZXN0cnVjdCBjaGVjayB1bm5lY2Vz
c2FyeQ0Kb25jZSB3ZSBnZXQgcGFzdCB0aGUgY2hlY2sgaW4gdGhlIGZpcnN0IGZ1bmN0aW9uIGlu
IHRoZSBpbnRlcnJ1cHQgaGFuZGxlciBmb3INCnRoaXMgZHJpdmVyIC0gIHN0b3J2c2Nfb25fY2hh
bm5lbF9jYWxsYmFjaygpLiANCkluIHRoZSBhYnNlbmNlIG9mIHRoaXMsIHRoZSBkZXN0cnVjdCBj
aGVjayBpcyBtZWFuaW5nbGVzcyBzaW5jZSB0aGUgc3RhdGUgY2FuIA0KY2hhbmdlIHNvb24gYWZ0
ZXIgaXQgaGFzIGJlZW4gY2hlY2tlZC4gU28sIGlmIGl0IGlzIG9rIHdpdGggeW91LCBJIHdpbGwg
YWRkIGFkZGl0aW9uYWwNCmNvbW1lbnQgdG8gdGhlIGNvbW1pdCBsb2cgYW5kIHJlc3VibWl0IHRo
ZSBwYXRjaC4NCg0KUmVnYXJkcywNCg0KSy4gWSAgDQoNCg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index d6ca4f2..b68aebe 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -945,19 +945,16 @@  static void storvsc_handle_error(struct vmscsi_request *vm_srb,
 }
 
 
-static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+				       struct storvsc_device *stor_dev)
 {
 	struct scsi_cmnd *scmnd = cmd_request->cmd;
-	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
 	struct scsi_sense_hdr sense_hdr;
 	struct vmscsi_request *vm_srb;
 	struct Scsi_Host *host;
-	struct storvsc_device *stor_dev;
-	struct hv_device *dev = host_dev->dev;
 	u32 payload_sz = cmd_request->payload_sz;
 	void *payload = cmd_request->payload;
 
-	stor_dev = get_in_stor_device(dev);
 	host = stor_dev->host;
 
 	vm_srb = &cmd_request->vstor_packet.vm_srb;
@@ -987,14 +984,13 @@  static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
 		kfree(payload);
 }
 
-static void storvsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct storvsc_device *stor_device,
 				  struct vstor_packet *vstor_packet,
 				  struct storvsc_cmd_request *request)
 {
-	struct storvsc_device *stor_device;
 	struct vstor_packet *stor_pkt;
+	struct hv_device *device = stor_device->device;
 
-	stor_device = hv_get_drvdata(device);
 	stor_pkt = &request->vstor_packet;
 
 	/*
@@ -1049,7 +1045,7 @@  static void storvsc_on_io_completion(struct hv_device *device,
 	stor_pkt->vm_srb.data_transfer_length =
 	vstor_packet->vm_srb.data_transfer_length;
 
-	storvsc_command_completion(request);
+	storvsc_command_completion(request, stor_device);
 
 	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
 		stor_device->drain_notify)
@@ -1058,21 +1054,19 @@  static void storvsc_on_io_completion(struct hv_device *device,
 
 }
 
-static void storvsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct storvsc_device *stor_device,
 			     struct vstor_packet *vstor_packet,
 			     struct storvsc_cmd_request *request)
 {
 	struct storvsc_scan_work *work;
-	struct storvsc_device *stor_device;
 
 	switch (vstor_packet->operation) {
 	case VSTOR_OPERATION_COMPLETE_IO:
-		storvsc_on_io_completion(device, vstor_packet, request);
+		storvsc_on_io_completion(stor_device, vstor_packet, request);
 		break;
 
 	case VSTOR_OPERATION_REMOVE_DEVICE:
 	case VSTOR_OPERATION_ENUMERATE_BUS:
-		stor_device = get_in_stor_device(device);
 		work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
 		if (!work)
 			return;
@@ -1083,7 +1077,6 @@  static void storvsc_on_receive(struct hv_device *device,
 		break;
 
 	case VSTOR_OPERATION_FCHBA_DATA:
-		stor_device = get_in_stor_device(device);
 		cache_wwn(stor_device, vstor_packet);
 #ifdef CONFIG_SCSI_FC_ATTRS
 		fc_host_node_name(stor_device->host) = stor_device->node_name;
@@ -1133,7 +1126,7 @@  static void storvsc_on_channel_callback(void *context)
 					vmscsi_size_delta));
 				complete(&request->wait_event);
 			} else {
-				storvsc_on_receive(device,
+				storvsc_on_receive(stor_device,
 						(struct vstor_packet *)packet,
 						request);
 			}