]>
Commit | Line | Data |
---|---|---|
59e2be0a GKH |
1 | From 318aaf34f1179b39fa9c30fa0f3288b645beee39 Mon Sep 17 00:00:00 2001 |
2 | From: Jason Yan <yanaijie@huawei.com> | |
3 | Date: Thu, 8 Mar 2018 10:34:53 +0800 | |
4 | Subject: scsi: libsas: defer ata device eh commands to libata | |
5 | ||
6 | From: Jason Yan <yanaijie@huawei.com> | |
7 | ||
8 | commit 318aaf34f1179b39fa9c30fa0f3288b645beee39 upstream. | |
9 | ||
10 | When ata device doing EH, some commands still attached with tasks are | |
11 | not passed to libata when abort failed or recover failed, so libata did | |
12 | not handle these commands. After these commands done, sas task is freed, | |
13 | but ata qc is not freed. This will cause ata qc leak and trigger a | |
14 | warning like below: | |
15 | ||
16 | WARNING: CPU: 0 PID: 28512 at drivers/ata/libata-eh.c:4037 | |
17 | ata_eh_finish+0xb4/0xcc | |
18 | CPU: 0 PID: 28512 Comm: kworker/u32:2 Tainted: G W OE 4.14.0#1 | |
19 | ...... | |
20 | Call 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 | ||
32 | If ata qc leaked too many, ata tag allocation will fail and io blocked | |
33 | for ever. | |
34 | ||
35 | As suggested by Dan Williams, defer ata device commands to libata and | |
36 | merge sas_eh_finish_cmd() with sas_eh_defer_cmd(). libata will handle | |
37 | ata qcs correctly after this. | |
38 | ||
39 | Signed-off-by: Jason Yan <yanaijie@huawei.com> | |
40 | CC: Xiaofei Tan <tanxiaofei@huawei.com> | |
41 | CC: John Garry <john.garry@huawei.com> | |
42 | CC: Dan Williams <dan.j.williams@intel.com> | |
43 | Reviewed-by: Dan Williams <dan.j.williams@intel.com> | |
44 | Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> | |
45 | Cc: Guenter Roeck <linux@roeck-us.net> | |
46 | Signed-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 | } |