hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
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,12 +78,12 @@
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
98
- assert_spin_locked(&sess->sess_cmd_lock);
99
- WARN_ON_ONCE(!irqs_disabled());
85
+ lockdep_assert_held(&sess->sess_cmd_lock);
86
+
10087 /*
10188 * If command already reached CMD_T_COMPLETE state within
10289 * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown,
....@@ -111,21 +98,6 @@
11198 if (se_cmd->transport_state & (CMD_T_COMPLETE | CMD_T_FABRIC_STOP)) {
11299 pr_debug("Attempted to abort io tag: %llu already complete or"
113100 " fabric stop, skipping\n", se_cmd->tag);
114
- spin_unlock(&se_cmd->t_state_lock);
115
- return false;
116
- }
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);
129101 spin_unlock(&se_cmd->t_state_lock);
130102 return false;
131103 }
....@@ -144,45 +116,69 @@
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;
124
+ int i;
150125
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) {
126
+ for (i = 0; i < dev->queue_cnt; i++) {
127
+ spin_lock_irqsave(&dev->queues[i].lock, flags);
128
+ list_for_each_entry_safe(se_cmd, next, &dev->queues[i].state_list,
129
+ state_list) {
130
+ if (se_sess != se_cmd->se_sess)
131
+ continue;
153132
154
- if (dev != se_cmd->se_dev)
155
- continue;
133
+ /*
134
+ * skip task management functions, including
135
+ * tmr->task_cmd
136
+ */
137
+ if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
138
+ continue;
156139
157
- /* skip task management functions, including tmr->task_cmd */
158
- if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
159
- continue;
140
+ ref_tag = se_cmd->tag;
141
+ if (tmr->ref_task_tag != ref_tag)
142
+ continue;
160143
161
- ref_tag = se_cmd->tag;
162
- if (tmr->ref_task_tag != ref_tag)
163
- continue;
144
+ pr_err("ABORT_TASK: Found referenced %s task_tag: %llu\n",
145
+ se_cmd->se_tfo->fabric_name, ref_tag);
164146
165
- printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
166
- se_cmd->se_tfo->get_fabric_name(), ref_tag);
147
+ spin_lock(&se_sess->sess_cmd_lock);
148
+ rc = __target_check_io_state(se_cmd, se_sess, 0);
149
+ spin_unlock(&se_sess->sess_cmd_lock);
150
+ if (!rc)
151
+ continue;
167152
168
- if (!__target_check_io_state(se_cmd, se_sess, 0))
169
- continue;
153
+ list_move_tail(&se_cmd->state_list, &aborted_list);
154
+ se_cmd->state_active = false;
155
+ spin_unlock_irqrestore(&dev->queues[i].lock, flags);
170156
171
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
157
+ /*
158
+ * Ensure that this ABORT request is visible to the LU
159
+ * RESET code.
160
+ */
161
+ if (!tmr->tmr_dev)
162
+ WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) < 0);
172163
173
- cancel_work_sync(&se_cmd->work);
174
- transport_wait_for_tasks(se_cmd);
164
+ if (dev->transport->tmr_notify)
165
+ dev->transport->tmr_notify(dev, TMR_ABORT_TASK,
166
+ &aborted_list);
175167
176
- if (!transport_cmd_finish_abort(se_cmd))
177
- target_put_sess_cmd(se_cmd);
168
+ list_del_init(&se_cmd->state_list);
169
+ target_put_cmd_and_wait(se_cmd);
178170
179
- printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
180
- " ref_tag: %llu\n", ref_tag);
181
- tmr->response = TMR_FUNCTION_COMPLETE;
182
- atomic_long_inc(&dev->aborts_complete);
183
- return;
171
+ pr_err("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for ref_tag: %llu\n",
172
+ ref_tag);
173
+ tmr->response = TMR_FUNCTION_COMPLETE;
174
+ atomic_long_inc(&dev->aborts_complete);
175
+ return;
176
+ }
177
+ spin_unlock_irqrestore(&dev->queues[i].lock, flags);
184178 }
185
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
179
+
180
+ if (dev->transport->tmr_notify)
181
+ dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list);
186182
187183 printk("ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST for ref_tag: %lld\n",
188184 tmr->ref_task_tag);
....@@ -206,14 +202,23 @@
206202 * LUN_RESET tmr..
207203 */
208204 spin_lock_irqsave(&dev->se_tmr_lock, flags);
209
- if (tmr)
210
- list_del_init(&tmr->tmr_list);
211205 list_for_each_entry_safe(tmr_p, tmr_pp, &dev->dev_tmr_list, tmr_list) {
206
+ if (tmr_p == tmr)
207
+ continue;
208
+
212209 cmd = tmr_p->task_cmd;
213210 if (!cmd) {
214211 pr_err("Unable to locate struct se_cmd for TMR\n");
215212 continue;
216213 }
214
+
215
+ /*
216
+ * We only execute one LUN_RESET at a time so we can't wait
217
+ * on them below.
218
+ */
219
+ if (tmr_p->function == TMR_LUN_RESET)
220
+ continue;
221
+
217222 /*
218223 * If this function was called with a valid pr_res_key
219224 * parameter (eg: for PROUT PREEMPT_AND_ABORT service action
....@@ -227,33 +232,13 @@
227232 continue;
228233
229234 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);
235
+ rc = __target_check_io_state(cmd, sess, 0);
236
+ spin_unlock(&sess->sess_cmd_lock);
249237
250
- rc = kref_get_unless_zero(&cmd->cmd_kref);
251238 if (!rc) {
252239 printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n");
253
- spin_unlock(&sess->sess_cmd_lock);
254240 continue;
255241 }
256
- spin_unlock(&sess->sess_cmd_lock);
257242
258243 list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
259244 }
....@@ -268,26 +253,40 @@
268253 (preempt_and_abort_list) ? "Preempt" : "", tmr_p,
269254 tmr_p->function, tmr_p->response, cmd->t_state);
270255
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);
256
+ target_put_cmd_and_wait(cmd);
276257 }
277258 }
278259
260
+/**
261
+ * core_tmr_drain_state_list() - abort SCSI commands associated with a device
262
+ *
263
+ * @dev: Device for which to abort outstanding SCSI commands.
264
+ * @prout_cmd: Pointer to the SCSI PREEMPT AND ABORT if this function is called
265
+ * to realize the PREEMPT AND ABORT functionality.
266
+ * @tmr_sess: Session through which the LUN RESET has been received.
267
+ * @tas: Task Aborted Status (TAS) bit from the SCSI control mode page.
268
+ * A quote from SPC-4, paragraph "7.5.10 Control mode page":
269
+ * "A task aborted status (TAS) bit set to zero specifies that
270
+ * aborted commands shall be terminated by the device server
271
+ * without any response to the application client. A TAS bit set
272
+ * to one specifies that commands aborted by the actions of an I_T
273
+ * nexus other than the I_T nexus on which the command was
274
+ * received shall be completed with TASK ABORTED status."
275
+ * @preempt_and_abort_list: For the PREEMPT AND ABORT functionality, a list
276
+ * with registrations that will be preempted.
277
+ */
279278 static void core_tmr_drain_state_list(
280279 struct se_device *dev,
281280 struct se_cmd *prout_cmd,
282281 struct se_session *tmr_sess,
283
- int tas,
282
+ bool tas,
284283 struct list_head *preempt_and_abort_list)
285284 {
286285 LIST_HEAD(drain_task_list);
287286 struct se_session *sess;
288287 struct se_cmd *cmd, *next;
289288 unsigned long flags;
290
- int rc;
289
+ int rc, i;
291290
292291 /*
293292 * Complete outstanding commands with TASK_ABORTED SAM status.
....@@ -311,35 +310,44 @@
311310 * Note that this seems to be independent of TAS (Task Aborted Status)
312311 * in the Control Mode Page.
313312 */
314
- spin_lock_irqsave(&dev->execute_task_lock, flags);
315
- list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) {
316
- /*
317
- * For PREEMPT_AND_ABORT usage, only process commands
318
- * with a matching reservation key.
319
- */
320
- if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
321
- continue;
313
+ for (i = 0; i < dev->queue_cnt; i++) {
314
+ spin_lock_irqsave(&dev->queues[i].lock, flags);
315
+ list_for_each_entry_safe(cmd, next, &dev->queues[i].state_list,
316
+ state_list) {
317
+ /*
318
+ * For PREEMPT_AND_ABORT usage, only process commands
319
+ * with a matching reservation key.
320
+ */
321
+ if (target_check_cdb_and_preempt(preempt_and_abort_list,
322
+ cmd))
323
+ continue;
322324
323
- /*
324
- * Not aborting PROUT PREEMPT_AND_ABORT CDB..
325
- */
326
- if (prout_cmd == cmd)
327
- continue;
325
+ /*
326
+ * Not aborting PROUT PREEMPT_AND_ABORT CDB..
327
+ */
328
+ if (prout_cmd == cmd)
329
+ continue;
328330
329
- sess = cmd->se_sess;
330
- if (WARN_ON_ONCE(!sess))
331
- continue;
331
+ sess = cmd->se_sess;
332
+ if (WARN_ON_ONCE(!sess))
333
+ continue;
332334
333
- spin_lock(&sess->sess_cmd_lock);
334
- rc = __target_check_io_state(cmd, tmr_sess, tas);
335
- spin_unlock(&sess->sess_cmd_lock);
336
- if (!rc)
337
- continue;
335
+ spin_lock(&sess->sess_cmd_lock);
336
+ rc = __target_check_io_state(cmd, tmr_sess, tas);
337
+ spin_unlock(&sess->sess_cmd_lock);
338
+ if (!rc)
339
+ continue;
338340
339
- list_move_tail(&cmd->state_list, &drain_task_list);
340
- cmd->state_active = false;
341
+ list_move_tail(&cmd->state_list, &drain_task_list);
342
+ cmd->state_active = false;
343
+ }
344
+ spin_unlock_irqrestore(&dev->queues[i].lock, flags);
341345 }
342
- spin_unlock_irqrestore(&dev->execute_task_lock, flags);
346
+
347
+ if (dev->transport->tmr_notify)
348
+ dev->transport->tmr_notify(dev, preempt_and_abort_list ?
349
+ TMR_LUN_RESET_PRO : TMR_LUN_RESET,
350
+ &drain_task_list);
343351
344352 while (!list_empty(&drain_task_list)) {
345353 cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
....@@ -350,18 +358,7 @@
350358 cmd->tag, (preempt_and_abort_list) ? "preempt" : "",
351359 cmd->pr_res_key);
352360
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);
361
+ target_put_cmd_and_wait(cmd);
365362 }
366363 }
367364
....@@ -374,7 +371,7 @@
374371 struct se_node_acl *tmr_nacl = NULL;
375372 struct se_portal_group *tmr_tpg = NULL;
376373 struct se_session *tmr_sess = NULL;
377
- int tas;
374
+ bool tas;
378375 /*
379376 * TASK_ABORTED status bit, this is configurable via ConfigFS
380377 * struct se_device attributes. spc4r17 section 7.4.6 Control mode page
....@@ -398,17 +395,28 @@
398395 if (tmr_nacl && tmr_tpg) {
399396 pr_debug("LUN_RESET: TMR caller fabric: %s"
400397 " initiator port %s\n",
401
- tmr_tpg->se_tpg_tfo->get_fabric_name(),
398
+ tmr_tpg->se_tpg_tfo->fabric_name,
402399 tmr_nacl->initiatorname);
403400 }
404401 }
402
+
403
+
404
+ /*
405
+ * We only allow one reset or preempt and abort to execute at a time
406
+ * to prevent one call from claiming all the cmds causing a second
407
+ * call from returning while cmds it should have waited on are still
408
+ * running.
409
+ */
410
+ mutex_lock(&dev->lun_reset_mutex);
411
+
405412 pr_debug("LUN_RESET: %s starting for [%s], tas: %d\n",
406413 (preempt_and_abort_list) ? "Preempt" : "TMR",
407414 dev->transport->name, tas);
408
-
409415 core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
410416 core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
411417 preempt_and_abort_list);
418
+
419
+ mutex_unlock(&dev->lun_reset_mutex);
412420
413421 /*
414422 * Clear any legacy SPC-2 reservation when called during
....@@ -417,7 +425,7 @@
417425 if (!preempt_and_abort_list &&
418426 (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) {
419427 spin_lock(&dev->dev_reservation_lock);
420
- dev->dev_reserved_node_acl = NULL;
428
+ dev->reservation_holder = NULL;
421429 dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
422430 spin_unlock(&dev->dev_reservation_lock);
423431 pr_debug("LUN_RESET: SCSI-2 Released reservation\n");