aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/request.c
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-03-04 17:06:42 -0500
committerDan Williams <dan.j.williams@intel.com>2011-07-03 06:55:29 -0400
commita5fde225364df30507ba1a5aafeec85e595000d3 (patch)
treed86c9daaafe01e9df139fe0569d7d21ce6fa3f8d /drivers/scsi/isci/request.c
parent11b00c194cfbd0eb0d90f32c096508b2bb8be6ec (diff)
isci: fix completion / abort path.
Corrected use of the request state_lock in the completion callback. In the case where an abort (or reset) thread is trying to terminate an I/O request, it sets the request state to "aborting" (or "terminating") if the state is still "starting". One of the bugs was to never set the state to "completed". Another was to not correctly recognize the situation where the I/O had completed but the sas_task was still pending callback to task_done - this was typically a problem in the LUN and device reset cases. It is now possible that we leave isci_task_abort_task() with request->io_request_completion pointing to localy allocated aborted_io_completion struct. It may result in a system crash. Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Maciej Trela <Maciej.Trela@intel.com> Signed-off-by: Jacek Danecki <Jacek.Danecki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r--drivers/scsi/isci/request.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 8039f1c72f72..c88e270b2b40 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -814,9 +814,8 @@ static void isci_task_save_for_upper_layer_completion(
814 break; 814 break;
815 815
816 case isci_perform_aborted_io_completion: 816 case isci_perform_aborted_io_completion:
817 /* 817 /* No notification to libsas because this request is
818 * No notification because this request is already 818 * already in the abort path.
819 * in the abort path.
820 */ 819 */
821 dev_warn(&host->pdev->dev, 820 dev_warn(&host->pdev->dev,
822 "%s: Aborted - task = %p, response=%d, status=%d\n", 821 "%s: Aborted - task = %p, response=%d, status=%d\n",
@@ -824,6 +823,19 @@ static void isci_task_save_for_upper_layer_completion(
824 task, 823 task,
825 response, 824 response,
826 status); 825 status);
826
827 /* Wake up whatever process was waiting for this
828 * request to complete.
829 */
830 WARN_ON(request->io_request_completion == NULL);
831
832 if (request->io_request_completion != NULL) {
833
834 /* Signal whoever is waiting that this
835 * request is complete.
836 */
837 complete(request->io_request_completion);
838 }
827 break; 839 break;
828 840
829 case isci_perform_error_io_completion: 841 case isci_perform_error_io_completion:
@@ -847,7 +859,7 @@ static void isci_task_save_for_upper_layer_completion(
847 response, 859 response,
848 status); 860 status);
849 861
850 /* Add to the aborted list. */ 862 /* Add to the error to libsas list. */
851 list_add(&request->completed_node, 863 list_add(&request->completed_node,
852 &host->requests_to_errorback); 864 &host->requests_to_errorback);
853 break; 865 break;
@@ -873,8 +885,6 @@ void isci_request_io_request_complete(
873 struct ssp_response_iu *resp_iu; 885 struct ssp_response_iu *resp_iu;
874 void *resp_buf; 886 void *resp_buf;
875 unsigned long task_flags; 887 unsigned long task_flags;
876 unsigned long state_flags;
877 struct completion *io_request_completion;
878 struct isci_remote_device *isci_device = request->isci_device; 888 struct isci_remote_device *isci_device = request->isci_device;
879 enum service_response response = SAS_TASK_UNDELIVERED; 889 enum service_response response = SAS_TASK_UNDELIVERED;
880 enum exec_status status = SAS_ABORTED_TASK; 890 enum exec_status status = SAS_ABORTED_TASK;
@@ -891,9 +901,8 @@ void isci_request_io_request_complete(
891 task->data_dir, 901 task->data_dir,
892 completion_status); 902 completion_status);
893 903
894 spin_lock_irqsave(&request->state_lock, state_flags); 904 spin_lock(&request->state_lock);
895 request_status = isci_request_get_state(request); 905 request_status = isci_request_get_state(request);
896 spin_unlock_irqrestore(&request->state_lock, state_flags);
897 906
898 /* Decode the request status. Note that if the request has been 907 /* Decode the request status. Note that if the request has been
899 * aborted by a task management function, we don't care 908 * aborted by a task management function, we don't care
@@ -928,6 +937,8 @@ void isci_request_io_request_complete(
928 937
929 complete_to_host = isci_perform_aborted_io_completion; 938 complete_to_host = isci_perform_aborted_io_completion;
930 /* This was an aborted request. */ 939 /* This was an aborted request. */
940
941 spin_unlock(&request->state_lock);
931 break; 942 break;
932 943
933 case aborting: 944 case aborting:
@@ -955,6 +966,8 @@ void isci_request_io_request_complete(
955 complete_to_host = isci_perform_aborted_io_completion; 966 complete_to_host = isci_perform_aborted_io_completion;
956 967
957 /* This was an aborted request. */ 968 /* This was an aborted request. */
969
970 spin_unlock(&request->state_lock);
958 break; 971 break;
959 972
960 case terminating: 973 case terminating:
@@ -977,13 +990,20 @@ void isci_request_io_request_complete(
977 else 990 else
978 status = SAS_ABORTED_TASK; 991 status = SAS_ABORTED_TASK;
979 992
980 complete_to_host = isci_perform_normal_io_completion; 993 complete_to_host = isci_perform_aborted_io_completion;
981 994
982 /* This was a terminated request. */ 995 /* This was a terminated request. */
996
997 spin_unlock(&request->state_lock);
983 break; 998 break;
984 999
985 default: 1000 default:
986 1001
1002 /* The request is done from an SCU HW perspective. */
1003 request->status = completed;
1004
1005 spin_unlock(&request->state_lock);
1006
987 /* This is an active request being completed from the core. */ 1007 /* This is an active request being completed from the core. */
988 switch (completion_status) { 1008 switch (completion_status) {
989 1009
@@ -1185,20 +1205,6 @@ void isci_request_io_request_complete(
1185 */ 1205 */
1186 request->sci_request_handle = NULL; 1206 request->sci_request_handle = NULL;
1187 1207
1188 /* Save possible completion ptr. */
1189 io_request_completion = request->io_request_completion;
1190
1191 if (io_request_completion) {
1192
1193 /* This is inherantly a regular I/O request,
1194 * since we are currently in the regular
1195 * I/O completion callback function.
1196 * Signal whoever is waiting that this
1197 * request is complete.
1198 */
1199 complete(io_request_completion);
1200 }
1201
1202 isci_host_can_dequeue(isci_host, 1); 1208 isci_host_can_dequeue(isci_host, 1);
1203} 1209}
1204 1210