Re: blk-mq: introduce BLK_STS_DEV_RESOURCE

2018-01-20 Thread Mike Snitzer
On Sat, Jan 20 2018 at  7:57pm -0500,
Ming Lei  wrote:

> On Sat, Jan 20, 2018 at 12:30:02PM -0500, Mike Snitzer wrote:
> > On Sat, Jan 20 2018 at  8:48am -0500,
> > Ming Lei  wrote:
> > 
> > > This status is returned from driver to block layer if device related
> > > resource is run out of, but driver can guarantee that IO dispatch is
> > > triggered in future when the resource is available.
> > > 
> > > This patch converts some drivers to use this return value. Meantime
> > > if driver returns BLK_STS_RESOURCE and S_SCHED_RESTART is marked, run
> > > queue after 10ms for avoiding IO hang.
> > > 
> > > Suggested-by: Jens Axboe 
> > > Cc: Mike Snitzer 
> > > Cc: Laurence Oberman 
> > > Cc: Bart Van Assche 
> > > Signed-off-by: Ming Lei 
> > > ---
> > >  block/blk-core.c |  1 +
> > >  block/blk-mq.c   | 20 
> > >  drivers/block/null_blk.c |  2 +-
> > >  drivers/block/virtio_blk.c   |  2 +-
> > >  drivers/block/xen-blkfront.c |  2 +-
> > >  drivers/scsi/scsi_lib.c  |  6 +++---
> > >  include/linux/blk_types.h|  7 +++
> > >  7 files changed, 30 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/block/blk-mq.c b/block/blk-mq.c
> > > index 01f271d40825..6e97e0bf8178 100644
> > > --- a/block/blk-mq.c
> > > +++ b/block/blk-mq.c
> > > @@ -1226,7 +1226,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue 
> > > *q, struct list_head *list,
> > >   }
> > >  
> > >   ret = q->mq_ops->queue_rq(hctx, );
> > > - if (ret == BLK_STS_RESOURCE) {
> > > + if ((ret == BLK_STS_RESOURCE) ||
> > > + (ret == BLK_STS_DEV_RESOURCE)) {
> > >   /*
> > >* If an I/O scheduler has been configured and we got a
> > >* driver tag for the next request already, free it
> > 
> > Just a nit, but this should be on one line.
> 
> It is too long, and my editor starts to highlight/complain it, :-)

Look at the lines immediately following it, your isn't longer than
them..

> > > @@ -1764,6 +1775,7 @@ static blk_status_t __blk_mq_issue_directly(struct 
> > > blk_mq_hw_ctx *hctx,
> > >   *cookie = new_cookie;
> > >   break;
> > >   case BLK_STS_RESOURCE:
> > > + case BLK_STS_DEV_RESOURCE:
> > >   __blk_mq_requeue_request(rq);
> > >   break;
> > >   default:
> > 
> > It seems the strategy for BLK_STS_DEV_RESOURCE and BLK_STS_RESOURCE is
> > too muddled: calling __blk_mq_requeue_request() for both will cause
> > underlying blk-mq driver to retain the request, won't it?
> 
> blk_mq_request_issue_directly() is used by driver(dm-rq) on underlying
> queue, and driver need to deal with underlying queue busy, now we simply
> free the (underlying)request and feedback the busy status to blk-mq via
> dm-rq.
> 
> Except for blk_mq_request_issue_directly(), this request need to be
> requeued, and is retained by blk-mq in hctx->dispatch_list.
> 
> The difference is that if driver returns BLK_STS_DEV_RESOURCE, the queue
> will be rerun when resource is available, so don't need to run queue after
> a delay for avoiding IO hang explicitly.

Yes, I understand the intent.

> > > @@ -1826,7 +1838,7 @@ static void blk_mq_try_issue_directly(struct 
> > > blk_mq_hw_ctx *hctx,
> > >   hctx_lock(hctx, _idx);
> > >  
> > >   ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false);
> > > - if (ret == BLK_STS_RESOURCE)
> > > + if ((ret == BLK_STS_RESOURCE) || (ret == BLK_STS_DEV_RESOURCE))
> > >   blk_mq_sched_insert_request(rq, false, true, false);
> > >   else if (ret != BLK_STS_OK)
> > >   blk_mq_end_request(rq, ret);
> > 
> > For this normal (non dm-mpath) case the request gets re-inserted;
> > dm-mpath must avoid that.
> > 
> > But with dm-mpath, which instead uses blk_mq_request_issue_directly(),
> > we're driving IO with stacked blk-mq drivers.  If the underlying blk-mq 
> > driver (e.g. scsi-mq or nvme) is made to retain the request, using
> > __blk_mq_issue_directly()'s call to __blk_mq_requeue_request() above,
> > then dm-mpath will not have the ability to requeue the request without
> > conflicting with the underlying blk-mq driver, will it?
> 
> No, as I explained, the exception is blk_mq_request_issue_directly(),
> and now dm-rq simply frees it(and in my original version, this request
> is cached for underlying queue, and reused in next dispatch), for others,
> the request is retained in hctx->dispatch_list, and owned by blk-mq.
>
> > Or am I'm misunderstanding what __blk_mq_requeue_request() is doing?

OK I was misunderstanding __blk_mq_requeue_request().  Seems
__blk_mq_requeue_request() is effectively resetting a request for
reuse.  Not retaining the request for reissue.

> > dm_mq_queue_rq
> > -> multipath_clone_and_map
> >-> blk_get_request (scsi_mq)
> >   -> if error, dm-mpath 

Re: blk-mq: introduce BLK_STS_DEV_RESOURCE

2018-01-20 Thread Ming Lei
On Sun, Jan 21, 2018 at 08:57:41AM +0800, Ming Lei wrote:
> On Sat, Jan 20, 2018 at 12:30:02PM -0500, Mike Snitzer wrote:
> > On Sat, Jan 20 2018 at  8:48am -0500,
> > Ming Lei  wrote:
> > 
> > > This status is returned from driver to block layer if device related
> > > resource is run out of, but driver can guarantee that IO dispatch is
> > > triggered in future when the resource is available.
> > > 
> > > This patch converts some drivers to use this return value. Meantime
> > > if driver returns BLK_STS_RESOURCE and S_SCHED_RESTART is marked, run
> > > queue after 10ms for avoiding IO hang.
> > > 
> > > Suggested-by: Jens Axboe 
> > > Cc: Mike Snitzer 
> > > Cc: Laurence Oberman 
> > > Cc: Bart Van Assche 
> > > Signed-off-by: Ming Lei 
> > > ---
> > >  block/blk-core.c |  1 +
> > >  block/blk-mq.c   | 20 
> > >  drivers/block/null_blk.c |  2 +-
> > >  drivers/block/virtio_blk.c   |  2 +-
> > >  drivers/block/xen-blkfront.c |  2 +-
> > >  drivers/scsi/scsi_lib.c  |  6 +++---
> > >  include/linux/blk_types.h|  7 +++
> > >  7 files changed, 30 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/block/blk-mq.c b/block/blk-mq.c
> > > index 01f271d40825..6e97e0bf8178 100644
> > > --- a/block/blk-mq.c
> > > +++ b/block/blk-mq.c
> > > @@ -1226,7 +1226,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue 
> > > *q, struct list_head *list,
> > >   }
> > >  
> > >   ret = q->mq_ops->queue_rq(hctx, );
> > > - if (ret == BLK_STS_RESOURCE) {
> > > + if ((ret == BLK_STS_RESOURCE) ||
> > > + (ret == BLK_STS_DEV_RESOURCE)) {
> > >   /*
> > >* If an I/O scheduler has been configured and we got a
> > >* driver tag for the next request already, free it
> > 
> > Just a nit, but this should be on one line.
> 
> It is too long, and my editor starts to highlight/complain it, :-)
> 
> > 
> > > @@ -1764,6 +1775,7 @@ static blk_status_t __blk_mq_issue_directly(struct 
> > > blk_mq_hw_ctx *hctx,
> > >   *cookie = new_cookie;
> > >   break;
> > >   case BLK_STS_RESOURCE:
> > > + case BLK_STS_DEV_RESOURCE:
> > >   __blk_mq_requeue_request(rq);
> > >   break;
> > >   default:
> > 
> > It seems the strategy for BLK_STS_DEV_RESOURCE and BLK_STS_RESOURCE is
> > too muddled: calling __blk_mq_requeue_request() for both will cause
> > underlying blk-mq driver to retain the request, won't it?
> 
> blk_mq_request_issue_directly() is used by driver(dm-rq) on underlying
> queue, and driver need to deal with underlying queue busy, now we simply
> free the (underlying)request and feedback the busy status to blk-mq via
> dm-rq.
> 
> Except for blk_mq_request_issue_directly(), this request need to be
> requeued, and is retained by blk-mq in hctx->dispatch_list.
> 
> The difference is that if driver returns BLK_STS_DEV_RESOURCE, the queue
> will be rerun when resource is available, so don't need to run queue after
> a delay for avoiding IO hang explicitly.
> 
> > 
> > > @@ -1826,7 +1838,7 @@ static void blk_mq_try_issue_directly(struct 
> > > blk_mq_hw_ctx *hctx,
> > >   hctx_lock(hctx, _idx);
> > >  
> > >   ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false);
> > > - if (ret == BLK_STS_RESOURCE)
> > > + if ((ret == BLK_STS_RESOURCE) || (ret == BLK_STS_DEV_RESOURCE))
> > >   blk_mq_sched_insert_request(rq, false, true, false);
> > >   else if (ret != BLK_STS_OK)
> > >   blk_mq_end_request(rq, ret);
> > 
> > For this normal (non dm-mpath) case the request gets re-inserted;
> > dm-mpath must avoid that.
> > 
> > But with dm-mpath, which instead uses blk_mq_request_issue_directly(),
> > we're driving IO with stacked blk-mq drivers.  If the underlying blk-mq 
> > driver (e.g. scsi-mq or nvme) is made to retain the request, using
> > __blk_mq_issue_directly()'s call to __blk_mq_requeue_request() above,
> > then dm-mpath will not have the ability to requeue the request without
> > conflicting with the underlying blk-mq driver, will it?
> 
> No, as I explained, the exception is blk_mq_request_issue_directly(),
> and now dm-rq simply frees it(and in my original version, this request
> is cached for underlying queue, and reused in next dispatch), for others,
> the request is retained in hctx->dispatch_list, and owned by blk-mq.
> 
> > 
> > Or am I'm misunderstanding what __blk_mq_requeue_request() is doing?
> > 
> > dm_mq_queue_rq
> > -> multipath_clone_and_map
> >-> blk_get_request (scsi_mq)
> >   -> if error, dm-mpath conditionally requeues (w/ or w/o delay)
> 
> Yes, with this patch, most of times blk-mq will run queue w/ delay
> because SCHED_RESTART is set after the 1st STS_RESOURCE from dm-rq
> .queue_rq()
> 
> >   -> if BLK_STS_OK then blk_mq_request_issue_directly() gets called
> 

Re: blk-mq: introduce BLK_STS_DEV_RESOURCE

2018-01-20 Thread Ming Lei
On Sat, Jan 20, 2018 at 12:30:02PM -0500, Mike Snitzer wrote:
> On Sat, Jan 20 2018 at  8:48am -0500,
> Ming Lei  wrote:
> 
> > This status is returned from driver to block layer if device related
> > resource is run out of, but driver can guarantee that IO dispatch is
> > triggered in future when the resource is available.
> > 
> > This patch converts some drivers to use this return value. Meantime
> > if driver returns BLK_STS_RESOURCE and S_SCHED_RESTART is marked, run
> > queue after 10ms for avoiding IO hang.
> > 
> > Suggested-by: Jens Axboe 
> > Cc: Mike Snitzer 
> > Cc: Laurence Oberman 
> > Cc: Bart Van Assche 
> > Signed-off-by: Ming Lei 
> > ---
> >  block/blk-core.c |  1 +
> >  block/blk-mq.c   | 20 
> >  drivers/block/null_blk.c |  2 +-
> >  drivers/block/virtio_blk.c   |  2 +-
> >  drivers/block/xen-blkfront.c |  2 +-
> >  drivers/scsi/scsi_lib.c  |  6 +++---
> >  include/linux/blk_types.h|  7 +++
> >  7 files changed, 30 insertions(+), 10 deletions(-)
> > 
> > diff --git a/block/blk-mq.c b/block/blk-mq.c
> > index 01f271d40825..6e97e0bf8178 100644
> > --- a/block/blk-mq.c
> > +++ b/block/blk-mq.c
> > @@ -1226,7 +1226,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
> > struct list_head *list,
> > }
> >  
> > ret = q->mq_ops->queue_rq(hctx, );
> > -   if (ret == BLK_STS_RESOURCE) {
> > +   if ((ret == BLK_STS_RESOURCE) ||
> > +   (ret == BLK_STS_DEV_RESOURCE)) {
> > /*
> >  * If an I/O scheduler has been configured and we got a
> >  * driver tag for the next request already, free it
> 
> Just a nit, but this should be on one line.

It is too long, and my editor starts to highlight/complain it, :-)

> 
> > @@ -1764,6 +1775,7 @@ static blk_status_t __blk_mq_issue_directly(struct 
> > blk_mq_hw_ctx *hctx,
> > *cookie = new_cookie;
> > break;
> > case BLK_STS_RESOURCE:
> > +   case BLK_STS_DEV_RESOURCE:
> > __blk_mq_requeue_request(rq);
> > break;
> > default:
> 
> It seems the strategy for BLK_STS_DEV_RESOURCE and BLK_STS_RESOURCE is
> too muddled: calling __blk_mq_requeue_request() for both will cause
> underlying blk-mq driver to retain the request, won't it?

blk_mq_request_issue_directly() is used by driver(dm-rq) on underlying
queue, and driver need to deal with underlying queue busy, now we simply
free the (underlying)request and feedback the busy status to blk-mq via
dm-rq.

Except for blk_mq_request_issue_directly(), this request need to be
requeued, and is retained by blk-mq in hctx->dispatch_list.

The difference is that if driver returns BLK_STS_DEV_RESOURCE, the queue
will be rerun when resource is available, so don't need to run queue after
a delay for avoiding IO hang explicitly.

> 
> > @@ -1826,7 +1838,7 @@ static void blk_mq_try_issue_directly(struct 
> > blk_mq_hw_ctx *hctx,
> > hctx_lock(hctx, _idx);
> >  
> > ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false);
> > -   if (ret == BLK_STS_RESOURCE)
> > +   if ((ret == BLK_STS_RESOURCE) || (ret == BLK_STS_DEV_RESOURCE))
> > blk_mq_sched_insert_request(rq, false, true, false);
> > else if (ret != BLK_STS_OK)
> > blk_mq_end_request(rq, ret);
> 
> For this normal (non dm-mpath) case the request gets re-inserted;
> dm-mpath must avoid that.
> 
> But with dm-mpath, which instead uses blk_mq_request_issue_directly(),
> we're driving IO with stacked blk-mq drivers.  If the underlying blk-mq 
> driver (e.g. scsi-mq or nvme) is made to retain the request, using
> __blk_mq_issue_directly()'s call to __blk_mq_requeue_request() above,
> then dm-mpath will not have the ability to requeue the request without
> conflicting with the underlying blk-mq driver, will it?

No, as I explained, the exception is blk_mq_request_issue_directly(),
and now dm-rq simply frees it(and in my original version, this request
is cached for underlying queue, and reused in next dispatch), for others,
the request is retained in hctx->dispatch_list, and owned by blk-mq.

> 
> Or am I'm misunderstanding what __blk_mq_requeue_request() is doing?
> 
> dm_mq_queue_rq
> -> multipath_clone_and_map
>-> blk_get_request (scsi_mq)
>   -> if error, dm-mpath conditionally requeues (w/ or w/o delay)

Yes, with this patch, most of times blk-mq will run queue w/ delay
because SCHED_RESTART is set after the 1st STS_RESOURCE from dm-rq
.queue_rq()

>   -> if BLK_STS_OK then blk_mq_request_issue_directly() gets called
> -> dm_dispatch_clone_request
>-> blk_mq_request_issue_directly
>   -> __blk_mq_try_issue_directly
>  -> __blk_mq_issue_directly
> -> q->mq_ops->queue_rq (this is the underlying scsi_mq)
>-> a 

Re: [PATCH 6/6] mpt3sas: Introduce function to clone mpi reply.

2018-01-20 Thread kbuild test robot
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.15-rc8 next-20180119]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Add-PCI-device-ID-for-Andromeda/20180121-002454
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   drivers/scsi/mpt3sas/mpt3sas_base.c:148:35: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:16: sparse: cast from restricted 
__le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:16: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:16: got restricted __le32 
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:36: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:36: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:151:36: got void
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:24: sparse: cast from restricted 
__le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:24: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:24: got restricted __le32 
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:169:64: got void COPYING CREDITS 
Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs 
crypto drivers firmware fs include init ipc kernel lib mm net samples scripts 
security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:24: sparse: cast from restricted 
__le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:24: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:24: got restricted __le32 
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:186:64: got void COPYING CREDITS 
Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs 
crypto drivers firmware fs include init ipc kernel lib mm net samples scripts 
security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:206:24: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:359:24: sparse: undefined identifier 
'mpt3sas_scsih_scsi_lookup_get'
   drivers/scsi/mpt3sas/mpt3sas_base.c:1208:42: sparse: incorrect type in 
assignment (different base types) @@ expected unsigned short Event @@ got short 
Event @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1209:49: sparse: incorrect type in 
assignment (different base types) @@ expected unsigned int EventContext @@ got 
ed int EventContext @@
>> drivers/scsi/mpt3sas/mpt3sas_base.c:1404:75: sparse: incorrect type in 
>> argument 2 (different base types) @@ expected restricted __le32 reply @@ got 
>> unsigned int [unsrestricted __le32 reply @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1430:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1479:52: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3011:32: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:3359:26: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:3303:26: sparse: incorrect type in 
initializer (different base types) @@ expected unsigned long long data_out @@ 
got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3326:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3326:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3443:34: sparse: cast 

Re: [PATCH 5/6] mpt3sas: Introduce function to clone mpi request.

2018-01-20 Thread kbuild test robot
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.15-rc8 next-20180119]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Add-PCI-device-ID-for-Andromeda/20180121-002454
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: sparse: cast from restricted 
__le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:24: got restricted __le32 
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:143:64: got void COPYING CREDITS 
Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs 
crypto drivers firmware fs include init ipc kernel lib mm net samples scripts 
security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: sparse: cast from restricted 
__le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:24: got restricted __le32 
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:160:64: got void COPYING CREDITS 
Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs 
crypto drivers firmware fs include init ipc kernel lib mm net samples scripts 
security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:180:24: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:333:24: sparse: undefined identifier 
'mpt3sas_scsih_scsi_lookup_get'
   drivers/scsi/mpt3sas/mpt3sas_base.c:1182:42: sparse: incorrect type in 
assignment (different base types) @@ expected unsigned short Event @@ got short 
Event @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1183:49: sparse: incorrect type in 
assignment (different base types) @@ expected unsigned int EventContext @@ got 
ed int EventContext @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1401:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1450:52: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:2982:32: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:3330:26: sparse: cast removes address 
space of expression
>> drivers/scsi/mpt3sas/mpt3sas_base.c:3274:26: sparse: incorrect type in 
>> initializer (different base types) @@ expected unsigned long long data_out 
>> @@ got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3414:34: sparse: cast removes address 
space of expression
>> drivers/scsi/mpt3sas/mpt3sas_base.c:3274:26: sparse: incorrect type in 
>> initializer (different base types) @@ expected unsigned long long data_out 
>> @@ got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3483:34: sparse: cast removes address 
space of expression
>> drivers/scsi/mpt3sas/mpt3sas_base.c:3274:26: sparse: incorrect type in 
>> initializer (different base types) @@ expected unsigned long long data_out 
>> @@ got g long data_out @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3297:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected 

Re: [PATCH 4/6] mpt3sas: Introduce Base function for cloning.

2018-01-20 Thread kbuild test robot
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.15-rc8 next-20180119]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Add-PCI-device-ID-for-Andromeda/20180121-002454
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/scsi/mpt3sas/mpt3sas_base.c:142:24: sparse: cast from restricted 
>> __le32
   drivers/scsi/mpt3sas/mpt3sas_base.c:142:24: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:142:24: expected unsigned int val
   drivers/scsi/mpt3sas/mpt3sas_base.c:142:24: got restricted __le32 
>> drivers/scsi/mpt3sas/mpt3sas_base.c:142:64: sparse: incorrect type in 
>> argument 2 (different address spaces) @@ expected void volatile @@ got @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:142:64: expected void volatile
   drivers/scsi/mpt3sas/mpt3sas_base.c:142:64: got void COPYING CREDITS 
Documentation Kbuild Kconfig MAINTAINERS Makefile README arch block certs 
crypto drivers firmware fs include init ipc kernel lib mm net samples scripts 
security sound tools usr virt
   drivers/scsi/mpt3sas/mpt3sas_base.c:162:24: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:315:24: sparse: undefined identifier 
'mpt3sas_scsih_scsi_lookup_get'
   drivers/scsi/mpt3sas/mpt3sas_base.c:1164:42: sparse: incorrect type in 
assignment (different base types) @@ expected unsigned short Event @@ got short 
Event @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1165:49: sparse: incorrect type in 
assignment (different base types) @@ expected unsigned int EventContext @@ got 
ed int EventContext @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1383:64: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:1432:52: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:2964:32: sparse: cast removes address 
space of expression
   drivers/scsi/mpt3sas/mpt3sas_base.c:3256:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3256:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3256:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3256:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3256:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned long val @@ got 
restunsigned long val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3411:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3433:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3456:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3477:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:3498:16: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:4950:24: sparse: incorrect type in 
argument 1 (different base types) @@ expected unsigned int val @@ got 
restrunsigned int val @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:4971:20: sparse: cast to restricted 
__le16
   drivers/scsi/mpt3sas/mpt3sas_base.c:4980:20: sparse: cast to restricted 
__le16
   drivers/scsi/mpt3sas/mpt3sas_base.c:4994:36: sparse: cast to restricted 
__le16
   drivers/scsi/mpt3sas/mpt3sas_base.c:6175:55: sparse: incorrect type in 
argument 2 (different address spaces) @@ expected void volatile @@ got oid 
volatile @@
   drivers/scsi/mpt3sas/mpt3sas_base.c:315:53: sparse: call with no type!
   drivers/scsi/mpt3sas/mpt3sas_base.c: In function '_clone_sg_entries':
   drivers/scsi/mpt3sas/mpt3sas_base.c:315:10: error: implicit 

Re: [PATCH 4/6] mpt3sas: Introduce Base function for cloning.

2018-01-20 Thread kbuild test robot
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.15-rc8 next-20180119]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Add-PCI-device-ID-for-Andromeda/20180121-002454
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: i386-randconfig-i1-201802 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/scsi/mpt3sas/mpt3sas_base.c: In function '_base_get_chain_phys':
   drivers/scsi/mpt3sas/mpt3sas_base.c:188:21: warning: cast to pointer from 
integer of different size [-Wint-to-pointer-cast]
 base_chain_phys  = (void *)ioc->chip_phys + MPI_FRAME_START_OFFSET +
^
   drivers/scsi/mpt3sas/mpt3sas_base.c: In function '_clone_sg_entries':
   drivers/scsi/mpt3sas/mpt3sas_base.c:315:10: error: implicit declaration of 
function 'mpt3sas_scsih_scsi_lookup_get'; did you mean 
'mpt3sas_scsih_issue_locked_tm'? [-Werror=implicit-function-declaration]
  scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
 ^
 mpt3sas_scsih_issue_locked_tm
   drivers/scsi/mpt3sas/mpt3sas_base.c:315:8: warning: assignment makes pointer 
from integer without a cast [-Wint-conversion]
  scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
   ^
>> drivers/scsi/mpt3sas/mpt3sas_base.c:378:20: warning: cast from pointer to 
>> integer of different size [-Wpointer-to-int-cast]
   sgel->Address = (dma_addr_t)dst_addr_phys;
   ^
   drivers/scsi/mpt3sas/mpt3sas_base.c:389:7: warning: cast from pointer to 
integer of different size [-Wpointer-to-int-cast]
  (dma_addr_t)buff_ptr_phys;
  ^
   drivers/scsi/mpt3sas/mpt3sas_base.c:395:10: warning: cast from pointer to 
integer of different size [-Wpointer-to-int-cast]
 (dma_addr_t)buff_ptr_phys;
 ^
   At top level:
   drivers/scsi/mpt3sas/mpt3sas_base.c:278:13: warning: '_clone_sg_entries' 
defined but not used [-Wunused-function]
static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
^
   cc1: some warnings being treated as errors

vim +378 drivers/scsi/mpt3sas/mpt3sas_base.c

   265  
   266  /**
   267   * _clone_sg_entries -  MPI EP's scsiio and config requests
   268   *  are handled here. Base function for
   269   *  double buffering, before submitting
   270   *  the requests.
   271   *
   272   * @ioc: per adapter object.
   273   * @mpi_request: mf request pointer.
   274   * @smid: system request message index.
   275   *
   276   * @Returns: Nothing.
   277   */
   278  static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc,
   279  void *mpi_request, u16 smid)
   280  {
   281  Mpi2SGESimple32_t *sgel, *sgel_next;
   282  u32  sgl_flags, sge_chain_count = 0;
   283  bool is_write = 0;
   284  u16 i = 0;
   285  void  *buffer_iomem, *buffer_iomem_phys;
   286  void *buff_ptr, *buff_ptr_phys;
   287  void *dst_chain_addr[MCPU_MAX_CHAINS_PER_IO];
   288  void *src_chain_addr[MCPU_MAX_CHAINS_PER_IO], *dst_addr_phys;
   289  MPI2RequestHeader_t *request_hdr;
   290  struct scsi_cmnd *scmd;
   291  struct scatterlist *sg_scmd = NULL;
   292  int is_scsiio_req = 0;
   293  
   294  request_hdr = (MPI2RequestHeader_t *) mpi_request;
   295  
   296  if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) {
   297  Mpi25SCSIIORequest_t *scsiio_request =
   298  (Mpi25SCSIIORequest_t *)mpi_request;
   299  sgel = (Mpi2SGESimple32_t *) _request->SGL;
   300  is_scsiio_req = 1;
   301  } else if (request_hdr->Function == MPI2_FUNCTION_CONFIG) {
   302  Mpi2ConfigRequest_t  *config_req =
   303  (Mpi2ConfigRequest_t *)mpi_request;
   304  sgel = (Mpi2SGESimple32_t *) _req->PageBufferSGE;
   305  } else
   306  return;
   307  
   308  /* From smid we can get scsi_cmd, once we have sg_scmd,
   309   * we just need to get sg_virt and sg_next to get virual
   310   * address associated with sgel->Address.
   311   */
   312  
   313  if (is_scsiio_req) {
   314  /* Get scsi_cmd using smid */
 > 315  scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid);
   316  if (scmd == NULL) {
   317  pr_err(MPT3SAS_FMT "scmd is NULL\n", ioc->name);
   318   

Re: blk-mq: introduce BLK_STS_DEV_RESOURCE

2018-01-20 Thread Mike Snitzer
On Sat, Jan 20 2018 at  8:48am -0500,
Ming Lei  wrote:

> This status is returned from driver to block layer if device related
> resource is run out of, but driver can guarantee that IO dispatch is
> triggered in future when the resource is available.
> 
> This patch converts some drivers to use this return value. Meantime
> if driver returns BLK_STS_RESOURCE and S_SCHED_RESTART is marked, run
> queue after 10ms for avoiding IO hang.
> 
> Suggested-by: Jens Axboe 
> Cc: Mike Snitzer 
> Cc: Laurence Oberman 
> Cc: Bart Van Assche 
> Signed-off-by: Ming Lei 
> ---
>  block/blk-core.c |  1 +
>  block/blk-mq.c   | 20 
>  drivers/block/null_blk.c |  2 +-
>  drivers/block/virtio_blk.c   |  2 +-
>  drivers/block/xen-blkfront.c |  2 +-
>  drivers/scsi/scsi_lib.c  |  6 +++---
>  include/linux/blk_types.h|  7 +++
>  7 files changed, 30 insertions(+), 10 deletions(-)
> 
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 01f271d40825..6e97e0bf8178 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -1226,7 +1226,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
> struct list_head *list,
>   }
>  
>   ret = q->mq_ops->queue_rq(hctx, );
> - if (ret == BLK_STS_RESOURCE) {
> + if ((ret == BLK_STS_RESOURCE) ||
> + (ret == BLK_STS_DEV_RESOURCE)) {
>   /*
>* If an I/O scheduler has been configured and we got a
>* driver tag for the next request already, free it

Just a nit, but this should be on one line.

> @@ -1764,6 +1775,7 @@ static blk_status_t __blk_mq_issue_directly(struct 
> blk_mq_hw_ctx *hctx,
>   *cookie = new_cookie;
>   break;
>   case BLK_STS_RESOURCE:
> + case BLK_STS_DEV_RESOURCE:
>   __blk_mq_requeue_request(rq);
>   break;
>   default:

It seems the strategy for BLK_STS_DEV_RESOURCE and BLK_STS_RESOURCE is
too muddled: calling __blk_mq_requeue_request() for both will cause
underlying blk-mq driver to retain the request, won't it?

> @@ -1826,7 +1838,7 @@ static void blk_mq_try_issue_directly(struct 
> blk_mq_hw_ctx *hctx,
>   hctx_lock(hctx, _idx);
>  
>   ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false);
> - if (ret == BLK_STS_RESOURCE)
> + if ((ret == BLK_STS_RESOURCE) || (ret == BLK_STS_DEV_RESOURCE))
>   blk_mq_sched_insert_request(rq, false, true, false);
>   else if (ret != BLK_STS_OK)
>   blk_mq_end_request(rq, ret);

For this normal (non dm-mpath) case the request gets re-inserted;
dm-mpath must avoid that.

But with dm-mpath, which instead uses blk_mq_request_issue_directly(),
we're driving IO with stacked blk-mq drivers.  If the underlying blk-mq 
driver (e.g. scsi-mq or nvme) is made to retain the request, using
__blk_mq_issue_directly()'s call to __blk_mq_requeue_request() above,
then dm-mpath will not have the ability to requeue the request without
conflicting with the underlying blk-mq driver, will it?

Or am I'm misunderstanding what __blk_mq_requeue_request() is doing?

dm_mq_queue_rq
-> multipath_clone_and_map
   -> blk_get_request (scsi_mq)
  -> if error, dm-mpath conditionally requeues (w/ or w/o delay)
  -> if BLK_STS_OK then blk_mq_request_issue_directly() gets called
-> dm_dispatch_clone_request
   -> blk_mq_request_issue_directly
  -> __blk_mq_try_issue_directly
 -> __blk_mq_issue_directly
-> q->mq_ops->queue_rq (this is the underlying scsi_mq)
   -> a BLK_STS_RESOURCE return here is how Bart was able to cause 
stalls
-> __blk_mq_requeue_request, if BLK_STS_RESOURCE or 
BLK_STS_DEV_RESOURCE **1
   -> (return from blk_mq_request_issue_directly)
   -> if BLK_STS_RESOURCE, the dm-mpath request is released using 
blk_put_request();
   and DM_MAPIO_REQUEUE is returned to dm_mq_queue_rq 
**2
-> if DM_MAPIO_REQUEUE return from map_request()'s call to 
dm_dispatch_clone_request:
   BLK_STS_RESOURCE is returned from dm-mpath's dm_mq_queue_rq

The redundant queueing (both to underlying blk-mq at **1 above, and
upper layer blk-mq at **2 above) is what I'm concerned about.

Hope this is clear.

I'd love to be missing something, please advise.

Thanks,
Mike


Re: [PATCH 3/6] mpt3sas: Introduce API's to get BAR0 mapped buffer address.

2018-01-20 Thread kbuild test robot
Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.15-rc8 next-20180119]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Add-PCI-device-ID-for-Andromeda/20180121-002454
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: i386-randconfig-x017-201803 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/scsi/mpt3sas/mpt3sas_base.c: In function '_base_get_chain_phys':
>> drivers/scsi/mpt3sas/mpt3sas_base.c:171:21: warning: cast to pointer from 
>> integer of different size [-Wint-to-pointer-cast]
 base_chain_phys  = (void *)ioc->chip_phys + MPI_FRAME_START_OFFSET +
^
   At top level:
   drivers/scsi/mpt3sas/mpt3sas_base.c:212:1: warning: 
'_base_get_buffer_phys_bar0' defined but not used [-Wunused-function]
_base_get_buffer_phys_bar0(struct MPT3SAS_ADAPTER *ioc, u16 smid)
^~
   drivers/scsi/mpt3sas/mpt3sas_base.c:191:1: warning: '_base_get_buffer_bar0' 
defined but not used [-Wunused-function]
_base_get_buffer_bar0(struct MPT3SAS_ADAPTER *ioc, u16 smid)
^

vim +171 drivers/scsi/mpt3sas/mpt3sas_base.c

   152  
   153  /**
   154   * _base_get_chain_phys - Calculates and Returns physical address
   155   *  in BAR0 for scatter gather chains, for
   156   *  the provided smid.
   157   *
   158   * @ioc: per adapter object
   159   * @smid: system request message index
   160   * @sge_chain_count: Scatter gather chain count.
   161   *
   162   * @Return - Physical chain address.
   163   */
   164  static inline void *
   165  _base_get_chain_phys(struct MPT3SAS_ADAPTER *ioc, u16 smid,
   166  u8 sge_chain_count)
   167  {
   168  void *base_chain_phys, *chain_phys;
   169  u16 cmd_credit = ioc->facts.RequestCredit + 1;
   170  
 > 171  base_chain_phys  = (void *)ioc->chip_phys + 
 > MPI_FRAME_START_OFFSET +
   172  (cmd_credit * ioc->request_sz) +
   173  REPLY_FREE_POOL_SIZE;
   174  chain_phys = base_chain_phys + (smid * ioc->facts.MaxChainDepth 
*
   175  ioc->request_sz) + (sge_chain_count * 
ioc->request_sz);
   176  return chain_phys;
   177  }
   178  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


[PATCH] blk-mq: introduce BLK_STS_DEV_RESOURCE

2018-01-20 Thread Ming Lei
This status is returned from driver to block layer if device related
resource is run out of, but driver can guarantee that IO dispatch is
triggered in future when the resource is available.

This patch converts some drivers to use this return value. Meantime
if driver returns BLK_STS_RESOURCE and S_SCHED_RESTART is marked, run
queue after 10ms for avoiding IO hang.

Suggested-by: Jens Axboe 
Cc: Mike Snitzer 
Cc: Laurence Oberman 
Cc: Bart Van Assche 
Signed-off-by: Ming Lei 
---
 block/blk-core.c |  1 +
 block/blk-mq.c   | 20 
 drivers/block/null_blk.c |  2 +-
 drivers/block/virtio_blk.c   |  2 +-
 drivers/block/xen-blkfront.c |  2 +-
 drivers/scsi/scsi_lib.c  |  6 +++---
 include/linux/blk_types.h|  7 +++
 7 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index a2005a485335..ac4789c5e329 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -145,6 +145,7 @@ static const struct {
[BLK_STS_MEDIUM]= { -ENODATA,   "critical medium" },
[BLK_STS_PROTECTION]= { -EILSEQ,"protection" },
[BLK_STS_RESOURCE]  = { -ENOMEM,"kernel resource" },
+   [BLK_STS_DEV_RESOURCE]  = { -ENOMEM,"device resource" },
[BLK_STS_AGAIN] = { -EAGAIN,"nonblocking retry" },
 
/* device mapper special case, should not leak out: */
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 01f271d40825..6e97e0bf8178 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1169,6 +1169,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
struct list_head *list,
struct request *rq, *nxt;
bool no_tag = false;
int errors, queued;
+   blk_status_t ret = BLK_STS_OK;
 
if (list_empty(list))
return false;
@@ -1181,7 +1182,6 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
struct list_head *list,
errors = queued = 0;
do {
struct blk_mq_queue_data bd;
-   blk_status_t ret;
 
rq = list_first_entry(list, struct request, queuelist);
if (!blk_mq_get_driver_tag(rq, , false)) {
@@ -1226,7 +1226,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
struct list_head *list,
}
 
ret = q->mq_ops->queue_rq(hctx, );
-   if (ret == BLK_STS_RESOURCE) {
+   if ((ret == BLK_STS_RESOURCE) ||
+   (ret == BLK_STS_DEV_RESOURCE)) {
/*
 * If an I/O scheduler has been configured and we got a
 * driver tag for the next request already, free it
@@ -1257,6 +1258,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
struct list_head *list,
 * that is where we will continue on next queue run.
 */
if (!list_empty(list)) {
+   bool needs_restart;
+
spin_lock(>lock);
list_splice_init(list, >dispatch);
spin_unlock(>lock);
@@ -1280,10 +1283,18 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, 
struct list_head *list,
 * - Some but not all block drivers stop a queue before
 *   returning BLK_STS_RESOURCE. Two exceptions are scsi-mq
 *   and dm-rq.
+*
+* If drivers return BLK_STS_RESOURCE and S_SCHED_RESTART
+* bit is set, run queue after 10ms for avoiding IO hang
+* because the queue may be idle and the RESTART mechanism
+* can't work any more.
 */
-   if (!blk_mq_sched_needs_restart(hctx) ||
+   needs_restart = blk_mq_sched_needs_restart(hctx);
+   if (!needs_restart ||
(no_tag && list_empty_careful(>dispatch_wait.entry)))
blk_mq_run_hw_queue(hctx, true);
+   else if (needs_restart && (ret == BLK_STS_RESOURCE))
+   blk_mq_delay_run_hw_queue(hctx, 10);
}
 
return (queued + errors) != 0;
@@ -1764,6 +1775,7 @@ static blk_status_t __blk_mq_issue_directly(struct 
blk_mq_hw_ctx *hctx,
*cookie = new_cookie;
break;
case BLK_STS_RESOURCE:
+   case BLK_STS_DEV_RESOURCE:
__blk_mq_requeue_request(rq);
break;
default:
@@ -1826,7 +1838,7 @@ static void blk_mq_try_issue_directly(struct 
blk_mq_hw_ctx *hctx,
hctx_lock(hctx, _idx);
 
ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false);
-   if (ret == BLK_STS_RESOURCE)
+   if ((ret == BLK_STS_RESOURCE) || (ret == BLK_STS_DEV_RESOURCE))
blk_mq_sched_insert_request(rq, false, true, false);
else if (ret != BLK_STS_OK)
blk_mq_end_request(rq, ret);
diff