forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/target/target_core_tmr.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*******************************************************************************
23 * Filename: target_core_tmr.c
34 *
....@@ -6,20 +7,6 @@
67 * (c) Copyright 2009-2013 Datera, Inc.
78 *
89 * Nicholas A. Bellinger <nab@kernel.org>
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License as published by
12
- * the Free Software Foundation; either version 2 of the License, or
13
- * (at your option) any later version.
14
- *
15
- * This program is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
- * GNU General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public License
21
- * along with this program; if not, write to the Free Software
22
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2310 *
2411 ******************************************************************************/
2512
....@@ -91,7 +78,7 @@
9178 }
9279
9380 static bool __target_check_io_state(struct se_cmd *se_cmd,
94
- struct se_session *tmr_sess, int tas)
81
+ struct se_session *tmr_sess, bool tas)
9582 {
9683 struct se_session *sess = se_cmd->se_sess;
9784
....@@ -114,21 +101,6 @@
114101 spin_unlock(&se_cmd->t_state_lock);
115102 return false;
116103 }
117
- if (se_cmd->transport_state & CMD_T_PRE_EXECUTE) {
118
- if (se_cmd->scsi_status) {
119
- pr_debug("Attempted to abort io tag: %llu early failure"
120
- " status: 0x%02x\n", se_cmd->tag,
121
- se_cmd->scsi_status);
122
- spin_unlock(&se_cmd->t_state_lock);
123
- return false;
124
- }
125
- }
126
- if (sess->sess_tearing_down) {
127
- pr_debug("Attempted to abort io tag: %llu already shutdown,"
128
- " skipping\n", se_cmd->tag);
129
- spin_unlock(&se_cmd->t_state_lock);
130
- return false;
131
- }
132104 se_cmd->transport_state |= CMD_T_ABORTED;
133105
134106 if ((tmr_sess != se_cmd->se_sess) && tas)
....@@ -144,14 +116,16 @@
144116 struct se_tmr_req *tmr,
145117 struct se_session *se_sess)
146118 {
147
- struct se_cmd *se_cmd;
119
+ LIST_HEAD(aborted_list);
120
+ struct se_cmd *se_cmd, *next;
148121 unsigned long flags;
122
+ bool rc;
149123 u64 ref_tag;
150124
151
- spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
152
- list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
125
+ spin_lock_irqsave(&dev->execute_task_lock, flags);
126
+ list_for_each_entry_safe(se_cmd, next, &dev->state_list, state_list) {
153127
154
- if (dev != se_cmd->se_dev)
128
+ if (se_sess != se_cmd->se_sess)
155129 continue;
156130
157131 /* skip task management functions, including tmr->task_cmd */
....@@ -163,18 +137,33 @@
163137 continue;
164138
165139 printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
166
- se_cmd->se_tfo->get_fabric_name(), ref_tag);
140
+ se_cmd->se_tfo->fabric_name, ref_tag);
167141
168
- if (!__target_check_io_state(se_cmd, se_sess, 0))
142
+ spin_lock(&se_sess->sess_cmd_lock);
143
+ rc = __target_check_io_state(se_cmd, se_sess, 0);
144
+ spin_unlock(&se_sess->sess_cmd_lock);
145
+ if (!rc)
169146 continue;
170147
171
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
148
+ list_move_tail(&se_cmd->state_list, &aborted_list);
149
+ se_cmd->state_active = false;
172150
173
- cancel_work_sync(&se_cmd->work);
174
- transport_wait_for_tasks(se_cmd);
151
+ spin_unlock_irqrestore(&dev->execute_task_lock, flags);
175152
176
- if (!transport_cmd_finish_abort(se_cmd))
177
- target_put_sess_cmd(se_cmd);
153
+ /*
154
+ * Ensure that this ABORT request is visible to the LU RESET
155
+ * code.
156
+ */
157
+ if (!tmr->tmr_dev)
158
+ WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) <
159
+ 0);
160
+
161
+ if (dev->transport->tmr_notify)
162
+ dev->transport->tmr_notify(dev, TMR_ABORT_TASK,
163
+ &aborted_list);
164
+
165
+ list_del_init(&se_cmd->state_list);
166
+ target_put_cmd_and_wait(se_cmd);
178167
179168 printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
180169 " ref_tag: %llu\n", ref_tag);
....@@ -182,7 +171,10 @@
182171 atomic_long_inc(&dev->aborts_complete);
183172 return;
184173 }
185
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
174
+ spin_unlock_irqrestore(&dev->execute_task_lock, flags);
175
+
176
+ if (dev->transport->tmr_notify)
177
+ dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list);
186178
187179 printk("ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST for ref_tag: %lld\n",
188180 tmr->ref_task_tag);
....@@ -227,33 +219,13 @@
227219 continue;
228220
229221 spin_lock(&sess->sess_cmd_lock);
230
- spin_lock(&cmd->t_state_lock);
231
- if (!(cmd->transport_state & CMD_T_ACTIVE) ||
232
- (cmd->transport_state & CMD_T_FABRIC_STOP)) {
233
- spin_unlock(&cmd->t_state_lock);
234
- spin_unlock(&sess->sess_cmd_lock);
235
- continue;
236
- }
237
- if (cmd->t_state == TRANSPORT_ISTATE_PROCESSING) {
238
- spin_unlock(&cmd->t_state_lock);
239
- spin_unlock(&sess->sess_cmd_lock);
240
- continue;
241
- }
242
- if (sess->sess_tearing_down) {
243
- spin_unlock(&cmd->t_state_lock);
244
- spin_unlock(&sess->sess_cmd_lock);
245
- continue;
246
- }
247
- cmd->transport_state |= CMD_T_ABORTED;
248
- spin_unlock(&cmd->t_state_lock);
222
+ rc = __target_check_io_state(cmd, sess, 0);
223
+ spin_unlock(&sess->sess_cmd_lock);
249224
250
- rc = kref_get_unless_zero(&cmd->cmd_kref);
251225 if (!rc) {
252226 printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n");
253
- spin_unlock(&sess->sess_cmd_lock);
254227 continue;
255228 }
256
- spin_unlock(&sess->sess_cmd_lock);
257229
258230 list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
259231 }
....@@ -268,19 +240,33 @@
268240 (preempt_and_abort_list) ? "Preempt" : "", tmr_p,
269241 tmr_p->function, tmr_p->response, cmd->t_state);
270242
271
- cancel_work_sync(&cmd->work);
272
- transport_wait_for_tasks(cmd);
273
-
274
- if (!transport_cmd_finish_abort(cmd))
275
- target_put_sess_cmd(cmd);
243
+ target_put_cmd_and_wait(cmd);
276244 }
277245 }
278246
247
+/**
248
+ * core_tmr_drain_state_list() - abort SCSI commands associated with a device
249
+ *
250
+ * @dev: Device for which to abort outstanding SCSI commands.
251
+ * @prout_cmd: Pointer to the SCSI PREEMPT AND ABORT if this function is called
252
+ * to realize the PREEMPT AND ABORT functionality.
253
+ * @tmr_sess: Session through which the LUN RESET has been received.
254
+ * @tas: Task Aborted Status (TAS) bit from the SCSI control mode page.
255
+ * A quote from SPC-4, paragraph "7.5.10 Control mode page":
256
+ * "A task aborted status (TAS) bit set to zero specifies that
257
+ * aborted commands shall be terminated by the device server
258
+ * without any response to the application client. A TAS bit set
259
+ * to one specifies that commands aborted by the actions of an I_T
260
+ * nexus other than the I_T nexus on which the command was
261
+ * received shall be completed with TASK ABORTED status."
262
+ * @preempt_and_abort_list: For the PREEMPT AND ABORT functionality, a list
263
+ * with registrations that will be preempted.
264
+ */
279265 static void core_tmr_drain_state_list(
280266 struct se_device *dev,
281267 struct se_cmd *prout_cmd,
282268 struct se_session *tmr_sess,
283
- int tas,
269
+ bool tas,
284270 struct list_head *preempt_and_abort_list)
285271 {
286272 LIST_HEAD(drain_task_list);
....@@ -341,6 +327,11 @@
341327 }
342328 spin_unlock_irqrestore(&dev->execute_task_lock, flags);
343329
330
+ if (dev->transport->tmr_notify)
331
+ dev->transport->tmr_notify(dev, preempt_and_abort_list ?
332
+ TMR_LUN_RESET_PRO : TMR_LUN_RESET,
333
+ &drain_task_list);
334
+
344335 while (!list_empty(&drain_task_list)) {
345336 cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
346337 list_del_init(&cmd->state_list);
....@@ -350,18 +341,7 @@
350341 cmd->tag, (preempt_and_abort_list) ? "preempt" : "",
351342 cmd->pr_res_key);
352343
353
- /*
354
- * If the command may be queued onto a workqueue cancel it now.
355
- *
356
- * This is equivalent to removal from the execute queue in the
357
- * loop above, but we do it down here given that
358
- * cancel_work_sync may block.
359
- */
360
- cancel_work_sync(&cmd->work);
361
- transport_wait_for_tasks(cmd);
362
-
363
- if (!transport_cmd_finish_abort(cmd))
364
- target_put_sess_cmd(cmd);
344
+ target_put_cmd_and_wait(cmd);
365345 }
366346 }
367347
....@@ -374,7 +354,7 @@
374354 struct se_node_acl *tmr_nacl = NULL;
375355 struct se_portal_group *tmr_tpg = NULL;
376356 struct se_session *tmr_sess = NULL;
377
- int tas;
357
+ bool tas;
378358 /*
379359 * TASK_ABORTED status bit, this is configurable via ConfigFS
380360 * struct se_device attributes. spc4r17 section 7.4.6 Control mode page
....@@ -398,7 +378,7 @@
398378 if (tmr_nacl && tmr_tpg) {
399379 pr_debug("LUN_RESET: TMR caller fabric: %s"
400380 " initiator port %s\n",
401
- tmr_tpg->se_tpg_tfo->get_fabric_name(),
381
+ tmr_tpg->se_tpg_tfo->fabric_name,
402382 tmr_nacl->initiatorname);
403383 }
404384 }
....@@ -417,7 +397,7 @@
417397 if (!preempt_and_abort_list &&
418398 (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) {
419399 spin_lock(&dev->dev_reservation_lock);
420
- dev->dev_reserved_node_acl = NULL;
400
+ dev->reservation_holder = NULL;
421401 dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
422402 spin_unlock(&dev->dev_reservation_lock);
423403 pr_debug("LUN_RESET: SCSI-2 Released reservation\n");