diff options
-rw-r--r-- | Documentation/scsi/scsi_eh.txt | 69 | ||||
-rw-r--r-- | Documentation/scsi/scsi_mid_low_api.txt | 9 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 6 |
3 files changed, 48 insertions, 36 deletions
diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt index 6ff16b620d84..a0c85110a07e 100644 --- a/Documentation/scsi/scsi_eh.txt +++ b/Documentation/scsi/scsi_eh.txt | |||
@@ -42,20 +42,14 @@ discussion. | |||
42 | 42 | ||
43 | Once LLDD gets hold of a scmd, either the LLDD will complete the | 43 | Once LLDD gets hold of a scmd, either the LLDD will complete the |
44 | command by calling scsi_done callback passed from midlayer when | 44 | command by calling scsi_done callback passed from midlayer when |
45 | invoking hostt->queuecommand() or SCSI midlayer will time it out. | 45 | invoking hostt->queuecommand() or the block layer will time it out. |
46 | 46 | ||
47 | 47 | ||
48 | [1-2-1] Completing a scmd w/ scsi_done | 48 | [1-2-1] Completing a scmd w/ scsi_done |
49 | 49 | ||
50 | For all non-EH commands, scsi_done() is the completion callback. It | 50 | For all non-EH commands, scsi_done() is the completion callback. It |
51 | does the following. | 51 | just calls blk_complete_request() to delete the block layer timer and |
52 | 52 | raise SCSI_SOFTIRQ | |
53 | 1. Delete timeout timer. If it fails, it means that timeout timer | ||
54 | has expired and is going to finish the command. Just return. | ||
55 | |||
56 | 2. Link scmd to per-cpu scsi_done_q using scmd->en_entry | ||
57 | |||
58 | 3. Raise SCSI_SOFTIRQ | ||
59 | 53 | ||
60 | SCSI_SOFTIRQ handler scsi_softirq calls scsi_decide_disposition() to | 54 | SCSI_SOFTIRQ handler scsi_softirq calls scsi_decide_disposition() to |
61 | determine what to do with the command. scsi_decide_disposition() | 55 | determine what to do with the command. scsi_decide_disposition() |
@@ -64,10 +58,12 @@ with the command. | |||
64 | 58 | ||
65 | - SUCCESS | 59 | - SUCCESS |
66 | scsi_finish_command() is invoked for the command. The | 60 | scsi_finish_command() is invoked for the command. The |
67 | function does some maintenance choirs and notify completion by | 61 | function does some maintenance chores and then calls |
68 | calling scmd->done() callback, which, for fs requests, would | 62 | scsi_io_completion() to finish the I/O. |
69 | be HLD completion callback - sd:sd_rw_intr, sr:rw_intr, | 63 | scsi_io_completion() then notifies the block layer on |
70 | st:st_intr. | 64 | the completed request by calling blk_end_request and |
65 | friends or figures out what to do with the remainder | ||
66 | of the data in case of an error. | ||
71 | 67 | ||
72 | - NEEDS_RETRY | 68 | - NEEDS_RETRY |
73 | - ADD_TO_MLQUEUE | 69 | - ADD_TO_MLQUEUE |
@@ -86,33 +82,45 @@ function | |||
86 | 1. invokes optional hostt->eh_timed_out() callback. Return value can | 82 | 1. invokes optional hostt->eh_timed_out() callback. Return value can |
87 | be one of | 83 | be one of |
88 | 84 | ||
89 | - EH_HANDLED | 85 | - BLK_EH_HANDLED |
90 | This indicates that eh_timed_out() dealt with the timeout. The | 86 | This indicates that eh_timed_out() dealt with the timeout. |
91 | scmd is passed to __scsi_done() and thus linked into per-cpu | 87 | The command is passed back to the block layer and completed |
92 | scsi_done_q. Normal command completion described in [1-2-1] | 88 | via __blk_complete_requests(). |
93 | follows. | 89 | |
90 | *NOTE* After returning BLK_EH_HANDLED the SCSI layer is | ||
91 | assumed to be finished with the command, and no other | ||
92 | functions from the SCSI layer will be called. So this | ||
93 | should typically only be returned if the eh_timed_out() | ||
94 | handler raced with normal completion. | ||
94 | 95 | ||
95 | - EH_RESET_TIMER | 96 | - BLK_EH_RESET_TIMER |
96 | This indicates that more time is required to finish the | 97 | This indicates that more time is required to finish the |
97 | command. Timer is restarted. This action is counted as a | 98 | command. Timer is restarted. This action is counted as a |
98 | retry and only allowed scmd->allowed + 1(!) times. Once the | 99 | retry and only allowed scmd->allowed + 1(!) times. Once the |
99 | limit is reached, action for EH_NOT_HANDLED is taken instead. | 100 | limit is reached, action for BLK_EH_NOT_HANDLED is taken instead. |
100 | 101 | ||
101 | *NOTE* This action is racy as the LLDD could finish the scmd | 102 | - BLK_EH_NOT_HANDLED |
102 | after the timeout has expired but before it's added back. In | 103 | eh_timed_out() callback did not handle the command. |
103 | such cases, scsi_done() would think that timeout has occurred | ||
104 | and return without doing anything. We lose completion and the | ||
105 | command will time out again. | ||
106 | |||
107 | - EH_NOT_HANDLED | ||
108 | This is the same as when eh_timed_out() callback doesn't exist. | ||
109 | Step #2 is taken. | 104 | Step #2 is taken. |
110 | 105 | ||
106 | 2. If the host supports asynchronous completion (as indicated by the | ||
107 | no_async_abort setting in the host template) scsi_abort_command() | ||
108 | is invoked to schedule an asynchrous abort. If that fails | ||
109 | Step #3 is taken. | ||
110 | |||
111 | 2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the | 111 | 2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the |
112 | command. See [1-3] for more information. | 112 | command. See [1-3] for more information. |
113 | 113 | ||
114 | [1-3] Asynchronous command aborts | ||
115 | |||
116 | After a timeout occurs a command abort is scheduled from | ||
117 | scsi_abort_command(). If the abort is successful the command | ||
118 | will either be retried (if the number of retries is not exhausted) | ||
119 | or terminated with DID_TIME_OUT. | ||
120 | Otherwise scsi_eh_scmd_add() is invoked for the command. | ||
121 | See [1-4] for more information. | ||
114 | 122 | ||
115 | [1-3] How EH takes over | 123 | [1-4] How EH takes over |
116 | 124 | ||
117 | scmds enter EH via scsi_eh_scmd_add(), which does the following. | 125 | scmds enter EH via scsi_eh_scmd_add(), which does the following. |
118 | 126 | ||
@@ -320,7 +328,8 @@ scmd->allowed. | |||
320 | 328 | ||
321 | <<scsi_eh_abort_cmds>> | 329 | <<scsi_eh_abort_cmds>> |
322 | 330 | ||
323 | This action is taken for each timed out command. | 331 | This action is taken for each timed out command when |
332 | no_async_abort is enabled in the host template. | ||
324 | hostt->eh_abort_handler() is invoked for each scmd. The | 333 | hostt->eh_abort_handler() is invoked for each scmd. The |
325 | handler returns SUCCESS if it has succeeded to make LLDD and | 334 | handler returns SUCCESS if it has succeeded to make LLDD and |
326 | all related hardware forget about the scmd. | 335 | all related hardware forget about the scmd. |
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 2b06aba4fa0f..d6a9bdeee7f2 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt | |||
@@ -882,8 +882,11 @@ Details: | |||
882 | * | 882 | * |
883 | * Calling context: kernel thread | 883 | * Calling context: kernel thread |
884 | * | 884 | * |
885 | * Notes: Invoked from scsi_eh thread. No other commands will be | 885 | * Notes: If 'no_async_abort' is defined this callback |
886 | * queued on current host during eh. | 886 | * will be invoked from scsi_eh thread. No other commands |
887 | * will then be queued on current host during eh. | ||
888 | * Otherwise it will be called whenever scsi_times_out() | ||
889 | * is called due to a command timeout. | ||
887 | * | 890 | * |
888 | * Optionally defined in: LLD | 891 | * Optionally defined in: LLD |
889 | **/ | 892 | **/ |
@@ -1257,6 +1260,8 @@ of interest: | |||
1257 | address space | 1260 | address space |
1258 | use_clustering - 1=>SCSI commands in mid level's queue can be merged, | 1261 | use_clustering - 1=>SCSI commands in mid level's queue can be merged, |
1259 | 0=>disallow SCSI command merging | 1262 | 0=>disallow SCSI command merging |
1263 | no_async_abort - 1=>Asynchronous aborts are not supported | ||
1264 | 0=>Timed-out commands will be aborted asynchronously | ||
1260 | hostt - pointer to driver's struct scsi_host_template from which | 1265 | hostt - pointer to driver's struct scsi_host_template from which |
1261 | this struct Scsi_Host instance was spawned | 1266 | this struct Scsi_Host instance was spawned |
1262 | hostt->proc_name - name of LLD. This is the driver name that sysfs uses | 1267 | hostt->proc_name - name of LLD. This is the driver name that sysfs uses |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2b04a57e0f4f..d8afec8317cf 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -745,15 +745,13 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
745 | } | 745 | } |
746 | 746 | ||
747 | /** | 747 | /** |
748 | * scsi_done - Enqueue the finished SCSI command into the done queue. | 748 | * scsi_done - Invoke completion on finished SCSI command. |
749 | * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives | 749 | * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives |
750 | * ownership back to SCSI Core -- i.e. the LLDD has finished with it. | 750 | * ownership back to SCSI Core -- i.e. the LLDD has finished with it. |
751 | * | 751 | * |
752 | * Description: This function is the mid-level's (SCSI Core) interrupt routine, | 752 | * Description: This function is the mid-level's (SCSI Core) interrupt routine, |
753 | * which regains ownership of the SCSI command (de facto) from a LLDD, and | 753 | * which regains ownership of the SCSI command (de facto) from a LLDD, and |
754 | * enqueues the command to the done queue for further processing. | 754 | * calls blk_complete_request() for further processing. |
755 | * | ||
756 | * This is the producer of the done queue who enqueues at the tail. | ||
757 | * | 755 | * |
758 | * This function is interrupt context safe. | 756 | * This function is interrupt context safe. |
759 | */ | 757 | */ |