diff mbox

[v2,02/16] scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly

Message ID b92d12e4f78c4998bc8ad000359c127e673379f3.1476276823.git.jthumshirn@suse.de (mailing list archive)
State Not Applicable
Headers show

Commit Message

Johannes Thumshirn Oct. 12, 2016, 1:06 p.m. UTC
Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
helper variables bsg_request and bsg_reply. This will be helpfull  when
transitioning to bsg-lib.

Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
---
 drivers/s390/scsi/zfcp_fc.c      |   9 +-
 drivers/scsi/bfa/bfad_bsg.c      |  40 +++---
 drivers/scsi/ibmvscsi/ibmvfc.c   |  22 ++--
 drivers/scsi/libfc/fc_lport.c    |  23 ++--
 drivers/scsi/lpfc/lpfc_bsg.c     | 194 +++++++++++++++++-----------
 drivers/scsi/qla2xxx/qla_bsg.c   | 264 ++++++++++++++++++++++-----------------
 drivers/scsi/qla2xxx/qla_iocb.c  |   5 +-
 drivers/scsi/qla2xxx/qla_isr.c   |  46 ++++---
 drivers/scsi/qla2xxx/qla_mr.c    |  10 +-
 drivers/scsi/scsi_transport_fc.c |  37 +++---
 10 files changed, 387 insertions(+), 263 deletions(-)

Comments

Hannes Reinecke Oct. 13, 2016, 11:25 a.m. UTC | #1
On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> helper variables bsg_request and bsg_reply. This will be helpfull  when
> transitioning to bsg-lib.
> 
> Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
> ---
>  drivers/s390/scsi/zfcp_fc.c      |   9 +-
>  drivers/scsi/bfa/bfad_bsg.c      |  40 +++---
>  drivers/scsi/ibmvscsi/ibmvfc.c   |  22 ++--
>  drivers/scsi/libfc/fc_lport.c    |  23 ++--
>  drivers/scsi/lpfc/lpfc_bsg.c     | 194 +++++++++++++++++-----------
>  drivers/scsi/qla2xxx/qla_bsg.c   | 264 ++++++++++++++++++++++-----------------
>  drivers/scsi/qla2xxx/qla_iocb.c  |   5 +-
>  drivers/scsi/qla2xxx/qla_isr.c   |  46 ++++---
>  drivers/scsi/qla2xxx/qla_mr.c    |  10 +-
>  drivers/scsi/scsi_transport_fc.c |  37 +++---
>  10 files changed, 387 insertions(+), 263 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
Steffen Maier Oct. 13, 2016, 3:15 p.m. UTC | #2
I'm puzzled.

$ git bisect start fc_bsg master
Bisecting: 8 revisions left to test after this (roughly 3 steps)
[005d51510eee6102636d5dbb06310531c5d46151] scsi: fc: implement kref 
backed reference counting
$ git bisect bad
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[bef6da201de1bb81bb4d9511f9a155862efc251f] scsi: Unify interfaces of 
fc_bsg_jobdone and bsg_job_done
$ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[3087864ce3d7282f59021245d8a5f83ef1caef18] scsi: don't use 
fc_bsg_job::request and fc_bsg_job::reply directly
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[81aea44720d22d2e0c4a2613ae8b1c256ef6b0cb] scsi: Get rid of struct 
fc_bsg_buffer
> $ git bisect good
> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
> Author: Johannes Thumshirn <jthumshirn@suse.de>
> Date:   Wed Oct 12 15:06:28 2016 +0200
>
>     scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>
>     Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
>     helper variables bsg_request and bsg_reply. This will be helpfull  when
>     transitioning to bsg-lib.
>
>     Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
>
> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2 0d9fe225615679550be91fbd9f84c09ab1e280fc M	drivers

 From there (on the reverse bisect path) I get the following Oops,
except for the full patch set having another stack trace as in my 
previous mail (dying in zfcp code).

