[SCSI] fix possible deadlock in scsi_lib.c
authorNeil Brown <neilb@suse.de>
Fri, 2 Sep 2005 03:13:54 +0000 (13:13 +1000)
committerJames Bottomley <jejb@mulgrave.(none)>
Fri, 9 Sep 2005 15:29:22 +0000 (10:29 -0500)
  If a filesystem, while writing out data, decides that it is good
to issue a cache flush on a SCSI drive (or other 'sd' device), it will
call blkdev_issue_flush which calls ->issue_flush_fn which is
scsi_issue_flush_fn.
This calls sd_issue_flush which calls sd_sync_cache, which calls
scsi_execute_request.
This will (as sshdr != NULL) call
    kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL)

If memory is tight, the presence of GFP_KERNEL may cause write
requests to be sent to some filesystem to free up memory, however if
that filesystem is waiting for the issue_flush_fn to complete, you
could get a deadlock.

I wonder if it might be more appropriate to use GFP_NOIO as in the
following patch.

I wonder if it might be even more appropriate to cope better with a
kmalloc failure, especially as in this use, sd_sync_cache only will
use the sense information to print out a more informative error
message.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/scsi_lib.c

index 77f2d44..2ad60f1 100644 (file)
@@ -339,7 +339,7 @@ int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
        int result;
        
        if (sshdr) {
-               sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+               sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
                if (!sense)
                        return DRIVER_ERROR << 24;
                memset(sense, 0, SCSI_SENSE_BUFFERSIZE);