]> git.ipfire.org Git - people/ms/linux.git/commit
sg: fix unkillable I/O wait deadlock with scsi-mq
authorTony Battersby <tonyb@cybernetics.com>
Fri, 13 Feb 2015 17:09:44 +0000 (12:09 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 6 Mar 2015 22:52:59 +0000 (14:52 -0800)
commitba48f249ae10e0ecd8e5dfef215560596d92a1ab
treeff1dc34c578d3e2ddaed127ac222f57cbbfdea66
parent70bcf9f418ebefe6c862fb1d27a7bcf9d4056ffe
sg: fix unkillable I/O wait deadlock with scsi-mq

commit 7568615c1054907ea8c7701ab86dad51aa099888 upstream.

When using the write()/read() interface for submitting commands, the
SCSI generic driver does not call blk_put_request() on a completed SCSI
command until userspace calls read() to get the command completion.
Since scsi-mq uses a fixed number of preallocated requests, this makes
it possible for userspace to exhaust the entire preallocated supply of
requests.  For places in the kernel that call blk_get_request() with
GFP_KERNEL, this can cause the calling process to deadlock in a
permanent unkillable I/O wait in blk_get_request() -> ... -> bt_get().
For places in the kernel that call blk_get_request() with GFP_ATOMIC,
this can cause blk_get_request() always to return -EWOULDBLOCK.  Note
that these problems happen only if scsi-mq is enabled.  Prevent the
problems by calling blk_put_request() as soon as the SCSI command
completes instead of waiting for userspace to call read().

Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
Acked-by: Douglas Gilbert <dgilbert@interlog.com>
Tested-by: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/sg.c