> [   46.942452] Oops: 0004 ilc:2 [#1] [   46.942460] PREEMPT  SMP [   46.942465]
> [   46.942470] Modules linked in: nf_log_ipv6 xt_pkttype nf_log_ipv4 nf_log_common xt_LOG xt_limit ip6t_REJECT nf_reject_ipv6 xt_tcpudp nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw ipt_REJECT nf_reject_ipv4 iptable_raw xt_CT iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables qeth_l2 ghash_s390 prng ecb aes_s390 des_s390 des_generic sha512_s390 sha256_s390 sha1_s390 sha_common dm_mod qeth ccwgroup zfcp qdio autofs4
> [   46.942547] CPU: 1 PID: 1714 Comm: zfcp_ping Not tainted 4.8.0fcbsg+ #9
> [   46.942550] Hardware name: IBM              2964 N96              702              (z/VM)
> [   46.942556] task: 000000005c988008 task.stack: 000000005d2ec000
> [   46.942560] Krnl PSW : 0704e00180000000 00000000007c91ec[   46.942574]  (fc_bsg_request_handler+0x404/0x4b0)
> [   46.942579]
> [   46.942583]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:000:
> [   46.942598]  RI:0 EA:3
> [   46.942601]
> [   46.942601] Krnl GPRS: 0000000000000000 00000000ffffffcb 0000000000000000 0000000080000001
> [   46.942603]            00000000007c8fe8 0000000064398c68 0000000069f967e8 000000006a3d8008
> [   46.942605]            000000006a5e02c8 00000000698b5490 0000000000000000 0000000000000000
> [   46.942607]            000000006a9ef5f8 0000000000a36840 00000000007c8fe8 000000005d2efa00
> [   46.942619] Krnl Code: 00000000007c91de: e55dc08c0003        clfhsi  140(%r12),3[   46.942622]
> [   46.942622]            00000000007c91e4: a7240004            brc     2,7c91ec
>                          #00000000007c91e8: a7f40001           brc     15,7c91ea[   46.942629]
> [   46.942629]           >00000000007c91ec: 5010b000            st      %r1,0(%r11)
>                           00000000007c91f0: e54cb0040000       mvhi    4(%r11),0[   46.942635]
> [   46.942635]            00000000007c91f6: e54cc08c0004        mvhi    140(%r12),4
>                           00000000007c91fc: b904002c           lgr     %r2,%r12[   46.942643]
> [   46.942643]            00000000007c9200: c0e5ffffe2c0        brasl   %r14,7c5780
> [   46.942646]
> [   46.942647] Call Trace:
> [   46.942650] ([<00000000007c8fe8>] fc_bsg_request_handler+0x200/0x4b0)
> [   46.942656] ([<00000000006b8e0a>] __blk_run_queue+0x52/0x68)
> [   46.942661] ([<00000000006c549a>] blk_execute_rq_nowait+0xf2/0x110)
> [   46.942664] ([<00000000006c557a>] blk_execute_rq+0xa2/0x110)
> [   46.942668] ([<00000000006de0ee>] bsg_ioctl+0x1f6/0x268)
> [   46.942675] ([<000000000036ca20>] do_vfs_ioctl+0x680/0x6d8)
> [   46.942677] ([<000000000036caf4>] SyS_ioctl+0x7c/0xb0)
> [   46.942685] ([<00000000009a541e>] system_call+0xd6/0x270)
> [   46.942687] INFO: lockdep is turned off.
> [   46.942688] Last Breaking-Event-Address:
> [   46.942692]  [<00000000007c91e4>] fc_bsg_request_handler+0x3fc/0x4b0
> [   46.942696]  [   46.942698] Kernel panic - not syncing: Fatal exception: panic_on_oops



On 10/12/2016 03:06 PM, Johannes Thumshirn wrote:
> Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> helper variables bsg_request and bsg_reply. This will be helpfull  when
> transitioning to bsg-lib.
>
> Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
> ---
>  drivers/s390/scsi/zfcp_fc.c      |   9 +-
>  drivers/scsi/bfa/bfad_bsg.c      |  40 +++---
>  drivers/scsi/ibmvscsi/ibmvfc.c   |  22 ++--
>  drivers/scsi/libfc/fc_lport.c    |  23 ++--
>  drivers/scsi/lpfc/lpfc_bsg.c     | 194 +++++++++++++++++-----------
>  drivers/scsi/qla2xxx/qla_bsg.c   | 264 ++++++++++++++++++++++-----------------
>  drivers/scsi/qla2xxx/qla_iocb.c  |   5 +-
>  drivers/scsi/qla2xxx/qla_isr.c   |  46 ++++---
>  drivers/scsi/qla2xxx/qla_mr.c    |  10 +-
>  drivers/scsi/scsi_transport_fc.c |  37 +++---
>  10 files changed, 387 insertions(+), 263 deletions(-)


> diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
> index 8ff2067..eafc7555 100644
> --- a/drivers/scsi/scsi_transport_fc.c
> +++ b/drivers/scsi/scsi_transport_fc.c
> @@ -3588,9 +3588,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
>  {
>  	struct request *req = job->req;
>  	struct request *rsp = req->next_rq;
> +	struct fc_bsg_reply *bsg_reply = job->reply;
>  	int err;
>
> -	err = job->req->errors = job->reply->result;
> +	err = job->req->errors = bsg_reply->result;
>
>  	if (err < 0)
>  		/* we're only returning the result field in the reply */
> @@ -3602,10 +3603,10 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
>  	req->resid_len = 0;
>
>  	if (rsp) {
> -		WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
> +		WARN_ON(bsg_reply->reply_payload_rcv_len > rsp->resid_len);
>
>  		/* set reply (bidi) residual */
> -		rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
> +		rsp->resid_len -= min(bsg_reply->reply_payload_rcv_len,
>  				      rsp->resid_len);
>  	}
>  	blk_complete_request(req);
> @@ -3701,6 +3702,8 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
>  	struct fc_internal *i = to_fc_internal(shost->transportt);
>  	struct request *rsp = req->next_rq;
>  	struct fc_bsg_job *job;
> +	struct fc_bsg_request *bsg_request;
> +	struct fc_bsg_reply *bsg_reply;
>  	int ret;
>
>  	BUG_ON(req->special);
> @@ -3726,9 +3729,9 @@ fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
>  	if (i->f->dd_bsg_size)
>  		job->dd_data = (void *)&job[1];
>  	spin_lock_init(&job->job_lock);
> -	job->request = (struct fc_bsg_request *)req->cmd;
> +	bsg_request = (struct fc_bsg_request *)req->cmd;
>  	job->request_len = req->cmd_len;
> -	job->reply = req->sense;
> +	bsg_reply = req->sense;
>  	job->reply_len = SCSI_SENSE_BUFFERSIZE;	/* Size of sense buffer
>  						 * allocated */
>  	if (req->bio) {
> @@ -3779,11 +3782,13 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
>  			 struct fc_bsg_job *job)
>  {
>  	struct fc_internal *i = to_fc_internal(shost->transportt);
> +	struct fc_bsg_request *bsg_request = job->request;
> +	struct fc_bsg_reply *bsg_reply = job->reply;
>  	int cmdlen = sizeof(uint32_t);	/* start with length of msgcode */
>  	int ret;
>
>  	/* Validate the host command */
> -	switch (job->request->msgcode) {
> +	switch (bsg_request->msgcode) {
>  	case FC_BSG_HST_ADD_RPORT:
>  		cmdlen += sizeof(struct fc_bsg_host_add_rport);
>  		break;
> @@ -3815,7 +3820,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
>  	case FC_BSG_HST_VENDOR:
>  		cmdlen += sizeof(struct fc_bsg_host_vendor);
>  		if ((shost->hostt->vendor_id == 0L) ||
> -		    (job->request->rqst_data.h_vendor.vendor_id !=
> +		    (bsg_request->rqst_data.h_vendor.vendor_id !=
>  			shost->hostt->vendor_id)) {
>  			ret = -ESRCH;
>  			goto fail_host_msg;
> @@ -3840,8 +3845,8 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
>  fail_host_msg:
>  	/* return the errno failure code as the only status */
>  	BUG_ON(job->reply_len < sizeof(uint32_t));
> -	job->reply->reply_payload_rcv_len = 0;
> -	job->reply->result = ret;
> +	bsg_reply->reply_payload_rcv_len = 0;
> +	bsg_reply->result = ret;
>  	job->reply_len = sizeof(uint32_t);
>  	fc_bsg_jobdone(job);
>  	return FC_DISPATCH_UNLOCKED;
> @@ -3878,11 +3883,13 @@ fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
>  			 struct fc_rport *rport, struct fc_bsg_job *job)
>  {
>  	struct fc_internal *i = to_fc_internal(shost->transportt);
> +	struct fc_bsg_request *bsg_request = job->request;
> +	struct fc_bsg_reply *bsg_reply = job->reply;
>  	int cmdlen = sizeof(uint32_t);	/* start with length of msgcode */
>  	int ret;
>
>  	/* Validate the rport command */
> -	switch (job->request->msgcode) {
> +	switch (bsg_request->msgcode) {
>  	case FC_BSG_RPT_ELS:
>  		cmdlen += sizeof(struct fc_bsg_rport_els);
>  		goto check_bidi;
> @@ -3915,8 +3922,8 @@ check_bidi:
>  fail_rport_msg:
>  	/* return the errno failure code as the only status */
>  	BUG_ON(job->reply_len < sizeof(uint32_t));
> -	job->reply->reply_payload_rcv_len = 0;
> -	job->reply->result = ret;
> +	bsg_reply->reply_payload_rcv_len = 0;
> +	bsg_reply->result = ret;
>  	job->reply_len = sizeof(uint32_t);
>  	fc_bsg_jobdone(job);
>  	return FC_DISPATCH_UNLOCKED;


> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
>  	struct request *req;
>  	struct fc_bsg_job *job;
>  	enum fc_dispatch_result ret;
> +	struct fc_bsg_reply *bsg_reply;
>
>  	if (!get_device(dev))
>  		return;
> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
>  		/* check if we have the msgcode value at least */
>  		if (job->request_len < sizeof(uint32_t)) {
>  			BUG_ON(job->reply_len < sizeof(uint32_t));
> -			job->reply->reply_payload_rcv_len = 0;
> -			job->reply->result = -ENOMSG;
> +			bsg_reply = job->reply;
> +			bsg_reply->reply_payload_rcv_len = 0;
> +			bsg_reply->result = -ENOMSG;
>  			job->reply_len = sizeof(uint32_t);
>  			fc_bsg_jobdone(job);
>  			spin_lock_irq(q->queue_lock);
>
Johannes Thumshirn Oct. 13, 2016, 4:24 p.m. UTC | #3
On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
> I'm puzzled.
> 
> $ git bisect start fc_bsg master
> Bisecting: 8 revisions left to test after this (roughly 3 steps)
> [005d51510eee6102636d5dbb06310531c5d46151] scsi: fc: implement kref backed
> reference counting
> $ git bisect bad
> Bisecting: 3 revisions left to test after this (roughly 2 steps)
> [bef6da201de1bb81bb4d9511f9a155862efc251f] scsi: Unify interfaces of
> fc_bsg_jobdone and bsg_job_done
> $ git bisect bad
> Bisecting: 1 revision left to test after this (roughly 1 step)
> [3087864ce3d7282f59021245d8a5f83ef1caef18] scsi: don't use
> fc_bsg_job::request and fc_bsg_job::reply directly
> $ git bisect bad
> Bisecting: 0 revisions left to test after this (roughly 0 steps)
> [81aea44720d22d2e0c4a2613ae8b1c256ef6b0cb] scsi: Get rid of struct
> fc_bsg_buffer
> > $ git bisect good
> > 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
> > commit 3087864ce3d7282f59021245d8a5f83ef1caef18
> > Author: Johannes Thumshirn <jthumshirn@suse.de>
> > Date:   Wed Oct 12 15:06:28 2016 +0200
> > 
> >     scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
> > 
> >     Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
> >     helper variables bsg_request and bsg_reply. This will be helpfull  when
> >     transitioning to bsg-lib.
> > 
> >     Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
> > 
> > :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2 0d9fe225615679550be91fbd9f84c09ab1e280fc M	drivers
> 
> From there (on the reverse bisect path) I get the following Oops,
> except for the full patch set having another stack trace as in my previous
> mail (dying in zfcp code).
> 

[...]

> 
> > @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> >  	struct request *req;
> >  	struct fc_bsg_job *job;
> >  	enum fc_dispatch_result ret;
> > +	struct fc_bsg_reply *bsg_reply;
> > 
> >  	if (!get_device(dev))
> >  		return;
> > @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> >  		/* check if we have the msgcode value at least */
> >  		if (job->request_len < sizeof(uint32_t)) {
> >  			BUG_ON(job->reply_len < sizeof(uint32_t));
> > -			job->reply->reply_payload_rcv_len = 0;
> > -			job->reply->result = -ENOMSG;
> > +			bsg_reply = job->reply;
> > +			bsg_reply->reply_payload_rcv_len = 0;
> > +			bsg_reply->result = -ENOMSG;
> >  			job->reply_len = sizeof(uint32_t);
> >  			fc_bsg_jobdone(job);
> >  			spin_lock_irq(q->queue_lock);
> > 

Ahm and what exactly can break here? It's just assigning variables. Now
I'm puzzled too.

I'll have to look into it tomorrow.

Byte,
        Johannes
Steffen Maier Oct. 28, 2016, 9:53 a.m. UTC | #4
On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
>> I'm puzzled.
>>
>> $ git bisect start fc_bsg master

>>> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
>>> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
>>> Author: Johannes Thumshirn <jthumshirn@suse.de>
>>> Date:   Wed Oct 12 15:06:28 2016 +0200
>>>
>>>     scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>>>
>>>     Don't use fc_bsg_job::request and fc_bsg_job::reply directly, but use
>>>     helper variables bsg_request and bsg_reply. This will be helpfull  when
>>>     transitioning to bsg-lib.
>>>
>>>     Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
>>>
>>> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2 0d9fe225615679550be91fbd9f84c09ab1e280fc M	drivers
>>
>> From there (on the reverse bisect path) I get the following Oops,
>> except for the full patch set having another stack trace as in my previous
>> mail (dying in zfcp code).
>>
>
> [...]
>
>>
>>> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
>>>  	struct request *req;
>>>  	struct fc_bsg_job *job;
>>>  	enum fc_dispatch_result ret;
>>> +	struct fc_bsg_reply *bsg_reply;
>>>
>>>  	if (!get_device(dev))
>>>  		return;
>>> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
>>>  		/* check if we have the msgcode value at least */
>>>  		if (job->request_len < sizeof(uint32_t)) {
>>>  			BUG_ON(job->reply_len < sizeof(uint32_t));
>>> -			job->reply->reply_payload_rcv_len = 0;
>>> -			job->reply->result = -ENOMSG;
>>> +			bsg_reply = job->reply;
>>> +			bsg_reply->reply_payload_rcv_len = 0;
>>> +			bsg_reply->result = -ENOMSG;

Compiler optimization re-ordered above two lines and the first pointer 
derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
The assignment tries to write to memory at address NULL causing the 
kernel page fault.

Does your suggested change for [PATCH v3 02/16], shuffling the 
job->request_len checks, address above kernel page fault?

>>>  			job->reply_len = sizeof(uint32_t);
>>>  			fc_bsg_jobdone(job);
>>>  			spin_lock_irq(q->queue_lock);
>>>
>
> Ahm and what exactly can break here? It's just assigning variables. Now
> I'm puzzled too.
Hannes Reinecke Oct. 28, 2016, 11:31 a.m. UTC | #5
On 10/28/2016 11:53 AM, Steffen Maier wrote:
> 
> 
> On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
>> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
>>> I'm puzzled.
>>>
>>> $ git bisect start fc_bsg master
> 
>>>> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
>>>> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
>>>> Author: Johannes Thumshirn <jthumshirn@suse.de>
>>>> Date:   Wed Oct 12 15:06:28 2016 +0200
>>>>
>>>>     scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>>>>
>>>>     Don't use fc_bsg_job::request and fc_bsg_job::reply directly,
>>>> but use
>>>>     helper variables bsg_request and bsg_reply. This will be
>>>> helpfull  when
>>>>     transitioning to bsg-lib.
>>>>
>>>>     Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
>>>>
>>>> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2
>>>> 0d9fe225615679550be91fbd9f84c09ab1e280fc M    drivers
>>>
>>> From there (on the reverse bisect path) I get the following Oops,
>>> except for the full patch set having another stack trace as in my
>>> previous
>>> mail (dying in zfcp code).
>>>
>>
>> [...]
>>
>>>
>>>> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue
>>>> *q, struct Scsi_Host *shost,
>>>>      struct request *req;
>>>>      struct fc_bsg_job *job;
>>>>      enum fc_dispatch_result ret;
>>>> +    struct fc_bsg_reply *bsg_reply;
>>>>
>>>>      if (!get_device(dev))
>>>>          return;
>>>> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue
>>>> *q, struct Scsi_Host *shost,
>>>>          /* check if we have the msgcode value at least */
>>>>          if (job->request_len < sizeof(uint32_t)) {
>>>>              BUG_ON(job->reply_len < sizeof(uint32_t));
>>>> -            job->reply->reply_payload_rcv_len = 0;
>>>> -            job->reply->result = -ENOMSG;
>>>> +            bsg_reply = job->reply;
>>>> +            bsg_reply->reply_payload_rcv_len = 0;
>>>> +            bsg_reply->result = -ENOMSG;
> 
> Compiler optimization re-ordered above two lines and the first pointer
> derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
> The assignment tries to write to memory at address NULL causing the
> kernel page fault.
> 
I spoke to our compiler people, and they strongly believed this not to
be the case. Or, put it the other way round, if such a thing would
happen it would be a compiler issue.

Have you checked the compiler output?

Cheers,

Hannes
Steffen Maier Oct. 28, 2016, 1:53 p.m. UTC | #6
On 10/28/2016 01:31 PM, Hannes Reinecke wrote:
> On 10/28/2016 11:53 AM, Steffen Maier wrote:
>> On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
>>> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
>>>> I'm puzzled.
>>>>
>>>> $ git bisect start fc_bsg master
>>
>>>>> 3087864ce3d7282f59021245d8a5f83ef1caef18 is the first bad commit
>>>>> commit 3087864ce3d7282f59021245d8a5f83ef1caef18
>>>>> Author: Johannes Thumshirn <jthumshirn@suse.de>
>>>>> Date:   Wed Oct 12 15:06:28 2016 +0200
>>>>>
>>>>>     scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
>>>>>
>>>>>     Don't use fc_bsg_job::request and fc_bsg_job::reply directly,
>>>>> but use
>>>>>     helper variables bsg_request and bsg_reply. This will be
>>>>> helpfull  when
>>>>>     transitioning to bsg-lib.
>>>>>
>>>>>     Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
>>>>>
>>>>> :040000 040000 140c4b6829d5cfaec4079716e0795f63f8bc3bd2
>>>>> 0d9fe225615679550be91fbd9f84c09ab1e280fc M    drivers
>>>>
>>>> From there (on the reverse bisect path) I get the following Oops,
>>>> except for the full patch set having another stack trace as in my
>>>> previous
>>>> mail (dying in zfcp code).
>>>
>>> [...]
>>>
>>>>> @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue
>>>>> *q, struct Scsi_Host *shost,
>>>>>      struct request *req;
>>>>>      struct fc_bsg_job *job;
>>>>>      enum fc_dispatch_result ret;
>>>>> +    struct fc_bsg_reply *bsg_reply;
>>>>>
>>>>>      if (!get_device(dev))
>>>>>          return;
>>>>> @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue
>>>>> *q, struct Scsi_Host *shost,
>>>>>          /* check if we have the msgcode value at least */
>>>>>          if (job->request_len < sizeof(uint32_t)) {
>>>>>              BUG_ON(job->reply_len < sizeof(uint32_t));
>>>>> -            job->reply->reply_payload_rcv_len = 0;
>>>>> -            job->reply->result = -ENOMSG;
>>>>> +            bsg_reply = job->reply;
>>>>> +            bsg_reply->reply_payload_rcv_len = 0;
>>>>> +            bsg_reply->result = -ENOMSG;
>>
>> Compiler optimization re-ordered above two lines and the first pointer
>> derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
>> The assignment tries to write to memory at address NULL causing the
>> kernel page fault.
>>
> I spoke to our compiler people, and they strongly believed this not to
> be the case. Or, put it the other way round, if such a thing would
> happen it would be a compiler issue.
>
> Have you checked the compiler output?

I just mentioned the compiler optimization to explain why the assembler 
code visible in the panic dies at bsg_reply->result = -ENOMSG and not at 
bsg_reply->reply_payload_rcv_len = 0. I don't think it makes a 
difference regarding the issue, which remains a NULL pointer dereference 
with bsg_reply either way, which I doubt is caused by compiler output. 
But then again, see further down below.

> [   46.942560] Krnl PSW : 0704e00180000000 00000000007c91ec[   46.942574]  (fc_bsg_request_handler+0x404/0x4b0)
> [   46.942579]
> [   46.942583]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:000:
> [   46.942598]  RI:0 EA:3
> [   46.942601]
> [   46.942601] Krnl GPRS: 0000000000000000 00000000ffffffcb 0000000000000000 0000000080000001
> [   46.942603]            00000000007c8fe8 0000000064398c68 0000000069f967e8 000000006a3d8008
> [   46.942605]            000000006a5e02c8 00000000698b5490 0000000000000000 0000000000000000

 
        %r11 is NULL

> [   46.942607]            000000006a9ef5f8 0000000000a36840 00000000007c8fe8 000000005d2efa00
> [   46.942619] Krnl Code: 00000000007c91de: e55dc08c0003        clfhsi  140(%r12),3[   46.942622]
> [   46.942622]            00000000007c91e4: a7240004            brc     2,7c91ec
>                          #00000000007c91e8: a7f40001           brc     15,7c91ea[   46.942629]
> [   46.942629]           >00000000007c91ec: 5010b000            st      %r1,0(%r11)
>                           00000000007c91f0: e54cb0040000       mvhi    4(%r11),0[   46.942635]
> [   46.942635]            00000000007c91f6: e54cc08c0004        mvhi    140(%r12),4
>                           00000000007c91fc: b904002c           lgr     %r2,%r12[   46.942643]
> [   46.942643]            00000000007c9200: c0e5ffffe2c0        brasl   %r14,7c5780
> [   46.942646]
> [   46.942647] Call Trace:
> [   46.942650] ([<00000000007c8fe8>] fc_bsg_request_handler+0x200/0x4b0)
> [   46.942656] ([<00000000006b8e0a>] __blk_run_queue+0x52/0x68)
> [   46.942661] ([<00000000006c549a>] blk_execute_rq_nowait+0xf2/0x110)
> [   46.942664] ([<00000000006c557a>] blk_execute_rq+0xa2/0x110)
> [   46.942668] ([<00000000006de0ee>] bsg_ioctl+0x1f6/0x268)
> [   46.942675] ([<000000000036ca20>] do_vfs_ioctl+0x680/0x6d8)
> [   46.942677] ([<000000000036caf4>] SyS_ioctl+0x7c/0xb0)
> [   46.942685] ([<00000000009a541e>] system_call+0xd6/0x270)
> [   46.942687] INFO: lockdep is turned off.
> [   46.942688] Last Breaking-Event-Address:
> [   46.942692]  [<00000000007c91e4>] fc_bsg_request_handler+0x3fc/0x4b0
> [   46.942696]  [   46.942698] Kernel panic - not syncing: Fatal exception: panic_on_oops

all the following was written from bottom to top:

> crash> dis -l fc_bsg_request_handler
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3943

static void
fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
		       struct fc_rport *rport, struct device *dev)
{

> 0x7c8de8 <fc_bsg_request_handler>:      brcl    0,0x7c8de8 <fc_bsg_request_handler>
> 0x7c8dee <fc_bsg_request_handler+0x6>:  stmg    %r6,%r15,72(%r15)
> 0x7c8df4 <fc_bsg_request_handler+0xc>:  larl    %r13,0xa36840
> 0x7c8dfa <fc_bsg_request_handler+0x12>: tmll    %r15,16256
> 0x7c8dfe <fc_bsg_request_handler+0x16>: lgr     %r14,%r15
> 0x7c8e02 <fc_bsg_request_handler+0x1a>: je      0x7c8e04 <fc_bsg_request_handler+0x1c>
> 0x7c8e06 <fc_bsg_request_handler+0x1e>: lay     %r15,-112(%r15)
> 0x7c8e0c <fc_bsg_request_handler+0x24>: stg     %r14,152(%r15)
> 0x7c8e12 <fc_bsg_request_handler+0x2a>: lgr     %r9,%r2
> 0x7c8e16 <fc_bsg_request_handler+0x2e>: stg     %r5,176(%r15)
> 0x7c8e1c <fc_bsg_request_handler+0x34>: lgr     %r2,%r5
> 0x7c8e20 <fc_bsg_request_handler+0x38>: lgr     %r6,%r3
> 0x7c8e24 <fc_bsg_request_handler+0x3c>: lgr     %r10,%r4
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3949
> 0x7c8e28 <fc_bsg_request_handler+0x40>: brasl   %r14,0x787968 <get_device>
> 0x7c8e2e <fc_bsg_request_handler+0x46>: cgij    %r2,0,8,0x7c9288 <fc_bsg_request_handler+0x4a0>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3751

there is some confusing inlining of part of fc_req_to_bsgjob

> 0x7c8e34 <fc_bsg_request_handler+0x4c>: la      %r1,960(%r6)
> 0x7c8e38 <fc_bsg_request_handler+0x50>: stg     %r1,168(%r15)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3749
> 0x7c8e3e <fc_bsg_request_handler+0x56>: la      %r1,96(%r10)
> 0x7c8e42 <fc_bsg_request_handler+0x5a>: stg     %r1,160(%r15)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3953
> 0x7c8e48 <fc_bsg_request_handler+0x60>: cgij    %r10,0,8,0x7c9270 <fc_bsg_request_handler+0x488>
> 0x7c8e4e <fc_bsg_request_handler+0x66>: clc     4(4,%r13),40(%r10)
> 0x7c8e54 <fc_bsg_request_handler+0x6c>: jne     0x7c9258 <fc_bsg_request_handler+0x470>
> 0x7c8e58 <fc_bsg_request_handler+0x70>: tm      72(%r10),4
> 0x7c8e5c <fc_bsg_request_handler+0x74>: jne     0x7c9258 <fc_bsg_request_handler+0x470>
> 0x7c8e60 <fc_bsg_request_handler+0x78>: j       0x7c920a <fc_bsg_request_handler+0x422>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3961
> 0x7c8e64 <fc_bsg_request_handler+0x7c>: clc     0(4,%r13),40(%r10)
> 0x7c8e6a <fc_bsg_request_handler+0x82>: je      0x7c8e9e <fc_bsg_request_handler+0xb6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3962

fc_bsg_request_handler()
                         req->errors = -ENXIO;

> 0x7c8e6e <fc_bsg_request_handler+0x86>: mvhi    260(%r12),-6

crash> struct -od request.errors
struct request {
   [260] int errors;
}

********************************************************************

BUT this seems the first time %r12 is used in fc_bsg_request_handler(),
especially I seem to miss %r12 being initalized with anything.
But then again I'm not at all well versed in disassembly.
Maybe fc_bsg_request_handler() is itself in turn inlined and I would 
need to start disassembling even earlier to get to %r12 init?
s390x ELF ABI says %r12:
usage: Local variable, commonly used as GOT pointer;
call effect: saved.
Even if it wasn't initialized and remained NULL below why did it not 
already page fault at above instruction? Silly me, we did not execute 
this instruction as it's "if" conditional. This makes me wonder even 
more where the content of %r12 comes from.

Ulli, Andreas, could you please shed some light on this?

********************************************************************

> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 357
> 0x7c8e74 <fc_bsg_request_handler+0x8c>: lg      %r2,2600(%r9)
> 0x7c8e7a <fc_bsg_request_handler+0x92>: brasl   %r14,0x9a46d0 <_raw_spin_unlock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3964
> 0x7c8e80 <fc_bsg_request_handler+0x98>: lgr     %r2,%r12
> 0x7c8e84 <fc_bsg_request_handler+0x9c>: lghi    %r3,-6
> 0x7c8e88 <fc_bsg_request_handler+0xa0>: brasl   %r14,0x6be2f0 <blk_end_request_all>
> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 332
> 0x7c8e8e <fc_bsg_request_handler+0xa6>: lg      %r2,2600(%r9)
> 0x7c8e94 <fc_bsg_request_handler+0xac>: brasl   %r14,0x9a4280 <_raw_spin_lock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3966
> 0x7c8e9a <fc_bsg_request_handler+0xb2>: j       0x7c8e48 <fc_bsg_request_handler+0x60>
> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 357
> 0x7c8e9e <fc_bsg_request_handler+0xb6>: lg      %r2,2600(%r9)
> 0x7c8ea4 <fc_bsg_request_handler+0xbc>: brasl   %r14,0x9a46d0 <_raw_spin_unlock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3709
> 0x7c8eaa <fc_bsg_request_handler+0xc2>: ltg     %r1,248(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3702
> 0x7c8eb0 <fc_bsg_request_handler+0xc8>: lg      %r7,512(%r6)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3703
> 0x7c8eb6 <fc_bsg_request_handler+0xce>: lg      %r8,360(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3709
> 0x7c8ebc <fc_bsg_request_handler+0xd4>: je      0x7c8ec4 <fc_bsg_request_handler+0xdc>
> 0x7c8ec0 <fc_bsg_request_handler+0xd8>: j       0x7c8ec2 <fc_bsg_request_handler+0xda>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3711
> 0x7c8ec4 <fc_bsg_request_handler+0xdc>: lg      %r1,568(%r7)
> 0x7c8eca <fc_bsg_request_handler+0xe2>: llgf    %r1,216(%r1)
> /home/maier/kernel/linux-vanilla/./include/linux/slab.h: 495
> 0x7c8ed0 <fc_bsg_request_handler+0xe8>: lgfi    %r3,37781696
> 0x7c8ed6 <fc_bsg_request_handler+0xee>: la      %r2,184(%r1)
> 0x7c8eda <fc_bsg_request_handler+0xf2>: brasl   %r14,0x325e38 <__kmalloc>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3713
> 0x7c8ee0 <fc_bsg_request_handler+0xf8>: lgr     %r11,%r2
> 0x7c8ee4 <fc_bsg_request_handler+0xfc>: cgij    %r2,0,8,0x7c9234 <fc_bsg_request_handler+0x44c>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3725

fc_req_to_bsgjob()
         req->special = job;

> 0x7c8eea <fc_bsg_request_handler+0x102>:        stg     %r2,248(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3726
> 0x7c8ef0 <fc_bsg_request_handler+0x108>:        stg     %r6,0(%r2)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3727
> 0x7c8ef6 <fc_bsg_request_handler+0x10e>:        stg     %r10,8(%r2)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3728

fc_req_to_bsgjob()
         job->req = req;

> 0x7c8efc <fc_bsg_request_handler+0x114>:        stg     %r12,24(%r2)

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3729
> 0x7c8f02 <fc_bsg_request_handler+0x11a>:        lg      %r1,568(%r7)
> 0x7c8f08 <fc_bsg_request_handler+0x120>:        lt      %r1,216(%r1)
> 0x7c8f0e <fc_bsg_request_handler+0x126>:        je      0x7c8f1c <fc_bsg_request_handler+0x134>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3730
> 0x7c8f12 <fc_bsg_request_handler+0x12a>:        la      %r1,184(%r2)
> 0x7c8f16 <fc_bsg_request_handler+0x12e>:        stg     %r1,176(%r2)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3731
> 0x7c8f1c <fc_bsg_request_handler+0x134>:        larl    %r4,0x2054808 <proc_scsi+0x48>
> 0x7c8f22 <fc_bsg_request_handler+0x13a>:        larl    %r3,0xbddbd8
> 0x7c8f28 <fc_bsg_request_handler+0x140>:        la      %r2,32(%r11)
> 0x7c8f2c <fc_bsg_request_handler+0x144>:        brasl   %r14,0x1b7ac8 <__raw_spin_lock_init>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3733
> 0x7c8f32 <fc_bsg_request_handler+0x14a>:        llh     %r1,288(%r12)
> 0x7c8f38 <fc_bsg_request_handler+0x150>:        st      %r1,136(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3735
> 0x7c8f3c <fc_bsg_request_handler+0x154>:        mvhi    140(%r11),96
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3737
> 0x7c8f42 <fc_bsg_request_handler+0x15a>:        ltg     %r1,104(%r12)
> 0x7c8f48 <fc_bsg_request_handler+0x160>:        jne     0x7c8f56 <fc_bsg_request_handler+0x16e>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3742
> 0x7c8f4c <fc_bsg_request_handler+0x164>:        cgij    %r8,0,6,0x7c8f84 <fc_bsg_request_handler+0x19c>
> 0x7c8f52 <fc_bsg_request_handler+0x16a>:        j       0x7c8f6e <fc_bsg_request_handler+0x186>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3738
> 0x7c8f56 <fc_bsg_request_handler+0x16e>:        lgr     %r3,%r12
> 0x7c8f5a <fc_bsg_request_handler+0x172>:        la      %r2,144(%r11)
> 0x7c8f5e <fc_bsg_request_handler+0x176>:        brasl   %r14,0x7c56c8 <fc_bsg_map_buffer>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3739
> 0x7c8f64 <fc_bsg_request_handler+0x17c>:        cij     %r2,0,8,0x7c8f4c <fc_bsg_request_handler+0x164>
> 0x7c8f6a <fc_bsg_request_handler+0x182>:        j       0x7c900e <fc_bsg_request_handler+0x226>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3747
> 0x7c8f6e <fc_bsg_request_handler+0x186>:        larl    %r1,0x7c5780 <fc_bsg_jobdone>
> 0x7c8f74 <fc_bsg_request_handler+0x18c>:        stg     %r1,112(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3748
> 0x7c8f7a <fc_bsg_request_handler+0x192>:        cgij    %r10,0,6,0x7c8fa6 <fc_bsg_request_handler+0x1be>
> 0x7c8f80 <fc_bsg_request_handler+0x198>:        j       0x7c8fd2 <fc_bsg_request_handler+0x1ea>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3742
> 0x7c8f84 <fc_bsg_request_handler+0x19c>:        ltg     %r1,104(%r8)
> 0x7c8f8a <fc_bsg_request_handler+0x1a2>:        je      0x7c8f6e <fc_bsg_request_handler+0x186>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3743
> 0x7c8f8e <fc_bsg_request_handler+0x1a6>:        lgr     %r3,%r8
> 0x7c8f92 <fc_bsg_request_handler+0x1aa>:        la      %r2,160(%r11)
> 0x7c8f96 <fc_bsg_request_handler+0x1ae>:        brasl   %r14,0x7c56c8 <fc_bsg_map_buffer>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3744
> 0x7c8f9c <fc_bsg_request_handler+0x1b4>:        cij     %r2,0,8,0x7c8f6e <fc_bsg_request_handler+0x186>
> 0x7c8fa2 <fc_bsg_request_handler+0x1ba>:        j       0x7c9002 <fc_bsg_request_handler+0x21a>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3749
> 0x7c8fa6 <fc_bsg_request_handler+0x1be>:        lg      %r2,160(%r15)
> 0x7c8fac <fc_bsg_request_handler+0x1c4>:        stg     %r2,16(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3752
> 0x7c8fb2 <fc_bsg_request_handler+0x1ca>:        brasl   %r14,0x787968 <get_device>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3754
> 0x7c8fb8 <fc_bsg_request_handler+0x1d0>:        mvhi    108(%r11),1
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3979

      fc_bsg_request_handler()
            job = req->special;

> 0x7c8fbe <fc_bsg_request_handler+0x1d6>:        lg      %r12,248(%r12)

crash> struct -od request.special
struct request {
   [248] void *special;
}

********************************************************************

so above %r12 did contain req, below it contains job.
since we could deref req further up it must have been non-NULL and 
pointing to a mapped page, but req->special is NULL here?
well, req could even have been NULL and we read from address 248 in low 
core here which does not trigger a page fault (only on write to low core).

crash> x/g 248
0xf8 <_text+248>:       0x0

********************************************************************

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3982
> 0x7c8fc4 <fc_bsg_request_handler+0x1dc>:        l       %r1,136(%r12)
> 0x7c8fc8 <fc_bsg_request_handler+0x1e0>:        clij    %r1,3,12,0x7c901c <fc_bsg_request_handler+0x234>
> 0x7c8fce <fc_bsg_request_handler+0x1e6>:        j       0x7c905c <fc_bsg_request_handler+0x274>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3751
> 0x7c8fd2 <fc_bsg_request_handler+0x1ea>:        lg      %r1,168(%r15)
> 0x7c8fd8 <fc_bsg_request_handler+0x1f0>:        stg     %r1,16(%r11)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3752
> 0x7c8fde <fc_bsg_request_handler+0x1f6>:        lgr     %r2,%r1
> 0x7c8fe2 <fc_bsg_request_handler+0x1fa>:        brasl   %r14,0x787968 <get_device>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3754
> 0x7c8fe8 <fc_bsg_request_handler+0x200>:        mvhi    108(%r11),1
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3979
> 0x7c8fee <fc_bsg_request_handler+0x206>:        lg      %r12,248(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3982
> 0x7c8ff4 <fc_bsg_request_handler+0x20c>:        l       %r1,136(%r12)
> 0x7c8ff8 <fc_bsg_request_handler+0x210>:        clij    %r1,3,12,0x7c901c <fc_bsg_request_handler+0x234>
> 0x7c8ffe <fc_bsg_request_handler+0x216>:        j       0x7c90f4 <fc_bsg_request_handler+0x30c>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3760
> 0x7c9002 <fc_bsg_request_handler+0x21a>:        lg      %r2,152(%r11)
> 0x7c9008 <fc_bsg_request_handler+0x220>:        brasl   %r14,0x328ff0 <kfree>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3762
> 0x7c900e <fc_bsg_request_handler+0x226>:        lgr     %r2,%r11
> 0x7c9012 <fc_bsg_request_handler+0x22a>:        brasl   %r14,0x328ff0 <kfree>
> 0x7c9018 <fc_bsg_request_handler+0x230>:        j       0x7c9234 <fc_bsg_request_handler+0x44c>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3983
> 0x7c901c <fc_bsg_request_handler+0x234>:        clfhsi  140(%r12),3
> 0x7c9022 <fc_bsg_request_handler+0x23a>:        jh      0x7c902a <fc_bsg_request_handler+0x242>
> 0x7c9026 <fc_bsg_request_handler+0x23e>:        j       0x7c9028 <fc_bsg_request_handler+0x240>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3984
> 0x7c902a <fc_bsg_request_handler+0x242>:        lg      %r1,128(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3985
> 0x7c9030 <fc_bsg_request_handler+0x248>:        mvhi    4(%r1),0
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3986
> 0x7c9036 <fc_bsg_request_handler+0x24e>:        mvhi    0(%r1),-42
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3988
> 0x7c903c <fc_bsg_request_handler+0x254>:        lgr     %r2,%r12
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3987
> 0x7c9040 <fc_bsg_request_handler+0x258>:        mvhi    140(%r12),4
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3988
> 0x7c9046 <fc_bsg_request_handler+0x25e>:        brasl   %r14,0x7c5780 <fc_bsg_jobdone>
> /home/maier/kernel/linux-vanilla/./include/linux/spinlock.h: 332
> 0x7c904c <fc_bsg_request_handler+0x264>:        lg      %r2,2600(%r9)
> 0x7c9052 <fc_bsg_request_handler+0x26a>:        brasl   %r14,0x9a4280 <_raw_spin_lock_irq>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3990
> 0x7c9058 <fc_bsg_request_handler+0x270>:        j       0x7c8e48 <fc_bsg_request_handler+0x60>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3892
> 0x7c905c <fc_bsg_request_handler+0x274>:        lg      %r2,120(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3887
> 0x7c9062 <fc_bsg_request_handler+0x27a>:        lg      %r11,128(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3892
> 0x7c9068 <fc_bsg_request_handler+0x280>:        l       %r2,0(%r2)
> 0x7c906c <fc_bsg_request_handler+0x284>:        iilf    %r3,1073741825
> 0x7c9072 <fc_bsg_request_handler+0x28a>:        crj     %r2,%r3,8,0x7c9088 <fc_bsg_request_handler+0x2a0>
> 0x7c9078 <fc_bsg_request_handler+0x290>:        iilf    %r3,1073741826
> 0x7c907e <fc_bsg_request_handler+0x296>:        crj     %r2,%r3,8,0x7c9090 <fc_bsg_request_handler+0x2a8>
> 0x7c9084 <fc_bsg_request_handler+0x29c>:        j       0x7c90d2 <fc_bsg_request_handler+0x2ea>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3894
> 0x7c9088 <fc_bsg_request_handler+0x2a0>:        lhi     %r2,5
> 0x7c908c <fc_bsg_request_handler+0x2a4>:        j       0x7c9094 <fc_bsg_request_handler+0x2ac>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3898
> 0x7c9090 <fc_bsg_request_handler+0x2a8>:        lhi     %r2,16
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3901
> 0x7c9094 <fc_bsg_request_handler+0x2ac>:        lt      %r3,144(%r12)
> 0x7c909a <fc_bsg_request_handler+0x2b2>:        je      0x7c90da <fc_bsg_request_handler+0x2f2>
> 0x7c909e <fc_bsg_request_handler+0x2b6>:        lt      %r3,160(%r12)
> 0x7c90a4 <fc_bsg_request_handler+0x2bc>:        je      0x7c90da <fc_bsg_request_handler+0x2f2>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3913
> 0x7c90a8 <fc_bsg_request_handler+0x2c0>:        clrj    %r2,%r1,2,0x7c90e2 <fc_bsg_request_handler+0x2fa>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3918
> 0x7c90ae <fc_bsg_request_handler+0x2c6>:        lg      %r1,512(%r6)
> 0x7c90b4 <fc_bsg_request_handler+0x2cc>:        lg      %r1,568(%r1)
> 0x7c90ba <fc_bsg_request_handler+0x2d2>:        lg      %r1,192(%r1)
> 0x7c90c0 <fc_bsg_request_handler+0x2d8>:        lgr     %r2,%r12
> 0x7c90c4 <fc_bsg_request_handler+0x2dc>:        basr    %r14,%r1
> 0x7c90c6 <fc_bsg_request_handler+0x2de>:        lr      %r1,%r2
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3919
> 0x7c90c8 <fc_bsg_request_handler+0x2e0>:        cij     %r2,0,6,0x7c90e6 <fc_bsg_request_handler+0x2fe>
> 0x7c90ce <fc_bsg_request_handler+0x2e6>:        j       0x7c9248 <fc_bsg_request_handler+0x460>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3908
> 0x7c90d2 <fc_bsg_request_handler+0x2ea>:        lhi     %r1,-53
> 0x7c90d6 <fc_bsg_request_handler+0x2ee>:        j       0x7c90e6 <fc_bsg_request_handler+0x2fe>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3903
> 0x7c90da <fc_bsg_request_handler+0x2f2>:        lhi     %r1,-22
> 0x7c90de <fc_bsg_request_handler+0x2f6>:        j       0x7c90e6 <fc_bsg_request_handler+0x2fe>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3914
> 0x7c90e2 <fc_bsg_request_handler+0x2fa>:        lhi     %r1,-42
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3924
> 0x7c90e6 <fc_bsg_request_handler+0x2fe>:        clfhsi  140(%r12),3
> 0x7c90ec <fc_bsg_request_handler+0x304>:        jh      0x7c91ec <fc_bsg_request_handler+0x404>
> 0x7c90f0 <fc_bsg_request_handler+0x308>:        j       0x7c90f2 <fc_bsg_request_handler+0x30a>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3785

fc_bsg_host_dispatch()
	struct fc_bsg_request *bsg_request = job->request;

> 0x7c90f4 <fc_bsg_request_handler+0x30c>:        lg      %r3,120(%r12)
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3786

fc_bsg_host_dispatch()
	struct fc_bsg_reply *bsg_reply = job->reply;

> 0x7c90fa <fc_bsg_request_handler+0x312>:        lg      %r11,128(%r12)

load content of address in %r12 with displacement 128 into %r11.
so presumably job->reply is NULL.
due to funny inlining incl. fc_bsg_host_dispatch(), it's tricky to 
backtrack where job in %r12 came from and what happened to it on the way.
%r11 is not clobbered until used below where the page fault happens.
displacement is consistent:
crash> struct -od fc_bsg_job
struct fc_bsg_job {
     [0] struct Scsi_Host *shost;
     [8] struct fc_rport *rport;
    [16] struct device *dev;
    [24] struct request *req;
    [32] spinlock_t job_lock;
   [104] unsigned int state_flags;
   [108] unsigned int ref_cnt;
   [112] void (*job_done)(struct fc_bsg_job *);
   [120] struct fc_bsg_request *request;
   [128] struct fc_bsg_reply *reply;
   [136] unsigned int request_len;
   [140] unsigned int reply_len;
   [144] struct bsg_buffer request_payload;
   [160] struct bsg_buffer reply_payload;
   [176] void *dd_data;
}
SIZE: 184

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3791
> 0x7c9100 <fc_bsg_request_handler+0x318>:        l       %r2,0(%r3)
> 0x7c9104 <fc_bsg_request_handler+0x31c>:        clfi    %r2,2147483651
> 0x7c910a <fc_bsg_request_handler+0x322>:        je      0x7c913e <fc_bsg_request_handler+0x356>
> 0x7c910e <fc_bsg_request_handler+0x326>:        jh      0x7c9122 <fc_bsg_request_handler+0x33a>
> 0x7c9112 <fc_bsg_request_handler+0x32a>:        iilf    %r3,2147483649
> 0x7c9118 <fc_bsg_request_handler+0x330>:        clrj    %r2,%r3,10,0x7c9194 <fc_bsg_request_handler+0x3ac>
> 0x7c911e <fc_bsg_request_handler+0x336>:        j       0x7c91c2 <fc_bsg_request_handler+0x3da>
> 0x7c9122 <fc_bsg_request_handler+0x33a>:        iilf    %r4,2147483652
> 0x7c9128 <fc_bsg_request_handler+0x340>:        crj     %r2,%r4,8,0x7c9156 <fc_bsg_request_handler+0x36e>
> 0x7c912e <fc_bsg_request_handler+0x346>:        iilf    %r4,2147483903
> 0x7c9134 <fc_bsg_request_handler+0x34c>:        crj     %r2,%r4,8,0x7c9172 <fc_bsg_request_handler+0x38a>
> 0x7c913a <fc_bsg_request_handler+0x352>:        j       0x7c91c2 <fc_bsg_request_handler+0x3da>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3803
> 0x7c913e <fc_bsg_request_handler+0x356>:        lt      %r2,144(%r12)
> 0x7c9144 <fc_bsg_request_handler+0x35c>:        je      0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c9148 <fc_bsg_request_handler+0x360>:        lt      %r2,160(%r12)
> 0x7c914e <fc_bsg_request_handler+0x366>:        je      0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c9152 <fc_bsg_request_handler+0x36a>:        j       0x7c9194 <fc_bsg_request_handler+0x3ac>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3813
> 0x7c9156 <fc_bsg_request_handler+0x36e>:        lt      %r2,144(%r12)
> 0x7c915c <fc_bsg_request_handler+0x374>:        je      0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c9160 <fc_bsg_request_handler+0x378>:        lt      %r2,160(%r12)
> 0x7c9166 <fc_bsg_request_handler+0x37e>:        je      0x7c91ca <fc_bsg_request_handler+0x3e2>
> 0x7c916a <fc_bsg_request_handler+0x382>:        lhi     %r2,20
> 0x7c916e <fc_bsg_request_handler+0x386>:        j       0x7c9198 <fc_bsg_request_handler+0x3b0>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3822
> 0x7c9172 <fc_bsg_request_handler+0x38a>:        lg      %r2,504(%r6)
> 0x7c9178 <fc_bsg_request_handler+0x390>:        ltg     %r2,304(%r2)
> 0x7c917e <fc_bsg_request_handler+0x396>:        je      0x7c91d2 <fc_bsg_request_handler+0x3ea>
> 0x7c9182 <fc_bsg_request_handler+0x39a>:        cg      %r2,4(%r3)
> 0x7c9188 <fc_bsg_request_handler+0x3a0>:        jne     0x7c91d2 <fc_bsg_request_handler+0x3ea>
> 0x7c918c <fc_bsg_request_handler+0x3a4>:        lhi     %r2,12
> 0x7c9190 <fc_bsg_request_handler+0x3a8>:        j       0x7c9198 <fc_bsg_request_handler+0x3b0>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3791
> 0x7c9194 <fc_bsg_request_handler+0x3ac>:        lhi     %r2,8
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3836
> 0x7c9198 <fc_bsg_request_handler+0x3b0>:        clrj    %r2,%r1,2,0x7c91da <fc_bsg_request_handler+0x3f2>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3841
> 0x7c919e <fc_bsg_request_handler+0x3b6>:        lg      %r1,512(%r6)
> 0x7c91a4 <fc_bsg_request_handler+0x3bc>:        lg      %r1,568(%r1)
> 0x7c91aa <fc_bsg_request_handler+0x3c2>:        lg      %r1,192(%r1)
> 0x7c91b0 <fc_bsg_request_handler+0x3c8>:        lgr     %r2,%r12
> 0x7c91b4 <fc_bsg_request_handler+0x3cc>:        basr    %r14,%r1
> 0x7c91b6 <fc_bsg_request_handler+0x3ce>:        lr      %r1,%r2
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3842
> 0x7c91b8 <fc_bsg_request_handler+0x3d0>:        cij     %r2,0,6,0x7c91de <fc_bsg_request_handler+0x3f6>
> 0x7c91be <fc_bsg_request_handler+0x3d6>:        j       0x7c9248 <fc_bsg_request_handler+0x460>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3831
> 0x7c91c2 <fc_bsg_request_handler+0x3da>:        lhi     %r1,-53
> 0x7c91c6 <fc_bsg_request_handler+0x3de>:        j       0x7c91de <fc_bsg_request_handler+0x3f6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3805
> 0x7c91ca <fc_bsg_request_handler+0x3e2>:        lhi     %r1,-22
> 0x7c91ce <fc_bsg_request_handler+0x3e6>:        j       0x7c91de <fc_bsg_request_handler+0x3f6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3825
> 0x7c91d2 <fc_bsg_request_handler+0x3ea>:        lhi     %r1,-3
> 0x7c91d6 <fc_bsg_request_handler+0x3ee>:        j       0x7c91de <fc_bsg_request_handler+0x3f6>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3837
> 0x7c91da <fc_bsg_request_handler+0x3f2>:        lhi     %r1,-42
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3847

fc_bsg_host_dispatch()

fail_host_msg:
	/* return the errno failure code as the only status */
	BUG_ON(job->reply_len < sizeof(uint32_t));

> 0x7c91de <fc_bsg_request_handler+0x3f6>:        clfhsi  140(%r12),3
> 0x7c91e4 <fc_bsg_request_handler+0x3fc>:        jh      0x7c91ec <fc_bsg_request_handler+0x404>
> 0x7c91e8 <fc_bsg_request_handler+0x400>:        j       0x7c91ea <fc_bsg_request_handler+0x402>
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3849

	bsg_reply->result = ret;

> 0x7c91ec <fc_bsg_request_handler+0x404>:        st      %r1,0(%r11)

that store causes the kernel page fault because %r11 is NULL and with 
displacement 0 it still is NULL.

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3848

	bsg_reply->reply_payload_rcv_len = 0;

> 0x7c91f0 <fc_bsg_request_handler+0x408>:        mvhi    4(%r11),0

if we would have gotten this far:
16-bit signed immediate 0 is extended to 4-bytes and stored to where 
%r11 with displacement 4 points to.
displacements nicely match structure fields:
crash> struct -od fc_bsg_reply
struct fc_bsg_reply {
    [0] uint32_t result;
    [4] uint32_t reply_payload_rcv_len;
        union {
            struct fc_bsg_host_vendor_reply vendor_reply;
            struct fc_bsg_ctels_reply ctels_reply;
    [8] } reply_data;
}
SIZE: 16

> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3850

	job->reply_len = sizeof(uint32_t);

> 0x7c91f6 <fc_bsg_request_handler+0x40e>:        mvhi    140(%r12),4
> /home/maier/kernel/linux-vanilla/drivers/scsi/scsi_transport_fc.c: 3851
> 0x7c91fc <fc_bsg_request_handler+0x414>:        lgr     %r2,%r12
> 0x7c9200 <fc_bsg_request_handler+0x418>:        brasl   %r14,0x7c5780 <fc_bsg_jobdone>

source code is based on
> $ git log --graph --oneline
> * 271c1723d9c8 scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly
> * a3c95a6c69e4 scsi: Get rid of struct fc_bsg_buffer
> *   1573d2caf713 Merge branch 'parisc-4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Andreas Krebbel1 Oct. 28, 2016, 4:29 p.m. UTC | #7
> On 10/28/2016 01:31 PM, Hannes Reinecke wrote:
> > On 10/28/2016 11:53 AM, Steffen Maier wrote:
> >> On 10/13/2016 06:24 PM, Johannes Thumshirn wrote:
> >>> On Thu, Oct 13, 2016 at 05:15:25PM +0200, Steffen Maier wrote:
...
> fc_bsg_request_handler()
>                          req->errors = -ENXIO;
> 
> > 0x7c8e6e <fc_bsg_request_handler+0x86>: mvhi    260(%r12),-6
> 
> crash> struct -od request.errors
> struct request {
>    [260] int errors;
> }
> 
> ********************************************************************
> 
> BUT this seems the first time %r12 is used in fc_bsg_request_handler(),
> especially I seem to miss %r12 being initalized with anything.
> But then again I'm not at all well versed in disassembly.
> Maybe fc_bsg_request_handler() is itself in turn inlined and I would 
> need to start disassembling even earlier to get to %r12 init?
> s390x ELF ABI says %r12:
> usage: Local variable, commonly used as GOT pointer;
> call effect: saved.
> Even if it wasn't initialized and remained NULL below why did it not 
> already page fault at above instruction? Silly me, we did not execute 
> this instruction as it's "if" conditional. This makes me wonder even 
> more where the content of %r12 comes from.
> 
> Ulli, Andreas, could you please shed some light on this?
> 
> ********************************************************************

r12 holds variable req for that access. It is initialized here:

  req = blk_fetch_request(q);    
  if (!req)   
    break;

The asm code ends up down below in the function and loads the return value 
into r12. The code
invoking blk_fetch_request got duplicated and there are three jumps before 
the r12 access to these
locations.

  7c8e48:       ec a8 02 14 00 7c       cgije   %r10,0,7c9270 
<fc_bsg_request_handler+0x488>  <--- x
  7c8e4e:       d5 03 d0 04 a0 28       clc     4(4,%r13),40(%r10)
  7c8e54:       a7 74 02 02             jne     7c9258 
<fc_bsg_request_handler+0x470>         <--- y
  7c8e58:       91 04 a0 48             tm      72(%r10),4
  7c8e5c:       a7 74 01 fe             jne     7c9258 
<fc_bsg_request_handler+0x470>         <--- y
  7c8e60:       a7 f4 01 d5             j       7c920a 
<fc_bsg_request_handler+0x422>
  7c8e64:       d5 03 d0 00 a0 28       clc     0(4,%r13),40(%r10)
  7c8e6a:       a7 84 00 1a             je      7c8e9e 
<fc_bsg_request_handler+0xb6>
  7c8e6e:       e5 4c c1 04 ff fa       mvhi    260(%r12),-6
...

  7c9258:       b9 04 00 29             lgr     %r2,%r9
  7c925c:       c0 e5 ff f7 b3 a6       brasl   %r14,6bf9a8 
<blk_fetch_request>
  7c9262:       b9 04 00 c2             lgr     %r12,%r2
  7c9266:       ec 26 fd ff 00 7c       cgijne  %r2,0,7c8e64 
<fc_bsg_request_handler+0x7c>
  7c926c:       a7 f4 ff cf             j       7c920a 
<fc_bsg_request_handler+0x422>

  7c9270:       b9 04 00 29             lgr     %r2,%r9
  7c9274:       c0 e5 ff f7 b3 9a       brasl   %r14,6bf9a8 
<blk_fetch_request>
  7c927a:       b9 04 00 c2             lgr     %r12,%r2
  7c927e:       ec 26 fe 10 00 7c       cgijne  %r2,0,7c8e9e 
<fc_bsg_request_handler+0xb6>

-Andreas-
Johannes Thumshirn Oct. 30, 2016, 5:56 p.m. UTC | #8
On Fri, Oct 28, 2016 at 11:53:46AM +0200, Steffen Maier wrote:

[...]

> > > 
> > > > @@ -3937,6 +3944,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> > > >  	struct request *req;
> > > >  	struct fc_bsg_job *job;
> > > >  	enum fc_dispatch_result ret;
> > > > +	struct fc_bsg_reply *bsg_reply;
> > > > 
> > > >  	if (!get_device(dev))
> > > >  		return;
> > > > @@ -3973,8 +3981,9 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
> > > >  		/* check if we have the msgcode value at least */
> > > >  		if (job->request_len < sizeof(uint32_t)) {
> > > >  			BUG_ON(job->reply_len < sizeof(uint32_t));
> > > > -			job->reply->reply_payload_rcv_len = 0;
> > > > -			job->reply->result = -ENOMSG;
> > > > +			bsg_reply = job->reply;
> > > > +			bsg_reply->reply_payload_rcv_len = 0;
> > > > +			bsg_reply->result = -ENOMSG;
> 
> Compiler optimization re-ordered above two lines and the first pointer
> derefence is bsg_reply->result [field offset 0] where bsg_reply is NULL.
> The assignment tries to write to memory at address NULL causing the kernel
> page fault.
> 
> Does your suggested change for [PATCH v3 02/16], shuffling the
> job->request_len checks, address above kernel page fault?

This is what I hope at least. I'm sorry but I don't have any experience with s390
and zfcp at all. I still need to get a test environment set up, but all the
people knowing how to do are rather busy at the moment. All my tests on x86_64
with FCoE and lpfc haven't had a problem so far.

Thanks,
	Johannes
diff mbox

Patch

diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 237688a..4c4023f 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -900,8 +900,9 @@  static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
 	u32 preamble_word1;
 	u8 gs_type;
 	struct zfcp_adapter *adapter;
+	struct fc_bsg_request *bsg_request = job->request;
 
-	preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
+	preamble_word1 = bsg_request->rqst_data.r_ct.preamble_word1;
 	gs_type = (preamble_word1 & 0xff000000) >> 24;
 
 	adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
@@ -938,6 +939,7 @@  static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
 {
 	struct zfcp_fsf_ct_els *els = job->dd_data;
 	struct fc_rport *rport = job->rport;
+	struct fc_bsg_request *bsg_request = job->request;
 	struct zfcp_port *port;
 	u32 d_id;
 
@@ -949,7 +951,7 @@  static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
 		d_id = port->d_id;
 		put_device(&port->dev);
 	} else
-		d_id = ntoh24(job->request->rqst_data.h_els.port_id);
+		d_id = ntoh24(bsg_request->rqst_data.h_els.port_id);
 
 	els->handler = zfcp_fc_ct_els_job_handler;
 	return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
@@ -983,6 +985,7 @@  int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
 	struct Scsi_Host *shost;
 	struct zfcp_adapter *adapter;
 	struct zfcp_fsf_ct_els *ct_els = job->dd_data;
+	struct fc_bsg_request *bsg_request = job->request;
 
 	shost = job->rport ? rport_to_shost(job->rport) : job->shost;
 	adapter = (struct zfcp_adapter *)shost->hostdata[0];
@@ -994,7 +997,7 @@  int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
 	ct_els->resp = job->reply_payload.sg_list;
 	ct_els->handler_data = job;
 
-	switch (job->request->msgcode) {
+	switch (bsg_request->msgcode) {
 	case FC_BSG_RPT_ELS:
 	case FC_BSG_HST_ELS_NOLOGIN:
 		return zfcp_fc_exec_els_job(job, adapter);
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index d1ad020..48366d8 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3132,7 +3132,9 @@  bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
 static int
 bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
 {
-	uint32_t vendor_cmd = job->request->rqst_data.h_vendor.vendor_cmd[0];
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
+	uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0];
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) job->shost->hostdata[0];
 	struct bfad_s *bfad = im_port->bfad;
@@ -3175,8 +3177,8 @@  bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
 
 	/* Fill the BSG job reply data */
 	job->reply_len = job->reply_payload.payload_len;
-	job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
-	job->reply->result = rc;
+	bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len;
+	bsg_reply->result = rc;
 
 	job->job_done(job);
 	return rc;
@@ -3184,9 +3186,9 @@  error:
 	/* free the command buffer */
 	kfree(payload_kbuf);
 out:
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->reply_len = sizeof(uint32_t);
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 	return rc;
 }
 
@@ -3362,18 +3364,20 @@  bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
 	struct bfad_fcxp    *drv_fcxp;
 	struct bfa_fcs_lport_s *fcs_port;
 	struct bfa_fcs_rport_s *fcs_rport;
-	uint32_t command_type = job->request->msgcode;
+	struct fc_bsg_request *bsg_request = bsg_request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
+	uint32_t command_type = bsg_request->msgcode;
 	unsigned long flags;
 	struct bfad_buf_info *rsp_buf_info;
 	void *req_kbuf = NULL, *rsp_kbuf = NULL;
 	int rc = -EINVAL;
 
 	job->reply_len  = sizeof(uint32_t);	/* Atleast uint32_t reply_len */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	/* Get the payload passed in from userspace */
-	bsg_data = (struct bfa_bsg_data *) (((char *)job->request) +
-					sizeof(struct fc_bsg_request));
+	bsg_data = (struct bfa_bsg_data *) (((char *)bsg_request) +
+					    sizeof(struct fc_bsg_request));
 	if (bsg_data == NULL)
 		goto out;
 
@@ -3517,13 +3521,13 @@  bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
 	/* fill the job->reply data */
 	if (drv_fcxp->req_status == BFA_STATUS_OK) {
 		job->reply_len = drv_fcxp->rsp_len;
-		job->reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
-		job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+		bsg_reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
+		bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
 	} else {
-		job->reply->reply_payload_rcv_len =
+		bsg_reply->reply_payload_rcv_len =
 					sizeof(struct fc_bsg_ctels_reply);
 		job->reply_len = sizeof(uint32_t);
-		job->reply->reply_data.ctels_reply.status =
+		bsg_reply->reply_data.ctels_reply.status =
 						FC_CTELS_STATUS_REJECT;
 	}
 
@@ -3549,7 +3553,7 @@  out_free_mem:
 	kfree(bsg_fcpt);
 	kfree(drv_fcxp);
 out:
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 
 	if (rc == BFA_STATUS_OK)
 		job->job_done(job);
@@ -3560,9 +3564,11 @@  out:
 int
 bfad_im_bsg_request(struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	uint32_t rc = BFA_STATUS_OK;
 
-	switch (job->request->msgcode) {
+	switch (bsg_request->msgcode) {
 	case FC_BSG_HST_VENDOR:
 		/* Process BSG HST Vendor requests */
 		rc = bfad_im_bsg_vendor_request(job);
@@ -3575,8 +3581,8 @@  bfad_im_bsg_request(struct fc_bsg_job *job)
 		rc = bfad_im_bsg_els_ct_request(job);
 		break;
 	default:
-		job->reply->result = rc = -EINVAL;
-		job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->result = rc = -EINVAL;
+		bsg_reply->reply_payload_rcv_len = 0;
 		break;
 	}
 
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index ab67ec4..8b55279 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1821,28 +1821,30 @@  static int ibmvfc_bsg_request(struct fc_bsg_job *job)
 	struct ibmvfc_event *evt;
 	union ibmvfc_iu rsp_iu;
 	unsigned long flags, port_id = -1;
-	unsigned int code = job->request->msgcode;
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
+	unsigned int code = bsg_request->msgcode;
 	int rc = 0, req_seg, rsp_seg, issue_login = 0;
 	u32 fc_flags, rsp_len;
 
 	ENTER;
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 	if (rport)
 		port_id = rport->port_id;
 
 	switch (code) {
 	case FC_BSG_HST_ELS_NOLOGIN:
-		port_id = (job->request->rqst_data.h_els.port_id[0] << 16) |
-			(job->request->rqst_data.h_els.port_id[1] << 8) |
-			job->request->rqst_data.h_els.port_id[2];
+		port_id = (bsg_request->rqst_data.h_els.port_id[0] << 16) |
+			(bsg_request->rqst_data.h_els.port_id[1] << 8) |
+			bsg_request->rqst_data.h_els.port_id[2];
 	case FC_BSG_RPT_ELS:
 		fc_flags = IBMVFC_FC_ELS;
 		break;
 	case FC_BSG_HST_CT:
 		issue_login = 1;
-		port_id = (job->request->rqst_data.h_ct.port_id[0] << 16) |
-			(job->request->rqst_data.h_ct.port_id[1] << 8) |
-			job->request->rqst_data.h_ct.port_id[2];
+		port_id = (bsg_request->rqst_data.h_ct.port_id[0] << 16) |
+			(bsg_request->rqst_data.h_ct.port_id[1] << 8) |
+			bsg_request->rqst_data.h_ct.port_id[2];
 	case FC_BSG_RPT_CT:
 		fc_flags = IBMVFC_FC_CT_IU;
 		break;
@@ -1931,12 +1933,12 @@  static int ibmvfc_bsg_request(struct fc_bsg_job *job)
 	if (rsp_iu.passthru.common.status)
 		rc = -EIO;
 	else
-		job->reply->reply_payload_rcv_len = rsp_len;
+		bsg_reply->reply_payload_rcv_len = rsp_len;
 
 	spin_lock_irqsave(vhost->host->host_lock, flags);
 	ibmvfc_free_event(evt);
 	spin_unlock_irqrestore(vhost->host->host_lock, flags);
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->job_done(job);
 	rc = 0;
 out:
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 04ce7cf..a1c12e7 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1901,13 +1901,14 @@  static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
 {
 	struct fc_bsg_info *info = info_arg;
 	struct fc_bsg_job *job = info->job;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct fc_lport *lport = info->lport;
 	struct fc_frame_header *fh;
 	size_t len;
 	void *buf;
 
 	if (IS_ERR(fp)) {
-		job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
+		bsg_reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ?
 			-ECONNABORTED : -ETIMEDOUT;
 		job->reply_len = sizeof(uint32_t);
 		job->state_flags |= FC_RQST_STATE_DONE;
@@ -1928,23 +1929,23 @@  static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
 			(unsigned short)fc_frame_payload_op(fp);
 
 		/* Save the reply status of the job */
-		job->reply->reply_data.ctels_reply.status =
+		bsg_reply->reply_data.ctels_reply.status =
 			(cmd == info->rsp_code) ?
 			FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT;
 	}
 
-	job->reply->reply_payload_rcv_len +=
+	bsg_reply->reply_payload_rcv_len +=
 		fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
 					 &info->offset, NULL);
 
 	if (fr_eof(fp) == FC_EOF_T &&
 	    (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
 	    (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
-		if (job->reply->reply_payload_rcv_len >
+		if (bsg_reply->reply_payload_rcv_len >
 		    job->reply_payload.payload_len)
-			job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				job->reply_payload.payload_len;
-		job->reply->result = 0;
+		bsg_reply->result = 0;
 		job->state_flags |= FC_RQST_STATE_DONE;
 		job->job_done(job);
 		kfree(info);
@@ -2081,6 +2082,8 @@  static int fc_lport_ct_request(struct fc_bsg_job *job,
  */
 int fc_lport_bsg_request(struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct request *rsp = job->req->next_rq;
 	struct Scsi_Host *shost = job->shost;
 	struct fc_lport *lport = shost_priv(shost);
@@ -2089,13 +2092,13 @@  int fc_lport_bsg_request(struct fc_bsg_job *job)
 	int rc = -EINVAL;
 	u32 did, tov;
 
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 	if (rsp)
 		rsp->resid_len = job->reply_payload.payload_len;
 
 	mutex_lock(&lport->lp_mutex);
 
-	switch (job->request->msgcode) {
+	switch (bsg_request->msgcode) {
 	case FC_BSG_RPT_ELS:
 		rport = job->rport;
 		if (!rport)
@@ -2117,7 +2120,7 @@  int fc_lport_bsg_request(struct fc_bsg_job *job)
 		break;
 
 	case FC_BSG_HST_CT:
-		did = ntoh24(job->request->rqst_data.h_ct.port_id);
+		did = ntoh24(bsg_request->rqst_data.h_ct.port_id);
 		if (did == FC_FID_DIR_SERV) {
 			rdata = lport->dns_rdata;
 			if (!rdata)
@@ -2135,7 +2138,7 @@  int fc_lport_bsg_request(struct fc_bsg_job *job)
 		break;
 
 	case FC_BSG_HST_ELS_NOLOGIN:
-		did = ntoh24(job->request->rqst_data.h_els.port_id);
+		did = ntoh24(bsg_request->rqst_data.h_els.port_id);
 		rc = fc_lport_els_request(job, lport, did, lport->e_d_tov);
 		break;
 	}
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 1002627..27b5930 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -299,6 +299,7 @@  lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
 {
 	struct bsg_job_data *dd_data;
 	struct fc_bsg_job *job;
+	struct fc_bsg_reply *bsg_reply;
 	IOCB_t *rsp;
 	struct lpfc_dmabuf *bmp, *cmp, *rmp;
 	struct lpfc_nodelist *ndlp;
@@ -313,6 +314,7 @@  lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	job = dd_data->set_job;
 	if (job) {
+		bsg_reply = job->reply;
 		/* Prevent timeout handling from trying to abort job */
 		job->dd_data = NULL;
 	}
@@ -351,7 +353,7 @@  lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
 			}
 		} else {
 			rsp_size = rsp->un.genreq64.bdl.bdeSize;
-			job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				lpfc_bsg_copy_data(rmp, &job->reply_payload,
 						   rsp_size, 0);
 		}
@@ -368,7 +370,7 @@  lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
 	/* Complete the job if the job is still active */
 
 	if (job) {
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		job->job_done(job);
 	}
 	return;
@@ -385,6 +387,7 @@  lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_rport_data *rdata = job->rport->dd_data;
 	struct lpfc_nodelist *ndlp = rdata->pnode;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct ulp_bde64 *bpl = NULL;
 	uint32_t timeout;
 	struct lpfc_iocbq *cmdiocbq = NULL;
@@ -399,7 +402,7 @@  lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
 	int iocb_stat;
 
 	/* in case no data is transferred */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	/* allocate our bsg tracking structure */
 	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -543,7 +546,7 @@  no_ndlp:
 	kfree(dd_data);
 no_dd_data:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->dd_data = NULL;
 	return rc;
 }
@@ -572,6 +575,7 @@  lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
 {
 	struct bsg_job_data *dd_data;
 	struct fc_bsg_job *job;
+	struct fc_bsg_reply *bsg_reply;
 	IOCB_t *rsp;
 	struct lpfc_nodelist *ndlp;
 	struct lpfc_dmabuf *pcmd = NULL, *prsp = NULL;
@@ -589,6 +593,7 @@  lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	job = dd_data->set_job;
 	if (job) {
+		bsg_reply = job->reply;
 		/* Prevent timeout handling from trying to abort job  */
 		job->dd_data = NULL;
 	}
@@ -610,17 +615,17 @@  lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
 	if (job) {
 		if (rsp->ulpStatus == IOSTAT_SUCCESS) {
 			rsp_size = rsp->un.elsreq64.bdl.bdeSize;
-			job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				sg_copy_from_buffer(job->reply_payload.sg_list,
 						    job->reply_payload.sg_cnt,
 						    prsp->virt,
 						    rsp_size);
 		} else if (rsp->ulpStatus == IOSTAT_LS_RJT) {
-			job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				sizeof(struct fc_bsg_ctels_reply);
 			/* LS_RJT data returned in word 4 */
 			rjt_data = (uint8_t *)&rsp->un.ulpWord[4];
-			els_reply = &job->reply->reply_data.ctels_reply;
+			els_reply = &bsg_reply->reply_data.ctels_reply;
 			els_reply->status = FC_CTELS_STATUS_REJECT;
 			els_reply->rjt_data.action = rjt_data[3];
 			els_reply->rjt_data.reason_code = rjt_data[2];
@@ -638,7 +643,7 @@  lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
 	/* Complete the job if the job is still active */
 
 	if (job) {
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		job->job_done(job);
 	}
 	return;
@@ -655,6 +660,8 @@  lpfc_bsg_rport_els(struct fc_bsg_job *job)
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_rport_data *rdata = job->rport->dd_data;
 	struct lpfc_nodelist *ndlp = rdata->pnode;
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	uint32_t elscmd;
 	uint32_t cmdsize;
 	struct lpfc_iocbq *cmdiocbq;
@@ -665,7 +672,7 @@  lpfc_bsg_rport_els(struct fc_bsg_job *job)
 	int rc = 0;
 
 	/* in case no data is transferred */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	/* verify the els command is not greater than the
 	 * maximum ELS transfer size.
@@ -685,7 +692,7 @@  lpfc_bsg_rport_els(struct fc_bsg_job *job)
 		goto no_dd_data;
 	}
 
-	elscmd = job->request->rqst_data.r_els.els_code;
+	elscmd = bsg_request->rqst_data.r_els.els_code;
 	cmdsize = job->request_payload.payload_len;
 
 	if (!lpfc_nlp_get(ndlp)) {
@@ -772,7 +779,7 @@  free_dd_data:
 
 no_dd_data:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->dd_data = NULL;
 	return rc;
 }
@@ -919,6 +926,7 @@  lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	struct lpfc_hbq_entry *hbqe;
 	struct lpfc_sli_ct_request *ct_req;
 	struct fc_bsg_job *job = NULL;
+	struct fc_bsg_reply *bsg_reply;
 	struct bsg_job_data *dd_data = NULL;
 	unsigned long flags;
 	int size = 0;
@@ -1121,9 +1129,10 @@  lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		dd_data->set_job = NULL;
 		lpfc_bsg_event_unref(evt);
 		if (job) {
-			job->reply->reply_payload_rcv_len = size;
+			bsg_reply = job->reply;
+			bsg_reply->reply_payload_rcv_len = size;
 			/* make error code available to userspace */
-			job->reply->result = 0;
+			bsg_reply->result = 0;
 			job->dd_data = NULL;
 			/* complete the job back to userspace */
 			spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
@@ -1192,6 +1201,7 @@  lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
+	struct fc_bsg_request *bsg_request = job->request;
 	struct set_ct_event *event_req;
 	struct lpfc_bsg_event *evt;
 	int rc = 0;
@@ -1209,7 +1219,7 @@  lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
 	}
 
 	event_req = (struct set_ct_event *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+		bsg_request->rqst_data.h_vendor.vendor_cmd;
 	ev_mask = ((uint32_t)(unsigned long)event_req->type_mask &
 				FC_REG_EVENT_MASK);
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
@@ -1276,6 +1286,8 @@  lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct get_ct_event *event_req;
 	struct get_ct_event_reply *event_reply;
 	struct lpfc_bsg_event *evt, *evt_next;
@@ -1293,10 +1305,10 @@  lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
 	}
 
 	event_req = (struct get_ct_event *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+		bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	event_reply = (struct get_ct_event_reply *)
-		job->reply->reply_data.vendor_reply.vendor_rsp;
+		bsg_reply->reply_data.vendor_reply.vendor_rsp;
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	list_for_each_entry_safe(evt, evt_next, &phba->ct_ev_waiters, node) {
 		if (evt->reg_id == event_req->ev_reg_id) {
@@ -1316,7 +1328,7 @@  lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
 	 * an error indicating that there isn't anymore
 	 */
 	if (evt_dat == NULL) {
-		job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->reply_payload_rcv_len = 0;
 		rc = -ENOENT;
 		goto job_error;
 	}
@@ -1332,12 +1344,12 @@  lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
 	event_reply->type = evt_dat->type;
 	event_reply->immed_data = evt_dat->immed_dat;
 	if (evt_dat->len > 0)
-		job->reply->reply_payload_rcv_len =
+		bsg_reply->reply_payload_rcv_len =
 			sg_copy_from_buffer(job->request_payload.sg_list,
 					    job->request_payload.sg_cnt,
 					    evt_dat->data, evt_dat->len);
 	else
-		job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->reply_payload_rcv_len = 0;
 
 	if (evt_dat) {
 		kfree(evt_dat->data);
@@ -1348,13 +1360,13 @@  lpfc_bsg_hba_get_event(struct fc_bsg_job *job)
 	lpfc_bsg_event_unref(evt);
 	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 	job->dd_data = NULL;
-	job->reply->result = 0;
+	bsg_reply->result = 0;
 	job->job_done(job);
 	return 0;
 
 job_error:
 	job->dd_data = NULL;
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	return rc;
 }
 
@@ -1382,6 +1394,7 @@  lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
 {
 	struct bsg_job_data *dd_data;
 	struct fc_bsg_job *job;
+	struct fc_bsg_reply *bsg_reply;
 	IOCB_t *rsp;
 	struct lpfc_dmabuf *bmp, *cmp;
 	struct lpfc_nodelist *ndlp;
@@ -1412,6 +1425,7 @@  lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
 	/* Copy the completed job data or set the error status */
 
 	if (job) {
+		bsg_reply = job->reply;
 		if (rsp->ulpStatus) {
 			if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
 				switch (rsp->un.ulpWord[4] & IOERR_PARAM_MASK) {
@@ -1429,7 +1443,7 @@  lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
 				rc = -EACCES;
 			}
 		} else {
-			job->reply->reply_payload_rcv_len = 0;
+			bsg_reply->reply_payload_rcv_len = 0;
 		}
 	}
 
@@ -1443,7 +1457,7 @@  lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
 	/* Complete the job if the job is still active */
 
 	if (job) {
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		job->job_done(job);
 	}
 	return;
@@ -1608,8 +1622,10 @@  lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct send_mgmt_resp *mgmt_resp = (struct send_mgmt_resp *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+		bsg_request->rqst_data.h_vendor.vendor_cmd;
 	struct ulp_bde64 *bpl;
 	struct lpfc_dmabuf *bmp = NULL, *cmp = NULL;
 	int bpl_entries;
@@ -1619,7 +1635,7 @@  lpfc_bsg_send_mgmt_rsp(struct fc_bsg_job *job)
 	int rc = 0;
 
 	/* in case no data is transferred */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	if (!reqbfrcnt || (reqbfrcnt > (80 * BUF_SZ_4K))) {
 		rc = -ERANGE;
@@ -1665,7 +1681,7 @@  send_mgmt_rsp_free_bmp:
 	kfree(bmp);
 send_mgmt_rsp_exit:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->dd_data = NULL;
 	return rc;
 }
@@ -1763,6 +1779,8 @@  lpfc_bsg_diag_mode_exit(struct lpfc_hba *phba)
 static int
 lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct diag_mode_set *loopback_mode;
 	uint32_t link_flags;
 	uint32_t timeout;
@@ -1772,7 +1790,7 @@  lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
 	int rc = 0;
 
 	/* no data to return just the return code */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	if (job->request_len < sizeof(struct fc_bsg_request) +
 	    sizeof(struct diag_mode_set)) {
@@ -1792,7 +1810,7 @@  lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
 
 	/* bring the link to diagnostic mode */
 	loopback_mode = (struct diag_mode_set *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+		bsg_request->rqst_data.h_vendor.vendor_cmd;
 	link_flags = loopback_mode->type;
 	timeout = loopback_mode->timeout * 100;
 
@@ -1865,7 +1883,7 @@  loopback_mode_exit:
 
 job_error:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	/* complete the job back to userspace if no error */
 	if (rc == 0)
 		job->job_done(job);
@@ -2018,12 +2036,14 @@  lpfc_sli4_diag_fcport_reg_setup(struct lpfc_hba *phba)
 static int
 lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct diag_mode_set *loopback_mode;
 	uint32_t link_flags, timeout;
 	int i, rc = 0;
 
 	/* no data to return just the return code */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	if (job->request_len < sizeof(struct fc_bsg_request) +
 	    sizeof(struct diag_mode_set)) {
@@ -2055,7 +2075,7 @@  lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
 	lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
 			"3129 Bring link to diagnostic state.\n");
 	loopback_mode = (struct diag_mode_set *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+		bsg_request->rqst_data.h_vendor.vendor_cmd;
 	link_flags = loopback_mode->type;
 	timeout = loopback_mode->timeout * 100;
 
@@ -2152,7 +2172,7 @@  loopback_mode_exit:
 
 job_error:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	/* complete the job back to userspace if no error */
 	if (rc == 0)
 		job->job_done(job);
@@ -2205,6 +2225,8 @@  lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
 static int
 lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct Scsi_Host *shost;
 	struct lpfc_vport *vport;
 	struct lpfc_hba *phba;
@@ -2233,7 +2255,7 @@  lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
 	phba->link_flag &= ~LS_LOOPBACK_MODE;
 	spin_unlock_irq(&phba->hbalock);
 	loopback_mode_end_cmd = (struct diag_mode_set *)
-			job->request->rqst_data.h_vendor.vendor_cmd;
+			bsg_request->rqst_data.h_vendor.vendor_cmd;
 	timeout = loopback_mode_end_cmd->timeout * 100;
 
 	rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0);
@@ -2264,7 +2286,7 @@  lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
 
 loopback_mode_end_exit:
 	/* make return code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	/* complete the job back to userspace if no error */
 	if (rc == 0)
 		job->job_done(job);
@@ -2281,6 +2303,8 @@  loopback_mode_end_exit:
 static int
 lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct Scsi_Host *shost;
 	struct lpfc_vport *vport;
 	struct lpfc_hba *phba;
@@ -2336,7 +2360,7 @@  lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
 		goto job_error;
 
 	link_diag_test_cmd = (struct sli4_link_diag *)
-			 job->request->rqst_data.h_vendor.vendor_cmd;
+			 bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);
 
@@ -2386,7 +2410,7 @@  lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
 	}
 
 	diag_status_reply = (struct diag_status *)
-			    job->reply->reply_data.vendor_reply.vendor_rsp;
+			    bsg_reply->reply_data.vendor_reply.vendor_rsp;
 
 	if (job->reply_len <
 	    sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) {
@@ -2414,7 +2438,7 @@  link_diag_test_exit:
 
 job_error:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	/* complete the job back to userspace if no error */
 	if (rc == 0)
 		job->job_done(job);
@@ -2986,6 +3010,7 @@  static int
 lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_bsg_event *evt;
 	struct event_data *evdat;
@@ -3013,7 +3038,7 @@  lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
 	uint32_t total_mem;
 
 	/* in case no data is returned return just the return code */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	if (job->request_len <
 	    sizeof(struct fc_bsg_request) + sizeof(struct diag_mode_test)) {
@@ -3238,11 +3263,11 @@  lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
 			rc = IOCB_SUCCESS;
 			/* skip over elx loopback header */
 			rx_databuf += ELX_LOOPBACK_HEADER_SZ;
-			job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				sg_copy_from_buffer(job->reply_payload.sg_list,
 						    job->reply_payload.sg_cnt,
 						    rx_databuf, size);
-			job->reply->reply_payload_rcv_len = size;
+			bsg_reply->reply_payload_rcv_len = size;
 		}
 	}
 
@@ -3272,7 +3297,7 @@  err_loopback_test_exit:
 loopback_test_exit:
 	kfree(dataout);
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->dd_data = NULL;
 	/* complete the job back to userspace if no error */
 	if (rc == IOCB_SUCCESS)
@@ -3288,6 +3313,7 @@  static int
 lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct lpfc_hba *phba = vport->phba;
 	struct get_mgmt_rev_reply *event_reply;
 	int rc = 0;
@@ -3302,7 +3328,7 @@  lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
 	}
 
 	event_reply = (struct get_mgmt_rev_reply *)
-		job->reply->reply_data.vendor_reply.vendor_rsp;
+		bsg_reply->reply_data.vendor_reply.vendor_rsp;
 
 	if (job->reply_len <
 	    sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev_reply)) {
@@ -3316,7 +3342,7 @@  lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
 	event_reply->info.a_Major = MANAGEMENT_MAJOR_REV;
 	event_reply->info.a_Minor = MANAGEMENT_MINOR_REV;
 job_error:
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	if (rc == 0)
 		job->job_done(job);
 	return rc;
@@ -3337,6 +3363,7 @@  static void
 lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 {
 	struct bsg_job_data *dd_data;
+	struct fc_bsg_reply *bsg_reply;
 	struct fc_bsg_job *job;
 	uint32_t size;
 	unsigned long flags;
@@ -3365,8 +3392,9 @@  lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 	/* Copy the mailbox data to the job if it is still active */
 
 	if (job) {
+		bsg_reply = job->reply;
 		size = job->reply_payload.payload_len;
-		job->reply->reply_payload_rcv_len =
+		bsg_reply->reply_payload_rcv_len =
 			sg_copy_from_buffer(job->reply_payload.sg_list,
 					    job->reply_payload.sg_cnt,
 					    pmb_buf, size);
@@ -3380,7 +3408,7 @@  lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 	/* Complete the job if the job is still active */
 
 	if (job) {
-		job->reply->result = 0;
+		bsg_reply->result = 0;
 		job->job_done(job);
 	}
 	return;
@@ -3516,6 +3544,7 @@  lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 {
 	struct bsg_job_data *dd_data;
 	struct fc_bsg_job *job;
+	struct fc_bsg_reply *bsg_reply;
 	uint8_t *pmb, *pmb_buf;
 	unsigned long flags;
 	uint32_t size;
@@ -3530,6 +3559,7 @@  lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	job = dd_data->set_job;
 	if (job) {
+		bsg_reply = job->reply;
 		/* Prevent timeout handling from trying to abort job  */
 		job->dd_data = NULL;
 	}
@@ -3560,13 +3590,13 @@  lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 
 	if (job) {
 		size = job->reply_payload.payload_len;
-		job->reply->reply_payload_rcv_len =
+		bsg_reply->reply_payload_rcv_len =
 			sg_copy_from_buffer(job->reply_payload.sg_list,
 					    job->reply_payload.sg_cnt,
 					    pmb_buf, size);
 
 		/* result for successful */
-		job->reply->result = 0;
+		bsg_reply->result = 0;
 
 		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
 				"2937 SLI_CONFIG ext-buffer maibox command "
@@ -3773,6 +3803,7 @@  lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
 			      enum nemb_type nemb_tp,
 			      struct lpfc_dmabuf *dmabuf)
 {
+	struct fc_bsg_request *bsg_request = job->request;
 	struct lpfc_sli_config_mbox *sli_cfg_mbx;
 	struct dfc_mbox_req *mbox_req;
 	struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf;
@@ -3785,7 +3816,7 @@  lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
 	int rc, i;
 
 	mbox_req =
-	   (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+	   (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	/* pointer to the start of mailbox command */
 	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
@@ -3960,6 +3991,8 @@  lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
 			       enum nemb_type nemb_tp,
 			       struct lpfc_dmabuf *dmabuf)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct dfc_mbox_req *mbox_req;
 	struct lpfc_sli_config_mbox *sli_cfg_mbx;
 	uint32_t ext_buf_cnt;
@@ -3970,7 +4003,7 @@  lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
 	int rc = SLI_CONFIG_NOT_HANDLED, i;
 
 	mbox_req =
-	   (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+	   (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	/* pointer to the start of mailbox command */
 	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
@@ -4097,7 +4130,7 @@  lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
 
 	/* wait for additoinal external buffers */
 
-	job->reply->result = 0;
+	bsg_reply->result = 0;
 	job->job_done(job);
 	return SLI_CONFIG_HANDLED;
 
@@ -4271,6 +4304,7 @@  lpfc_bsg_mbox_ext_abort(struct lpfc_hba *phba)
 static int
 lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
 {
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct lpfc_sli_config_mbox *sli_cfg_mbx;
 	struct lpfc_dmabuf *dmabuf;
 	uint8_t *pbuf;
@@ -4308,7 +4342,7 @@  lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
 					dmabuf, index);
 
 	pbuf = (uint8_t *)dmabuf->virt;
-	job->reply->reply_payload_rcv_len =
+	bsg_reply->reply_payload_rcv_len =
 		sg_copy_from_buffer(job->reply_payload.sg_list,
 				    job->reply_payload.sg_cnt,
 				    pbuf, size);
@@ -4322,7 +4356,7 @@  lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
 		lpfc_bsg_mbox_ext_session_reset(phba);
 	}
 
-	job->reply->result = 0;
+	bsg_reply->result = 0;
 	job->job_done(job);
 
 	return SLI_CONFIG_HANDLED;
@@ -4340,6 +4374,7 @@  static int
 lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
 			struct lpfc_dmabuf *dmabuf)
 {
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct bsg_job_data *dd_data = NULL;
 	LPFC_MBOXQ_t *pmboxq = NULL;
 	MAILBOX_t *pmb;
@@ -4437,7 +4472,7 @@  lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
 	}
 
 	/* wait for additoinal external buffers */
-	job->reply->result = 0;
+	bsg_reply->result = 0;
 	job->job_done(job);
 	return SLI_CONFIG_HANDLED;
 
@@ -4506,11 +4541,12 @@  static int
 lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
 			    struct lpfc_dmabuf *dmabuf)
 {
+	struct fc_bsg_request *bsg_request = job->request;
 	struct dfc_mbox_req *mbox_req;
 	int rc = SLI_CONFIG_NOT_HANDLED;
 
 	mbox_req =
-	   (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+	   (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	/* mbox command with/without single external buffer */
 	if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0)
@@ -4583,6 +4619,8 @@  static int
 lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 	struct lpfc_vport *vport)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	LPFC_MBOXQ_t *pmboxq = NULL; /* internal mailbox queue */
 	MAILBOX_t *pmb; /* shortcut to the pmboxq mailbox */
 	/* a 4k buffer to hold the mb and extended data from/to the bsg */
@@ -4601,7 +4639,7 @@  lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 	uint32_t size;
 
 	/* in case no data is transferred */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	/* sanity check to protect driver */
 	if (job->reply_payload.payload_len > BSG_MBOX_SIZE ||
@@ -4620,7 +4658,7 @@  lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 	}
 
 	mbox_req =
-	    (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+	    (struct dfc_mbox_req *)bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	/* check if requested extended data lengths are valid */
 	if ((mbox_req->inExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t)) ||
@@ -4842,7 +4880,7 @@  lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 
 		/* job finished, copy the data */
 		memcpy(pmbx, pmb, sizeof(*pmb));
-		job->reply->reply_payload_rcv_len =
+		bsg_reply->reply_payload_rcv_len =
 			sg_copy_from_buffer(job->reply_payload.sg_list,
 					    job->reply_payload.sg_cnt,
 					    pmbx, size);
@@ -4874,12 +4912,14 @@  static int
 lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct lpfc_hba *phba = vport->phba;
 	struct dfc_mbox_req *mbox_req;
 	int rc = 0;
 
 	/* mix-and-match backward compatibility */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 	if (job->request_len <
 	    sizeof(struct fc_bsg_request) + sizeof(struct dfc_mbox_req)) {
 		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
@@ -4890,7 +4930,7 @@  lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
 				      sizeof(struct fc_bsg_request)),
 				(int)sizeof(struct dfc_mbox_req));
 		mbox_req = (struct dfc_mbox_req *)
-				job->request->rqst_data.h_vendor.vendor_cmd;
+				bsg_request->rqst_data.h_vendor.vendor_cmd;
 		mbox_req->extMboxTag = 0;
 		mbox_req->extSeqNum = 0;
 	}
@@ -4899,7 +4939,7 @@  lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
 
 	if (rc == 0) {
 		/* job done */
-		job->reply->result = 0;
+		bsg_reply->result = 0;
 		job->dd_data = NULL;
 		job->job_done(job);
 	} else if (rc == 1)
@@ -4907,7 +4947,7 @@  lpfc_bsg_mbox_cmd(struct fc_bsg_job *job)
 		rc = 0; /* return zero, no error */
 	else {
 		/* some error occurred */
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		job->dd_data = NULL;
 	}
 
@@ -4938,6 +4978,7 @@  lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
 {
 	struct bsg_job_data *dd_data;
 	struct fc_bsg_job *job;
+	struct fc_bsg_reply *bsg_reply;
 	IOCB_t *rsp;
 	struct lpfc_dmabuf *bmp, *cmp, *rmp;
 	struct lpfc_bsg_menlo *menlo;
@@ -4957,6 +4998,7 @@  lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	job = dd_data->set_job;
 	if (job) {
+		bsg_reply = job->reply;
 		/* Prevent timeout handling from trying to abort job  */
 		job->dd_data = NULL;
 	}
@@ -4971,7 +5013,7 @@  lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
 		 */
 
 		menlo_resp = (struct menlo_response *)
-			job->reply->reply_data.vendor_reply.vendor_rsp;
+			bsg_reply->reply_data.vendor_reply.vendor_rsp;
 		menlo_resp->xri = rsp->ulpContext;
 		if (rsp->ulpStatus) {
 			if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
@@ -4991,7 +5033,7 @@  lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
 			}
 		} else {
 			rsp_size = rsp->un.genreq64.bdl.bdeSize;
-			job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				lpfc_bsg_copy_data(rmp, &job->reply_payload,
 						   rsp_size, 0);
 		}
@@ -5008,7 +5050,7 @@  lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
 	/* Complete the job if active */
 
 	if (job) {
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		job->job_done(job);
 	}
 
@@ -5028,6 +5070,8 @@  static int
 lpfc_menlo_cmd(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_iocbq *cmdiocbq;
 	IOCB_t *cmd;
@@ -5040,7 +5084,7 @@  lpfc_menlo_cmd(struct fc_bsg_job *job)
 	struct ulp_bde64 *bpl = NULL;
 
 	/* in case no data is returned return just the return code */
-	job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 	if (job->request_len <
 	    sizeof(struct fc_bsg_request) +
@@ -5070,7 +5114,7 @@  lpfc_menlo_cmd(struct fc_bsg_job *job)
 	}
 
 	menlo_cmd = (struct menlo_command *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+		bsg_request->rqst_data.h_vendor.vendor_cmd;
 
 	/* allocate our bsg tracking structure */
 	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
@@ -5181,7 +5225,7 @@  free_dd:
 	kfree(dd_data);
 no_dd_data:
 	/* make error code available to userspace */
-	job->reply->result = rc;
+	bsg_reply->result = rc;
 	job->dd_data = NULL;
 	return rc;
 }
@@ -5193,7 +5237,9 @@  no_dd_data:
 static int
 lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
 {
-	int command = job->request->rqst_data.h_vendor.vendor_cmd[0];
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
+	int command = bsg_request->rqst_data.h_vendor.vendor_cmd[0];
 	int rc;
 
 	switch (command) {
@@ -5230,9 +5276,9 @@  lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
 		break;
 	default:
 		rc = -EINVAL;
-		job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->reply_payload_rcv_len = 0;
 		/* make error code available to userspace */
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		break;
 	}
 
@@ -5246,10 +5292,12 @@  lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
 int
 lpfc_bsg_request(struct fc_bsg_job *job)
 {
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	uint32_t msgcode;
 	int rc;
 
-	msgcode = job->request->msgcode;
+	msgcode = bsg_request->msgcode;
 	switch (msgcode) {
 	case FC_BSG_HST_VENDOR:
 		rc = lpfc_bsg_hst_vendor(job);
@@ -5262,9 +5310,9 @@  lpfc_bsg_request(struct fc_bsg_job *job)
 		break;
 	default:
 		rc = -EINVAL;
-		job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->reply_payload_rcv_len = 0;
 		/* make error code available to userspace */
-		job->reply->result = rc;
+		bsg_reply->result = rc;
 		break;
 	}
 
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 643014f..40f7c10 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -17,8 +17,9 @@  qla2x00_bsg_job_done(void *data, void *ptr, int res)
 	srb_t *sp = (srb_t *)ptr;
 	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
 	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 
-	bsg_job->reply->result = res;
+	bsg_reply->result = res;
 	bsg_job->job_done(bsg_job);
 	sp->free(vha, sp);
 }
@@ -29,12 +30,14 @@  qla2x00_bsg_sp_free(void *data, void *ptr)
 	srb_t *sp = (srb_t *)ptr;
 	struct scsi_qla_host *vha = sp->fcport->vha;
 	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
 
 	if (sp->type == SRB_FXIOCB_BCMD) {
 		piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
-		    &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+		    &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
 		if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
 			dma_unmap_sg(&ha->pdev->dev,
@@ -119,6 +122,8 @@  static int
 qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 {
 	struct Scsi_Host *host = bsg_job->shost;
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
 	int ret = 0;
@@ -131,7 +136,7 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 	}
 
 	/* Get the sub command */
-	oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
 	/* Only set config is allowed if config memory is not allocated */
 	if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
@@ -145,10 +150,10 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 			ha->fcp_prio_cfg->attributes &=
 				~FCP_PRIO_ATTR_ENABLE;
 			qla24xx_update_all_fcp_prio(vha);
-			bsg_job->reply->result = DID_OK;
+			bsg_reply->result = DID_OK;
 		} else {
 			ret = -EINVAL;
-			bsg_job->reply->result = (DID_ERROR << 16);
+			bsg_reply->result = (DID_ERROR << 16);
 			goto exit_fcp_prio_cfg;
 		}
 		break;
@@ -160,10 +165,10 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 				ha->fcp_prio_cfg->attributes |=
 				    FCP_PRIO_ATTR_ENABLE;
 				qla24xx_update_all_fcp_prio(vha);
-				bsg_job->reply->result = DID_OK;
+				bsg_reply->result = DID_OK;
 			} else {
 				ret = -EINVAL;
-				bsg_job->reply->result = (DID_ERROR << 16);
+				bsg_reply->result = (DID_ERROR << 16);
 				goto exit_fcp_prio_cfg;
 			}
 		}
@@ -173,12 +178,12 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 		len = bsg_job->reply_payload.payload_len;
 		if (!len || len > FCP_PRIO_CFG_SIZE) {
 			ret = -EINVAL;
-			bsg_job->reply->result = (DID_ERROR << 16);
+			bsg_reply->result = (DID_ERROR << 16);
 			goto exit_fcp_prio_cfg;
 		}
 
-		bsg_job->reply->result = DID_OK;
-		bsg_job->reply->reply_payload_rcv_len =
+		bsg_reply->result = DID_OK;
+		bsg_reply->reply_payload_rcv_len =
 			sg_copy_from_buffer(
 			bsg_job->reply_payload.sg_list,
 			bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
@@ -189,7 +194,7 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 	case QLFC_FCP_PRIO_SET_CONFIG:
 		len = bsg_job->request_payload.payload_len;
 		if (!len || len > FCP_PRIO_CFG_SIZE) {
-			bsg_job->reply->result = (DID_ERROR << 16);
+			bsg_reply->result = (DID_ERROR << 16);
 			ret = -EINVAL;
 			goto exit_fcp_prio_cfg;
 		}
@@ -200,7 +205,7 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 				ql_log(ql_log_warn, vha, 0x7050,
 				    "Unable to allocate memory for fcp prio "
 				    "config data (%x).\n", FCP_PRIO_CFG_SIZE);
-				bsg_job->reply->result = (DID_ERROR << 16);
+				bsg_reply->result = (DID_ERROR << 16);
 				ret = -ENOMEM;
 				goto exit_fcp_prio_cfg;
 			}
@@ -215,7 +220,7 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 
 		if (!qla24xx_fcp_prio_cfg_valid(vha,
 		    (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) {
-			bsg_job->reply->result = (DID_ERROR << 16);
+			bsg_reply->result = (DID_ERROR << 16);
 			ret = -EINVAL;
 			/* If buffer was invalidatic int
 			 * fcp_prio_cfg is of no use
@@ -229,7 +234,7 @@  qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 		if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
 			ha->flags.fcp_prio_enabled = 1;
 		qla24xx_update_all_fcp_prio(vha);
-		bsg_job->reply->result = DID_OK;
+		bsg_reply->result = DID_OK;
 		break;
 	default:
 		ret = -EINVAL;
@@ -244,6 +249,7 @@  exit_fcp_prio_cfg:
 static int
 qla2x00_process_els(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
 	struct fc_rport *rport;
 	fc_port_t *fcport = NULL;
 	struct Scsi_Host *host;
@@ -255,7 +261,7 @@  qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	int rval =  (DRIVER_ERROR << 16);
 	uint16_t nextlid = 0;
 
-	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
 		rport = bsg_job->rport;
 		fcport = *(fc_port_t **) rport->dd_data;
 		host = rport_to_shost(rport);
@@ -296,7 +302,7 @@  qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	}
 
 	/* ELS request for rport */
-	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
 		/* make sure the rport is logged in,
 		 * if not perform fabric login
 		 */
@@ -322,11 +328,11 @@  qla2x00_process_els(struct fc_bsg_job *bsg_job)
 		/* Initialize all required  fields of fcport */
 		fcport->vha = vha;
 		fcport->d_id.b.al_pa =
-			bsg_job->request->rqst_data.h_els.port_id[0];
+			bsg_request->rqst_data.h_els.port_id[0];
 		fcport->d_id.b.area =
-			bsg_job->request->rqst_data.h_els.port_id[1];
+			bsg_request->rqst_data.h_els.port_id[1];
 		fcport->d_id.b.domain =
-			bsg_job->request->rqst_data.h_els.port_id[2];
+			bsg_request->rqst_data.h_els.port_id[2];
 		fcport->loop_id =
 			(fcport->d_id.b.al_pa == 0xFD) ?
 			NPH_FABRIC_CONTROLLER : NPH_F_PORT;
@@ -366,11 +372,11 @@  qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	}
 
 	sp->type =
-		(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
-		SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
+		(bsg_request->msgcode == FC_BSG_RPT_ELS ?
+		 SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
 	sp->name =
-		(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
-		"bsg_els_rpt" : "bsg_els_hst");
+		(bsg_request->msgcode == FC_BSG_RPT_ELS ?
+		 "bsg_els_rpt" : "bsg_els_hst");
 	sp->u.bsg_job = bsg_job;
 	sp->free = qla2x00_bsg_sp_free;
 	sp->done = qla2x00_bsg_job_done;
@@ -378,7 +384,7 @@  qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	ql_dbg(ql_dbg_user, vha, 0x700a,
 	    "bsg rqst type: %s els type: %x - loop-id=%x "
 	    "portid=%-2x%02x%02x.\n", type,
-	    bsg_job->request->rqst_data.h_els.command_code, fcport->loop_id,
+	    bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
 	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
 
 	rval = qla2x00_start_sp(sp);
@@ -399,7 +405,7 @@  done_unmap_sg:
 	goto done_free_fcport;
 
 done_free_fcport:
-	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS)
+	if (bsg_request->msgcode == FC_BSG_RPT_ELS)
 		kfree(fcport);
 done:
 	return rval;
@@ -423,6 +429,7 @@  static int
 qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 {
 	srb_t *sp;
+	struct fc_bsg_request *bsg_request = bsg_job->request;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -469,7 +476,7 @@  qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 	}
 
 	loop_id =
-		(bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
+		(bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
 			>> 24;
 	switch (loop_id) {
 	case 0xFC:
@@ -500,9 +507,9 @@  qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 
 	/* Initialize all required  fields of fcport */
 	fcport->vha = vha;
-	fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0];
-	fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1];
-	fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2];
+	fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0];
+	fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1];
+	fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2];
 	fcport->loop_id = loop_id;
 
 	/* Alloc SRB structure */
@@ -524,7 +531,7 @@  qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 	ql_dbg(ql_dbg_user, vha, 0x7016,
 	    "bsg rqst type: %s else type: %x - "
 	    "loop-id=%x portid=%02x%02x%02x.\n", type,
-	    (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16),
+	    (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
 	    fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
 	    fcport->d_id.b.al_pa);
 
@@ -699,6 +706,8 @@  done_set_internal:
 static int
 qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -780,9 +789,9 @@  qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 	elreq.rcv_dma = rsp_data_dma;
 	elreq.transfer_size = req_data_len;
 
-	elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 	elreq.iteration_count =
-	    bsg_job->request->rqst_data.h_vendor.vendor_cmd[2];
+	    bsg_request->rqst_data.h_vendor.vendor_cmd[2];
 
 	if (atomic_read(&vha->loop_state) == LOOP_READY &&
 	    (ha->current_topology == ISP_CFG_F ||
@@ -896,12 +905,12 @@  qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 		    "Vendor request %s failed.\n", type);
 
 		rval = 0;
-		bsg_job->reply->result = (DID_ERROR << 16);
-		bsg_job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->result = (DID_ERROR << 16);
+		bsg_reply->reply_payload_rcv_len = 0;
 	} else {
 		ql_dbg(ql_dbg_user, vha, 0x702d,
 		    "Vendor request %s completed.\n", type);
-		bsg_job->reply->result = (DID_OK << 16);
+		bsg_reply->result = (DID_OK << 16);
 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 			bsg_job->reply_payload.sg_cnt, rsp_data,
 			rsp_data_len);
@@ -937,7 +946,9 @@  done_unmap_req_sg:
 static int
 qla84xx_reset(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
 	struct Scsi_Host *host = bsg_job->shost;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
 	int rval = 0;
@@ -948,7 +959,7 @@  qla84xx_reset(struct fc_bsg_job *bsg_job)
 		return -EINVAL;
 	}
 
-	flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
 	rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
 
@@ -960,7 +971,7 @@  qla84xx_reset(struct fc_bsg_job *bsg_job)
 	} else {
 		ql_dbg(ql_dbg_user, vha, 0x7031,
 		    "Vendor request 84xx reset completed.\n");
-		bsg_job->reply->result = DID_OK;
+		bsg_reply->result = DID_OK;
 		bsg_job->job_done(bsg_job);
 	}
 
@@ -970,6 +981,8 @@  qla84xx_reset(struct fc_bsg_job *bsg_job)
 static int
 qla84xx_updatefw(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1027,7 +1040,7 @@  qla84xx_updatefw(struct fc_bsg_job *bsg_job)
 		goto done_free_fw_buf;
 	}
 
-	flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 	fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2)));
 
 	memset(mn, 0, sizeof(struct access_chip_84xx));
@@ -1059,7 +1072,7 @@  qla84xx_updatefw(struct fc_bsg_job *bsg_job)
 		    "Vendor request 84xx updatefw completed.\n");
 
 		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-		bsg_job->reply->result = DID_OK;
+		bsg_reply->result = DID_OK;
 	}
 
 	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
@@ -1079,6 +1092,8 @@  done_unmap_sg:
 static int
 qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1107,7 +1122,7 @@  qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
 	memset(mn, 0, sizeof(struct access_chip_84xx));
 	mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
 	mn->entry_count = 1;
-	ql84_mgmt = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
+	ql84_mgmt = (void *)bsg_request + sizeof(struct fc_bsg_request);
 	switch (ql84_mgmt->mgmt.cmd) {
 	case QLA84_MGMT_READ_MEM:
 	case QLA84_MGMT_GET_INFO:
@@ -1239,11 +1254,11 @@  qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
 		    "Vendor request 84xx mgmt completed.\n");
 
 		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-		bsg_job->reply->result = DID_OK;
+		bsg_reply->result = DID_OK;
 
 		if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
 			(ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
-			bsg_job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 				bsg_job->reply_payload.payload_len;
 
 			sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
@@ -1274,6 +1289,8 @@  exit_mgmt:
 static int
 qla24xx_iidma(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	int rval = 0;
@@ -1288,7 +1305,7 @@  qla24xx_iidma(struct fc_bsg_job *bsg_job)
 		return -EINVAL;
 	}
 
-	port_param = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
+	port_param = (void *)bsg_request + sizeof(struct fc_bsg_request);
 	if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
 		ql_log(ql_log_warn, vha, 0x7048,
 		    "Invalid destination type.\n");
@@ -1343,14 +1360,14 @@  qla24xx_iidma(struct fc_bsg_job *bsg_job)
 			bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
 				sizeof(struct qla_port_param);
 
-			rsp_ptr = ((uint8_t *)bsg_job->reply) +
+			rsp_ptr = ((uint8_t *)bsg_reply) +
 				sizeof(struct fc_bsg_reply);
 
 			memcpy(rsp_ptr, port_param,
 				sizeof(struct qla_port_param));
 		}
 
-		bsg_job->reply->result = DID_OK;
+		bsg_reply->result = DID_OK;
 		bsg_job->job_done(bsg_job);
 	}
 
@@ -1361,6 +1378,7 @@  static int
 qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
 	uint8_t is_update)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
 	uint32_t start = 0;
 	int valid = 0;
 	struct qla_hw_data *ha = vha->hw;
@@ -1368,7 +1386,7 @@  qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
 	if (unlikely(pci_channel_offline(ha->pdev)))
 		return -EINVAL;
 
-	start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	start = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 	if (start > ha->optrom_size) {
 		ql_log(ql_log_warn, vha, 0x7055,
 		    "start %d > optrom_size %d.\n", start, ha->optrom_size);
@@ -1429,6 +1447,7 @@  qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
 static int
 qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1451,8 +1470,8 @@  qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
 	    bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
 	    ha->optrom_region_size);
 
-	bsg_job->reply->reply_payload_rcv_len = ha->optrom_region_size;
-	bsg_job->reply->result = DID_OK;
+	bsg_reply->reply_payload_rcv_len = ha->optrom_region_size;
+	bsg_reply->result = DID_OK;
 	vfree(ha->optrom_buffer);
 	ha->optrom_buffer = NULL;
 	ha->optrom_state = QLA_SWAITING;
@@ -1464,6 +1483,7 @@  qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
 static int
 qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1486,7 +1506,7 @@  qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
 	ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
 	    ha->optrom_region_start, ha->optrom_region_size);
 
-	bsg_job->reply->result = DID_OK;
+	bsg_reply->result = DID_OK;
 	vfree(ha->optrom_buffer);
 	ha->optrom_buffer = NULL;
 	ha->optrom_state = QLA_SWAITING;
@@ -1498,6 +1518,7 @@  qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
 static int
 qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1509,7 +1530,7 @@  qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
 	dma_addr_t sfp_dma;
 	void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
 	if (!sfp) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_NO_MEMORY;
 		goto done;
 	}
@@ -1525,21 +1546,21 @@  qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
 		    image->field_address.device, image->field_address.offset,
 		    sizeof(image->field_info), image->field_address.option);
 		if (rval) {
-			bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+			bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 			    EXT_STATUS_MAILBOX;
 			goto dealloc;
 		}
 		image++;
 	}
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
 
 dealloc:
 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
 
 done:
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	return 0;
@@ -1548,6 +1569,7 @@  done:
 static int
 qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1557,7 +1579,7 @@  qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
 	dma_addr_t sfp_dma;
 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
 	if (!sfp) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_NO_MEMORY;
 		goto done;
 	}
@@ -1571,7 +1593,7 @@  qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
 	sr->status_reg = *sfp;
 
 	if (rval) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_MAILBOX;
 		goto dealloc;
 	}
@@ -1579,15 +1601,15 @@  qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 	    bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
 
 dealloc:
 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
 
 done:
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->reply_payload_rcv_len = sizeof(*sr);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->reply_payload_rcv_len = sizeof(*sr);
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	return 0;
@@ -1596,6 +1618,7 @@  done:
 static int
 qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1605,7 +1628,7 @@  qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
 	dma_addr_t sfp_dma;
 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
 	if (!sfp) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_NO_MEMORY;
 		goto done;
 	}
@@ -1619,19 +1642,19 @@  qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
 	    sizeof(sr->status_reg), sr->field_address.option);
 
 	if (rval) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_MAILBOX;
 		goto dealloc;
 	}
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
 
 dealloc:
 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
 
 done:
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	return 0;
@@ -1640,6 +1663,7 @@  done:
 static int
 qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1649,7 +1673,7 @@  qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
 	dma_addr_t sfp_dma;
 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
 	if (!sfp) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_NO_MEMORY;
 		goto done;
 	}
@@ -1662,19 +1686,19 @@  qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
 	    i2c->device, i2c->offset, i2c->length, i2c->option);
 
 	if (rval) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_MAILBOX;
 		goto dealloc;
 	}
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
 
 dealloc:
 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
 
 done:
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	return 0;
@@ -1683,6 +1707,7 @@  done:
 static int
 qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1692,7 +1717,7 @@  qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
 	dma_addr_t sfp_dma;
 	uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
 	if (!sfp) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_NO_MEMORY;
 		goto done;
 	}
@@ -1704,7 +1729,7 @@  qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
 		i2c->device, i2c->offset, i2c->length, i2c->option);
 
 	if (rval) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_MAILBOX;
 		goto dealloc;
 	}
@@ -1713,15 +1738,15 @@  qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 	    bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
 
 dealloc:
 	dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
 
 done:
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->reply_payload_rcv_len = sizeof(*i2c);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	return 0;
@@ -1730,6 +1755,7 @@  done:
 static int
 qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1895,10 +1921,10 @@  done:
 	/* Return an error vendor specific response
 	 * and complete the bsg request
 	 */
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->reply_payload_rcv_len = 0;
-	bsg_job->reply->result = (DID_OK) << 16;
+	bsg_reply->reply_payload_rcv_len = 0;
+	bsg_reply->result = (DID_OK) << 16;
 	bsg_job->job_done(bsg_job);
 	/* Always return success, vendor rsp carries correct status */
 	return 0;
@@ -1907,6 +1933,7 @@  done:
 static int
 qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -1919,7 +1946,7 @@  qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)
 
 	/* Copy the IOCB specific information */
 	piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
-	    &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	    &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
 	/* Dump the vendor information */
 	ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
@@ -2029,6 +2056,7 @@  done:
 static int
 qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	int rval = 0;
@@ -2042,13 +2070,13 @@  qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
 	switch (sr.cmd) {
 	case INT_SC_SERDES_WRITE_REG:
 		rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
-		bsg_job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->reply_payload_rcv_len = 0;
 		break;
 	case INT_SC_SERDES_READ_REG:
 		rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 		    bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
-		bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
+		bsg_reply->reply_payload_rcv_len = sizeof(sr);
 		break;
 	default:
 		ql_dbg(ql_dbg_user, vha, 0x708c,
@@ -2057,11 +2085,11 @@  qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
 		break;
 	}
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 	    rval ? EXT_STATUS_MAILBOX : 0;
 
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 	return 0;
 }
@@ -2069,6 +2097,7 @@  qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
 static int
 qla8044_serdes_op(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	int rval = 0;
@@ -2082,13 +2111,13 @@  qla8044_serdes_op(struct fc_bsg_job *bsg_job)
 	switch (sr.cmd) {
 	case INT_SC_SERDES_WRITE_REG:
 		rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
-		bsg_job->reply->reply_payload_rcv_len = 0;
+		bsg_reply->reply_payload_rcv_len = 0;
 		break;
 	case INT_SC_SERDES_READ_REG:
 		rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
 		sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 		    bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
-		bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
+		bsg_reply->reply_payload_rcv_len = sizeof(sr);
 		break;
 	default:
 		ql_dbg(ql_dbg_user, vha, 0x70cf,
@@ -2097,11 +2126,11 @@  qla8044_serdes_op(struct fc_bsg_job *bsg_job)
 		break;
 	}
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 	    rval ? EXT_STATUS_MAILBOX : 0;
 
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 	return 0;
 }
@@ -2109,6 +2138,7 @@  qla8044_serdes_op(struct fc_bsg_job *bsg_job)
 static int
 qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -2125,13 +2155,13 @@  qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
 
 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 	    bsg_job->reply_payload.sg_cnt, &cap, sizeof(cap));
-	bsg_job->reply->reply_payload_rcv_len = sizeof(cap);
+	bsg_reply->reply_payload_rcv_len = sizeof(cap);
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 	    EXT_STATUS_OK;
 
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 	return 0;
 }
@@ -2139,6 +2169,7 @@  qla27xx_get_flash_upd_cap(struct fc_bsg_job *bsg_job)
 static int
 qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -2158,24 +2189,24 @@  qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
 			 (uint64_t)ha->fw_attributes;
 
 	if (online_fw_attr != cap.capabilities) {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_INVALID_PARAM;
 		return -EINVAL;
 	}
 
 	if (cap.outage_duration < MAX_LOOP_TIMEOUT)  {
-		bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+		bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 		    EXT_STATUS_INVALID_PARAM;
 		return -EINVAL;
 	}
 
-	bsg_job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 	    EXT_STATUS_OK;
 
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 	return 0;
 }
@@ -2183,6 +2214,7 @@  qla27xx_set_flash_upd_cap(struct fc_bsg_job *bsg_job)
 static int
 qla27xx_get_bbcr_data(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -2227,12 +2259,12 @@  qla27xx_get_bbcr_data(struct fc_bsg_job *bsg_job)
 done:
 	sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
 		bsg_job->reply_payload.sg_cnt, &bbcr, sizeof(bbcr));
-	bsg_job->reply->reply_payload_rcv_len = sizeof(bbcr);
+	bsg_reply->reply_payload_rcv_len = sizeof(bbcr);
 
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
 
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 	return 0;
 }
@@ -2240,6 +2272,8 @@  done:
 static int
 qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	struct qla_hw_data *ha = vha->hw;
@@ -2247,7 +2281,7 @@  qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
 	struct link_statistics *stats = NULL;
 	dma_addr_t stats_dma;
 	int rval;
-	uint32_t *cmd = bsg_job->request->rqst_data.h_vendor.vendor_cmd;
+	uint32_t *cmd = bsg_request->rqst_data.h_vendor.vendor_cmd;
 	uint options = cmd[0] == QL_VND_GET_PRIV_STATS_EX ? cmd[1] : 0;
 
 	if (test_bit(UNLOADING, &vha->dpc_flags))
@@ -2281,12 +2315,12 @@  qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
 			bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
 	}
 
-	bsg_job->reply->reply_payload_rcv_len = sizeof(*stats);
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+	bsg_reply->reply_payload_rcv_len = sizeof(*stats);
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 	    rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
 
-	bsg_job->reply_len = sizeof(*bsg_job->reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_job->reply_len = sizeof(*bsg_reply);
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
@@ -2298,6 +2332,7 @@  qla2x00_get_priv_stats(struct fc_bsg_job *bsg_job)
 static int
 qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	struct Scsi_Host *host = bsg_job->shost;
 	scsi_qla_host_t *vha = shost_priv(host);
 	int rval;
@@ -2323,12 +2358,12 @@  qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
 		    bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
 	}
 
-	bsg_job->reply->reply_payload_rcv_len = sizeof(*dd);
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
+	bsg_reply->reply_payload_rcv_len = sizeof(*dd);
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
 	    rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
 
-	bsg_job->reply_len = sizeof(*bsg_job->reply);
-	bsg_job->reply->result = DID_OK << 16;
+	bsg_job->reply_len = sizeof(*bsg_reply);
+	bsg_reply->result = DID_OK << 16;
 	bsg_job->job_done(bsg_job);
 
 	kfree(dd);
@@ -2339,7 +2374,9 @@  qla2x00_do_dport_diagnostics(struct fc_bsg_job *bsg_job)
 static int
 qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
 {
-	switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+
+	switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
 	case QL_VND_LOOPBACK:
 		return qla2x00_process_loopback(bsg_job);
 
@@ -2415,15 +2452,17 @@  qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
 int
 qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_request *bsg_request = bsg_job->request;
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	int ret = -EINVAL;
 	struct fc_rport *rport;
 	struct Scsi_Host *host;
 	scsi_qla_host_t *vha;
 
 	/* In case no data transferred. */
-	bsg_job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
-	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
+	if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
 		rport = bsg_job->rport;
 		host = rport_to_shost(rport);
 		vha = shost_priv(host);
@@ -2435,14 +2474,14 @@  qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
 	if (qla2x00_reset_active(vha)) {
 		ql_dbg(ql_dbg_user, vha, 0x709f,
 		    "BSG: ISP abort active/needed -- cmd=%d.\n",
-		    bsg_job->request->msgcode);
+		    bsg_request->msgcode);
 		return -EBUSY;
 	}
 
 	ql_dbg(ql_dbg_user, vha, 0x7000,
-	    "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
+	    "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
 
-	switch (bsg_job->request->msgcode) {
+	switch (bsg_request->msgcode) {
 	case FC_BSG_RPT_ELS:
 	case FC_BSG_HST_ELS_NOLOGIN:
 		ret = qla2x00_process_els(bsg_job);
@@ -2466,6 +2505,7 @@  qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
 int
 qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
 {
+	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
 	scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
 	struct qla_hw_data *ha = vha->hw;
 	srb_t *sp;
@@ -2494,13 +2534,13 @@  qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
 						    "mbx abort_command "
 						    "failed.\n");
 						bsg_job->req->errors =
-						bsg_job->reply->result = -EIO;
+						bsg_reply->result = -EIO;
 					} else {
 						ql_dbg(ql_dbg_user, vha, 0x708a,
 						    "mbx abort_command "
 						    "success.\n");
 						bsg_job->req->errors =
-						bsg_job->reply->result = 0;
+						bsg_reply->result = 0;
 					}
 					spin_lock_irqsave(&ha->hardware_lock, flags);
 					goto done;
@@ -2510,7 +2550,7 @@  qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
-	bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
+	bsg_job->req->errors = bsg_reply->result = -ENXIO;
 	return 0;
 
 done:
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index b41265a..6929fda 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2198,6 +2198,7 @@  static void
 qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
 {
 	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+	struct fc_bsg_request *bsg_request = bsg_job->request;
 
         els_iocb->entry_type = ELS_IOCB_TYPE;
         els_iocb->entry_count = 1;
@@ -2212,8 +2213,8 @@  qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
 
 	els_iocb->opcode =
 	    sp->type == SRB_ELS_CMD_RPT ?
-	    bsg_job->request->rqst_data.r_els.els_code :
-	    bsg_job->request->rqst_data.h_els.command_code;
+	    bsg_request->rqst_data.r_els.els_code :
+	    bsg_request->rqst_data.h_els.command_code;
         els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
         els_iocb->port_id[1] = sp->fcport->d_id.b.area;
         els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 987f1c7..1adaad3 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1357,6 +1357,7 @@  qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 	const char *type;
 	srb_t *sp;
 	struct fc_bsg_job *bsg_job;
+	struct fc_bsg_reply *bsg_reply;
 	uint16_t comp_status;
 	int res;
 
@@ -1365,6 +1366,7 @@  qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 		return;
 
 	bsg_job = sp->u.bsg_job;
+	bsg_reply = bsg_job->reply;
 
 	type = "ct pass-through";
 
@@ -1373,32 +1375,32 @@  qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 	/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
 	 * fc payload  to the caller
 	 */
-	bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+	bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
 
 	if (comp_status != CS_COMPLETE) {
 		if (comp_status == CS_DATA_UNDERRUN) {
 			res = DID_OK << 16;
-			bsg_job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 			    le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
 
 			ql_log(ql_log_warn, vha, 0x5048,
 			    "CT pass-through-%s error "
 			    "comp_status-status=0x%x total_byte = 0x%x.\n",
 			    type, comp_status,
-			    bsg_job->reply->reply_payload_rcv_len);
+			    bsg_reply->reply_payload_rcv_len);
 		} else {
 			ql_log(ql_log_warn, vha, 0x5049,
 			    "CT pass-through-%s error "
 			    "comp_status-status=0x%x.\n", type, comp_status);
 			res = DID_ERROR << 16;
-			bsg_job->reply->reply_payload_rcv_len = 0;
+			bsg_reply->reply_payload_rcv_len = 0;
 		}
 		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
 		    (uint8_t *)pkt, sizeof(*pkt));
 	} else {
 		res = DID_OK << 16;
-		bsg_job->reply->reply_payload_rcv_len =
+		bsg_reply->reply_payload_rcv_len =
 		    bsg_job->reply_payload.payload_len;
 		bsg_job->reply_len = 0;
 	}
@@ -1414,6 +1416,7 @@  qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 	const char *type;
 	srb_t *sp;
 	struct fc_bsg_job *bsg_job;
+	struct fc_bsg_reply *bsg_reply;
 	uint16_t comp_status;
 	uint32_t fw_status[3];
 	uint8_t* fw_sts_ptr;
@@ -1423,6 +1426,7 @@  qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 	if (!sp)
 		return;
 	bsg_job = sp->u.bsg_job;
+	bsg_reply = bsg_job->reply;
 
 	type = NULL;
 	switch (sp->type) {
@@ -1452,13 +1456,13 @@  qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 	/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
 	 * fc payload  to the caller
 	 */
-	bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
+	bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);
 
 	if (comp_status != CS_COMPLETE) {
 		if (comp_status == CS_DATA_UNDERRUN) {
 			res = DID_OK << 16;
-			bsg_job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 			    le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count);
 
 			ql_dbg(ql_dbg_user, vha, 0x503f,
@@ -1480,7 +1484,7 @@  qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 			    le16_to_cpu(((struct els_sts_entry_24xx *)
 				    pkt)->error_subcode_2));
 			res = DID_ERROR << 16;
-			bsg_job->reply->reply_payload_rcv_len = 0;
+			bsg_reply->reply_payload_rcv_len = 0;
 			fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
 			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
 		}
@@ -1489,7 +1493,7 @@  qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 	}
 	else {
 		res =  DID_OK << 16;
-		bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
+		bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
 		bsg_job->reply_len = 0;
 	}
 
@@ -1905,6 +1909,8 @@  qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 	uint16_t thread_id;
 	uint32_t rval = EXT_STATUS_OK;
 	struct fc_bsg_job *bsg_job = NULL;
+	struct fc_bsg_request *bsg_request;
+	struct fc_bsg_reply *bsg_reply;
 	sts_entry_t *sts;
 	struct sts_entry_24xx *sts24;
 	sts = (sts_entry_t *) pkt;
@@ -1919,11 +1925,7 @@  qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 	}
 
 	sp = req->outstanding_cmds[index];
-	if (sp) {
-		/* Free outstanding command slot. */
-		req->outstanding_cmds[index] = NULL;
-		bsg_job = sp->u.bsg_job;
-	} else {
+	if (!sp) {
 		ql_log(ql_log_warn, vha, 0x70b0,
 		    "Req:%d: Invalid ISP SCSI completion handle(0x%x)\n",
 		    req->id, index);
@@ -1932,6 +1934,12 @@  qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 		return;
 	}
 
+	/* Free outstanding command slot. */
+	req->outstanding_cmds[index] = NULL;
+	bsg_job = sp->u.bsg_job;
+	bsg_request = bsg_job->request;
+	bsg_reply = bsg_job->reply;
+
 	if (IS_FWI2_CAPABLE(ha)) {
 		comp_status = le16_to_cpu(sts24->comp_status);
 		scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
@@ -1940,14 +1948,14 @@  qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 		scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
 	}
 
-	thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+	thread_id = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 	switch (comp_status) {
 	case CS_COMPLETE:
 		if (scsi_status == 0) {
-			bsg_job->reply->reply_payload_rcv_len =
+			bsg_reply->reply_payload_rcv_len =
 					bsg_job->reply_payload.payload_len;
 			vha->qla_stats.input_bytes +=
-				bsg_job->reply->reply_payload_rcv_len;
+				bsg_reply->reply_payload_rcv_len;
 			vha->qla_stats.input_requests++;
 			rval = EXT_STATUS_OK;
 		}
@@ -2028,11 +2036,11 @@  qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
 		rval = EXT_STATUS_ERR;
 		break;
 	}
-	bsg_job->reply->reply_payload_rcv_len = 0;
+	bsg_reply->reply_payload_rcv_len = 0;
 
 done:
 	/* Return the vendor specific reply to API */
-	bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
+	bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
 	/* Always return DID_OK, bsg will send the vendor specific response
 	 * in this case only */
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 15dff70..b597d04 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -2207,6 +2207,7 @@  qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	const char func[] = "IOSB_IOCB";
 	srb_t *sp;
 	struct fc_bsg_job *bsg_job;
+	struct fc_bsg_reply *bsg_reply;
 	struct srb_iocb *iocb_job;
 	int res;
 	struct qla_mt_iocb_rsp_fx00 fstatus;
@@ -2226,6 +2227,7 @@  qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
 			    pkt->dataword_r;
 	} else {
 		bsg_job = sp->u.bsg_job;
+		bsg_reply = bsg_job->reply;
 
 		memset(&fstatus, 0, sizeof(struct qla_mt_iocb_rsp_fx00));
 
@@ -2257,8 +2259,8 @@  qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
 		    sp->fcport->vha, 0x5074,
 		    (uint8_t *)fw_sts_ptr, sizeof(struct qla_mt_iocb_rsp_fx00));
 
-		res = bsg_job->reply->result = DID_OK << 16;
-		bsg_job->reply->reply_payload_rcv_len =
+		res = bsg_reply->result = DID_OK << 16;
+		bsg_reply->reply_payload_rcv_len =
 		    bsg_job->reply_payload.payload_len;
 	}
 	sp->done(vha, sp, res);
@@ -3253,6 +3255,7 @@  qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
 	struct srb_iocb *fxio = &sp->u.iocb_cmd;
 	struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
 	struct fc_bsg_job *bsg_job;
+	struct fc_bsg_request *bsg_request;
 	struct fxdisc_entry_fx00 fx_iocb;
 	uint8_t entry_cnt = 1;
 
@@ -3301,8 +3304,9 @@  qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
 	} else {
 		struct scatterlist *sg;
 		bsg_job = sp->u.bsg_job;
+		bsg_request = bsg_job->request;
 		piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
-			&bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
+			&bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
 		fx_iocb.func_num = piocb_rqst->func_type;
 		fx_iocb.adapid = piocb_rqst->adapid;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 8ff2067..eafc7555 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3588,9 +3588,10 @@  fc_bsg_jobdone(struct fc_bsg_job *job)
 {
 	struct request *req = job->req;
 	struct request *rsp = req->next_rq;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	int err;
 
-	err = job->req->errors = job->reply->result;
+	err = job->req->errors = bsg_reply->result;
 
 	if (err < 0)
 		/* we're only returning the result field in the reply */
@@ -3602,10 +3603,10 @@  fc_bsg_jobdone(struct fc_bsg_job *job)
 	req->resid_len = 0;
 
 	if (rsp) {
-		WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
+		WARN_ON(bsg_reply->reply_payload_rcv_len > rsp->resid_len);
 
 		/* set reply (bidi) residual */
-		rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
+		rsp->resid_len -= min(bsg_reply->reply_payload_rcv_len,
 				      rsp->resid_len);
 	}
 	blk_complete_request(req);
@@ -3701,6 +3702,8 @@  fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
 	struct fc_internal *i = to_fc_internal(shost->transportt);
 	struct request *rsp = req->next_rq;
 	struct fc_bsg_job *job;
+	struct fc_bsg_request *bsg_request;
+	struct fc_bsg_reply *bsg_reply;
 	int ret;
 
 	BUG_ON(req->special);
@@ -3726,9 +3729,9 @@  fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
 	if (i->f->dd_bsg_size)
 		job->dd_data = (void *)&job[1];
 	spin_lock_init(&job->job_lock);
-	job->request = (struct fc_bsg_request *)req->cmd;
+	bsg_request = (struct fc_bsg_request *)req->cmd;
 	job->request_len = req->cmd_len;
-	job->reply = req->sense;
+	bsg_reply = req->sense;
 	job->reply_len = SCSI_SENSE_BUFFERSIZE;	/* Size of sense buffer
 						 * allocated */
 	if (req->bio) {
@@ -3779,11 +3782,13 @@  fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
 			 struct fc_bsg_job *job)
 {
 	struct fc_internal *i = to_fc_internal(shost->transportt);
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	int cmdlen = sizeof(uint32_t);	/* start with length of msgcode */
 	int ret;
 
 	/* Validate the host command */
-	switch (job->request->msgcode) {
+	switch (bsg_request->msgcode) {
 	case FC_BSG_HST_ADD_RPORT:
 		cmdlen += sizeof(struct fc_bsg_host_add_rport);
 		break;
@@ -3815,7 +3820,7 @@  fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
 	case FC_BSG_HST_VENDOR:
 		cmdlen += sizeof(struct fc_bsg_host_vendor);
 		if ((shost->hostt->vendor_id == 0L) ||
-		    (job->request->rqst_data.h_vendor.vendor_id !=
+		    (bsg_request->rqst_data.h_vendor.vendor_id !=
 			shost->hostt->vendor_id)) {
 			ret = -ESRCH;
 			goto fail_host_msg;
@@ -3840,8 +3845,8 @@  fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
 fail_host_msg:
 	/* return the errno failure code as the only status */
 	BUG_ON(job->reply_len < sizeof(uint32_t));
-	job->reply->reply_payload_rcv_len = 0;
-	job->reply->result = ret;
+	bsg_reply->reply_payload_rcv_len = 0;
+	bsg_reply->result = ret;
 	job->reply_len = sizeof(uint32_t);
 	fc_bsg_jobdone(job);
 	return FC_DISPATCH_UNLOCKED;
@@ -3878,11 +3883,13 @@  fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
 			 struct fc_rport *rport, struct fc_bsg_job *job)
 {
 	struct fc_internal *i = to_fc_internal(shost->transportt);
+	struct fc_bsg_request *bsg_request = job->request;
+	struct fc_bsg_reply *bsg_reply = job->reply;
 	int cmdlen = sizeof(uint32_t);	/* start with length of msgcode */
 	int ret;
 
 	/* Validate the rport command */
-	switch (job->request->msgcode) {
+	switch (bsg_request->msgcode) {
 	case FC_BSG_RPT_ELS:
 		cmdlen += sizeof(struct fc_bsg_rport_els);
 		goto check_bidi;
@@ -3915,8 +3922,8 @@  check_bidi:
 fail_rport_msg:
 	/* return the errno failure code as the only status */
 	BUG_ON(job->reply_len < sizeof(uint32_t));
-	job->reply->reply_payload_rcv_len = 0;
-	job->reply->result = ret;
+	bsg_reply->reply_payload_rcv_len = 0;
+	bsg_reply->result = ret;
 	job->reply_len = sizeof(uint32_t);
 	fc_bsg_jobdone(job);
 	return FC_DISPATCH_UNLOCKED;
@@ -3937,6 +3944,7 @@  fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
 	struct request *req;
 	struct fc_bsg_job *job;
 	enum fc_dispatch_result ret;
+	struct fc_bsg_reply *bsg_reply;
 
 	if (!get_device(dev))
 		return;
@@ -3973,8 +3981,9 @@  fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
 		/* check if we have the msgcode value at least */
 		if (job->request_len < sizeof(uint32_t)) {
 			BUG_ON(job->reply_len < sizeof(uint32_t));
-			job->reply->reply_payload_rcv_len = 0;
-			job->reply->result = -ENOMSG;
+			bsg_reply = job->reply;
+			bsg_reply->reply_payload_rcv_len = 0;
+			bsg_reply->result = -ENOMSG;
 			job->reply_len = sizeof(uint32_t);
 			fc_bsg_jobdone(job);
 			spin_lock_irq(q->queue_lock);