sg: fix EWOULDBLOCK errors with scsi-mq
Subsystems (2)
PATCH v2 2/2 sg: fix EWOULDBLOCK errors with scsi-mq
With scsi-mq enabled, userspace programs can get unexpected EWOULDBLOCK (a.k.a. EAGAIN) errors when submitting commands to the SCSI generic driver. Fix by calling blk_get_request() with GFP_KERNEL instead of GFP_ATOMIC.
Note: to avoid introducing a potential deadlock, this patch should be applied after the patch titled "sg: fix unkillable I/O wait deadlock with scsi-mq".
---
For inclusion in kernel 3.20.
The difference in behavior is due to bt_get() in block/blk-mq-tag.c checking for __GFP_WAIT.
The bsg driver already calls blk_get_request() with GFP_KERNEL, so there is no need for a change there.
drivers/scsi/sg.c renamed from drivers/scsi/sg.c.orig +16 -1
@@ -1695,7 +1695,22 @@ sg_start_req(Sg_request *srp, unsigned creturn -ENOMEM ; } +/* +* NOTE +* +* With scsi-mq enabled, there are a fixed number of preallocated +* requests equal in number to shost->can_queue. If all of the +* preallocated requests are already in use, then using GFP_ATOMIC with +* blk_get_request() will return -EWOULDBLOCK, whereas using GFP_KERNEL +* will cause blk_get_request() to sleep until an active command +* completes, freeing up a request. Neither option is ideal, but +* GFP_KERNEL is the better choice to prevent userspace from getting an +* unexpected EWOULDBLOCK. +* +* With scsi-mq disabled, blk_get_request() with GFP_KERNEL usually +* does not sleep except under memory pressure. +*/ + rq =blk_get_request (q, rw,GFP_KERNEL ); - rq =blk_get_request (q, rw,GFP_ATOMIC );if (IS_ERR (rq)) {kfree (long_cmdp);return PTR_ERR (rq);
Quoted 5 lines · Tony Battersby
With scsi-mq enabled, userspace programs can get unexpected EWOULDBLOCK (a.k.a. EAGAIN) errors when submitting commands to the SCSI generic driver. Fix by calling
blk_get_request()withGFP_KERNELinstead ofGFP_ATOMIC.
Quoted 7 lines
Note: to avoid introducing a potential deadlock, this patch should be applied after the patch titled "sg: fix unkillable I/O wait deadlock with scsi-mq".
Cc Douglas Gilbert <[email protected]>Cc <[email protected]> # 3.17+Signed-off-by Tony Battersby <[email protected]>
Quoted 36 lines
For inclusion in kernel 3.20.
The difference in behavior is due to
bt_get()inblock/blk-mq-tag.cchecking for__GFP_WAIT.The bsg driver already calls
blk_get_request()withGFP_KERNEL, so there is no need for a change there.drivers/scsi/sg.c renamed from drivers/scsi/sg.c.orig +16
-2@@ -1695,7 +1695,22 @@ sg_start_req(Sg_request *srp, unsigned creturn -ENOMEM ; } +/* +* NOTE +* +* With scsi-mq enabled, there are a fixed number of preallocated +* requests equal in number to shost->can_queue. If all of the +* preallocated requests are already in use, then using GFP_ATOMIC with +* blk_get_request() will return -EWOULDBLOCK, whereas using GFP_KERNEL +* will cause blk_get_request() to sleep until an active command +* completes, freeing up a request. Neither option is ideal, but +* GFP_KERNEL is the better choice to prevent userspace from getting an +* unexpected EWOULDBLOCK. +* +* With scsi-mq disabled, blk_get_request() with GFP_KERNEL usually +* does not sleep except under memory pressure. +*/ + rq =blk_get_request (q, rw,GFP_KERNEL ); - rq =blk_get_request (q, rw,GFP_ATOMIC );if (IS_ERR (rq)) {kfree (long_cmdp);return PTR_ERR (rq); --