]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.133/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.133 / scsi-libsas-defer-ata-device-eh-commands-to-libata.patch
CommitLineData
59e2be0a
GKH
1From 318aaf34f1179b39fa9c30fa0f3288b645beee39 Mon Sep 17 00:00:00 2001
2From: Jason Yan <yanaijie@huawei.com>
3Date: Thu, 8 Mar 2018 10:34:53 +0800
4Subject: scsi: libsas: defer ata device eh commands to libata
5
6From: Jason Yan <yanaijie@huawei.com>
7
8commit 318aaf34f1179b39fa9c30fa0f3288b645beee39 upstream.
9
10When ata device doing EH, some commands still attached with tasks are
11not passed to libata when abort failed or recover failed, so libata did
12not handle these commands. After these commands done, sas task is freed,
13but ata qc is not freed. This will cause ata qc leak and trigger a
14warning like below:
15
16WARNING: CPU: 0 PID: 28512 at drivers/ata/libata-eh.c:4037
17ata_eh_finish+0xb4/0xcc
18CPU: 0 PID: 28512 Comm: kworker/u32:2 Tainted: G W OE 4.14.0#1
19......
20Call trace:
21[<ffff0000088b7bd0>] ata_eh_finish+0xb4/0xcc
22[<ffff0000088b8420>] ata_do_eh+0xc4/0xd8
23[<ffff0000088b8478>] ata_std_error_handler+0x44/0x8c
24[<ffff0000088b8068>] ata_scsi_port_error_handler+0x480/0x694
25[<ffff000008875fc4>] async_sas_ata_eh+0x4c/0x80
26[<ffff0000080f6be8>] async_run_entry_fn+0x4c/0x170
27[<ffff0000080ebd70>] process_one_work+0x144/0x390
28[<ffff0000080ec100>] worker_thread+0x144/0x418
29[<ffff0000080f2c98>] kthread+0x10c/0x138
30[<ffff0000080855dc>] ret_from_fork+0x10/0x18
31
32If ata qc leaked too many, ata tag allocation will fail and io blocked
33for ever.
34
35As suggested by Dan Williams, defer ata device commands to libata and
36merge sas_eh_finish_cmd() with sas_eh_defer_cmd(). libata will handle
37ata qcs correctly after this.
38
39Signed-off-by: Jason Yan <yanaijie@huawei.com>
40CC: Xiaofei Tan <tanxiaofei@huawei.com>
41CC: John Garry <john.garry@huawei.com>
42CC: Dan Williams <dan.j.williams@intel.com>
43Reviewed-by: Dan Williams <dan.j.williams@intel.com>
44Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
45Cc: Guenter Roeck <linux@roeck-us.net>
46Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
47
48---
49 drivers/scsi/libsas/sas_scsi_host.c | 33 +++++++++++++--------------------
50 1 file changed, 13 insertions(+), 20 deletions(-)
51
52--- a/drivers/scsi/libsas/sas_scsi_host.c
53+++ b/drivers/scsi/libsas/sas_scsi_host.c
54@@ -222,6 +222,7 @@ out_done:
55 static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
56 {
57 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
58+ struct domain_device *dev = cmd_to_domain_dev(cmd);
59 struct sas_task *task = TO_SAS_TASK(cmd);
60
61 /* At this point, we only get called following an actual abort
62@@ -230,6 +231,14 @@ static void sas_eh_finish_cmd(struct scs
63 */
64 sas_end_task(cmd, task);
65
66+ if (dev_is_sata(dev)) {
67+ /* defer commands to libata so that libata EH can
68+ * handle ata qcs correctly
69+ */
70+ list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q);
71+ return;
72+ }
73+
74 /* now finish the command and move it on to the error
75 * handler done list, this also takes it off the
76 * error handler pending list.
77@@ -237,22 +246,6 @@ static void sas_eh_finish_cmd(struct scs
78 scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
79 }
80
81-static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
82-{
83- struct domain_device *dev = cmd_to_domain_dev(cmd);
84- struct sas_ha_struct *ha = dev->port->ha;
85- struct sas_task *task = TO_SAS_TASK(cmd);
86-
87- if (!dev_is_sata(dev)) {
88- sas_eh_finish_cmd(cmd);
89- return;
90- }
91-
92- /* report the timeout to libata */
93- sas_end_task(cmd, task);
94- list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
95-}
96-
97 static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
98 {
99 struct scsi_cmnd *cmd, *n;
100@@ -260,7 +253,7 @@ static void sas_scsi_clear_queue_lu(stru
101 list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
102 if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
103 cmd->device->lun == my_cmd->device->lun)
104- sas_eh_defer_cmd(cmd);
105+ sas_eh_finish_cmd(cmd);
106 }
107 }
108
109@@ -622,12 +615,12 @@ static void sas_eh_handle_sas_errors(str
110 case TASK_IS_DONE:
111 SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
112 task);
113- sas_eh_defer_cmd(cmd);
114+ sas_eh_finish_cmd(cmd);
115 continue;
116 case TASK_IS_ABORTED:
117 SAS_DPRINTK("%s: task 0x%p is aborted\n",
118 __func__, task);
119- sas_eh_defer_cmd(cmd);
120+ sas_eh_finish_cmd(cmd);
121 continue;
122 case TASK_IS_AT_LU:
123 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
124@@ -638,7 +631,7 @@ static void sas_eh_handle_sas_errors(str
125 "recovered\n",
126 SAS_ADDR(task->dev),
127 cmd->device->lun);
128- sas_eh_defer_cmd(cmd);
129+ sas_eh_finish_cmd(cmd);
130 sas_scsi_clear_queue_lu(work_q, cmd);
131 goto Again;
132 }