aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2009-01-02 11:42:21 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-01-05 09:54:11 -0500
commit4f5299ac4e3a03d5c596c00d726fa932c600609d (patch)
treeab303d64c6df361fff4531801eaaedd9c473ea42 /drivers/scsi/scsi_lib.c
parenta234b1103f7df35eacb1de7a9d15a636046e263b (diff)
[SCSI] scsi_lib: don't decrement busy counters when inserting commands
A bug was introduced by commit b60af5b0adf0da24c673598c8d3fb4d4189a15ce Author: Alan Stern <stern@rowland.harvard.edu> Date: Mon Nov 3 15:56:47 2008 -0500 [SCSI] simplify scsi_io_completion() because the simplification uses scsi_queue_insert(). The problem with this function is that it expects to be called from the completion path while the command is still outstanding, so it decrements the device and host busy counts to do the requeue. The problem is that scsi_io_completion() is a path executed well after these counts have *already* been decremented, leading to a double decrement if the command goes down any error path leading to ACTION_DELAYED_RETRY. The fix is to allow a private function __scsi_queue_insert() with a flag to say whether the busy counters should be decremented. This is made static to scsi_lib.c to discourage other use. Reported-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 8c73bb4e0a2f..911514c1fea7 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -91,26 +91,19 @@ static void scsi_unprep_request(struct request *req)
91 scsi_put_command(cmd); 91 scsi_put_command(cmd);
92} 92}
93 93
94/* 94/**
95 * Function: scsi_queue_insert() 95 * __scsi_queue_insert - private queue insertion
96 * 96 * @cmd: The SCSI command being requeued
97 * Purpose: Insert a command in the midlevel queue. 97 * @reason: The reason for the requeue
98 * 98 * @unbusy: Whether the queue should be unbusied
99 * Arguments: cmd - command that we are adding to queue. 99 *
100 * reason - why we are inserting command to queue. 100 * This is a private queue insertion. The public interface
101 * 101 * scsi_queue_insert() always assumes the queue should be unbusied
102 * Lock status: Assumed that lock is not held upon entry. 102 * because it's always called before the completion. This function is
103 * 103 * for a requeue after completion, which should only occur in this
104 * Returns: Nothing. 104 * file.
105 *
106 * Notes: We do this for one of two cases. Either the host is busy
107 * and it cannot accept any more commands for the time being,
108 * or the device returned QUEUE_FULL and can accept no more
109 * commands.
110 * Notes: This could be called either from an interrupt context or a
111 * normal process context.
112 */ 105 */
113int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) 106static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
114{ 107{
115 struct Scsi_Host *host = cmd->device->host; 108 struct Scsi_Host *host = cmd->device->host;
116 struct scsi_device *device = cmd->device; 109 struct scsi_device *device = cmd->device;
@@ -150,7 +143,8 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
150 * Decrement the counters, since these commands are no longer 143 * Decrement the counters, since these commands are no longer
151 * active on the host/device. 144 * active on the host/device.
152 */ 145 */
153 scsi_device_unbusy(device); 146 if (unbusy)
147 scsi_device_unbusy(device);
154 148
155 /* 149 /*
156 * Requeue this command. It will go before all other commands 150 * Requeue this command. It will go before all other commands
@@ -172,6 +166,29 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
172 return 0; 166 return 0;
173} 167}
174 168
169/*
170 * Function: scsi_queue_insert()
171 *
172 * Purpose: Insert a command in the midlevel queue.
173 *
174 * Arguments: cmd - command that we are adding to queue.
175 * reason - why we are inserting command to queue.
176 *
177 * Lock status: Assumed that lock is not held upon entry.
178 *
179 * Returns: Nothing.
180 *
181 * Notes: We do this for one of two cases. Either the host is busy
182 * and it cannot accept any more commands for the time being,
183 * or the device returned QUEUE_FULL and can accept no more
184 * commands.
185 * Notes: This could be called either from an interrupt context or a
186 * normal process context.
187 */
188int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
189{
190 return __scsi_queue_insert(cmd, reason, 1);
191}
175/** 192/**
176 * scsi_execute - insert request and wait for the result 193 * scsi_execute - insert request and wait for the result
177 * @sdev: scsi device 194 * @sdev: scsi device
@@ -1075,11 +1092,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
1075 break; 1092 break;
1076 case ACTION_RETRY: 1093 case ACTION_RETRY:
1077 /* Retry the same command immediately */ 1094 /* Retry the same command immediately */
1078 scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY); 1095 __scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY, 0);
1079 break; 1096 break;
1080 case ACTION_DELAYED_RETRY: 1097 case ACTION_DELAYED_RETRY:
1081 /* Retry the same command after a delay */ 1098 /* Retry the same command after a delay */
1082 scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); 1099 __scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
1083 break; 1100 break;
1084 } 1101 }
1085} 1102}