diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-04-24 00:25:05 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-05-06 18:11:26 -0400 |
commit | cf572a9627c9ae86082216de109780c1d2e2ee28 (patch) | |
tree | fe6eec75bc3c388534390efe3be2b3b2c4c93903 /drivers | |
parent | 785fdf70b2b46588c973ad8b65ed62871994452f (diff) |
target: move the state and execute lists to the command
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_internal.h | 5 | ||||
-rw-r--r-- | drivers/target/target_core_tmr.c | 54 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 375 |
3 files changed, 152 insertions, 282 deletions
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 1675be4e308c..165e82429687 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -104,8 +104,7 @@ void release_se_kmem_caches(void); | |||
104 | u32 scsi_get_new_index(scsi_index_t); | 104 | u32 scsi_get_new_index(scsi_index_t); |
105 | void transport_subsystem_check_init(void); | 105 | void transport_subsystem_check_init(void); |
106 | void transport_cmd_finish_abort(struct se_cmd *, int); | 106 | void transport_cmd_finish_abort(struct se_cmd *, int); |
107 | void __transport_remove_task_from_execute_queue(struct se_task *, | 107 | void __target_remove_from_execute_list(struct se_cmd *); |
108 | struct se_device *); | ||
109 | unsigned char *transport_dump_cmd_direction(struct se_cmd *); | 108 | unsigned char *transport_dump_cmd_direction(struct se_cmd *); |
110 | void transport_dump_dev_state(struct se_device *, char *, int *); | 109 | void transport_dump_dev_state(struct se_device *, char *, int *); |
111 | void transport_dump_dev_info(struct se_device *, struct se_lun *, | 110 | void transport_dump_dev_info(struct se_device *, struct se_lun *, |
@@ -114,7 +113,7 @@ void transport_dump_vpd_proto_id(struct t10_vpd *, unsigned char *, int); | |||
114 | int transport_dump_vpd_assoc(struct t10_vpd *, unsigned char *, int); | 113 | int transport_dump_vpd_assoc(struct t10_vpd *, unsigned char *, int); |
115 | int transport_dump_vpd_ident_type(struct t10_vpd *, unsigned char *, int); | 114 | int transport_dump_vpd_ident_type(struct t10_vpd *, unsigned char *, int); |
116 | int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); | 115 | int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); |
117 | bool target_stop_task(struct se_task *task, unsigned long *flags); | 116 | bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags); |
118 | int transport_clear_lun_from_sessions(struct se_lun *); | 117 | int transport_clear_lun_from_sessions(struct se_lun *); |
119 | void transport_send_task_abort(struct se_cmd *); | 118 | void transport_send_task_abort(struct se_cmd *); |
120 | 119 | ||
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 98204d06cdf6..e0ffbdc4a486 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -244,7 +244,7 @@ static void core_tmr_drain_tmr_list( | |||
244 | } | 244 | } |
245 | } | 245 | } |
246 | 246 | ||
247 | static void core_tmr_drain_task_list( | 247 | static void core_tmr_drain_state_list( |
248 | struct se_device *dev, | 248 | struct se_device *dev, |
249 | struct se_cmd *prout_cmd, | 249 | struct se_cmd *prout_cmd, |
250 | struct se_node_acl *tmr_nacl, | 250 | struct se_node_acl *tmr_nacl, |
@@ -252,12 +252,13 @@ static void core_tmr_drain_task_list( | |||
252 | struct list_head *preempt_and_abort_list) | 252 | struct list_head *preempt_and_abort_list) |
253 | { | 253 | { |
254 | LIST_HEAD(drain_task_list); | 254 | LIST_HEAD(drain_task_list); |
255 | struct se_cmd *cmd; | 255 | struct se_cmd *cmd, *next; |
256 | struct se_task *task, *task_tmp; | ||
257 | unsigned long flags; | 256 | unsigned long flags; |
258 | int fe_count; | 257 | int fe_count; |
258 | |||
259 | /* | 259 | /* |
260 | * Complete outstanding struct se_task CDBs with TASK_ABORTED SAM status. | 260 | * Complete outstanding commands with TASK_ABORTED SAM status. |
261 | * | ||
261 | * This is following sam4r17, section 5.6 Aborting commands, Table 38 | 262 | * This is following sam4r17, section 5.6 Aborting commands, Table 38 |
262 | * for TMR LUN_RESET: | 263 | * for TMR LUN_RESET: |
263 | * | 264 | * |
@@ -278,45 +279,36 @@ static void core_tmr_drain_task_list( | |||
278 | * in the Control Mode Page. | 279 | * in the Control Mode Page. |
279 | */ | 280 | */ |
280 | spin_lock_irqsave(&dev->execute_task_lock, flags); | 281 | spin_lock_irqsave(&dev->execute_task_lock, flags); |
281 | list_for_each_entry_safe(task, task_tmp, &dev->state_task_list, | 282 | list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) { |
282 | t_state_list) { | ||
283 | if (!task->task_se_cmd) { | ||
284 | pr_err("task->task_se_cmd is NULL!\n"); | ||
285 | continue; | ||
286 | } | ||
287 | cmd = task->task_se_cmd; | ||
288 | |||
289 | /* | 283 | /* |
290 | * For PREEMPT_AND_ABORT usage, only process commands | 284 | * For PREEMPT_AND_ABORT usage, only process commands |
291 | * with a matching reservation key. | 285 | * with a matching reservation key. |
292 | */ | 286 | */ |
293 | if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) | 287 | if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd)) |
294 | continue; | 288 | continue; |
289 | |||
295 | /* | 290 | /* |
296 | * Not aborting PROUT PREEMPT_AND_ABORT CDB.. | 291 | * Not aborting PROUT PREEMPT_AND_ABORT CDB.. |
297 | */ | 292 | */ |
298 | if (prout_cmd == cmd) | 293 | if (prout_cmd == cmd) |
299 | continue; | 294 | continue; |
300 | 295 | ||
301 | list_move_tail(&task->t_state_list, &drain_task_list); | 296 | list_move_tail(&cmd->state_list, &drain_task_list); |
302 | task->t_state_active = false; | 297 | cmd->state_active = false; |
303 | /* | 298 | |
304 | * Remove from task execute list before processing drain_task_list | 299 | if (!list_empty(&cmd->execute_list)) |
305 | */ | 300 | __target_remove_from_execute_list(cmd); |
306 | if (!list_empty(&task->t_execute_list)) | ||
307 | __transport_remove_task_from_execute_queue(task, dev); | ||
308 | } | 301 | } |
309 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | 302 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); |
310 | 303 | ||
311 | while (!list_empty(&drain_task_list)) { | 304 | while (!list_empty(&drain_task_list)) { |
312 | task = list_entry(drain_task_list.next, struct se_task, t_state_list); | 305 | cmd = list_entry(drain_task_list.next, struct se_cmd, state_list); |
313 | list_del(&task->t_state_list); | 306 | list_del(&cmd->state_list); |
314 | cmd = task->task_se_cmd; | ||
315 | 307 | ||
316 | pr_debug("LUN_RESET: %s cmd: %p task: %p" | 308 | pr_debug("LUN_RESET: %s cmd: %p" |
317 | " ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state: %d" | 309 | " ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state: %d" |
318 | "cdb: 0x%02x\n", | 310 | "cdb: 0x%02x\n", |
319 | (preempt_and_abort_list) ? "Preempt" : "", cmd, task, | 311 | (preempt_and_abort_list) ? "Preempt" : "", cmd, |
320 | cmd->se_tfo->get_task_tag(cmd), 0, | 312 | cmd->se_tfo->get_task_tag(cmd), 0, |
321 | cmd->se_tfo->get_cmd_state(cmd), cmd->t_state, | 313 | cmd->se_tfo->get_cmd_state(cmd), cmd->t_state, |
322 | cmd->t_task_cdb[0]); | 314 | cmd->t_task_cdb[0]); |
@@ -341,12 +333,12 @@ static void core_tmr_drain_task_list( | |||
341 | cancel_work_sync(&cmd->work); | 333 | cancel_work_sync(&cmd->work); |
342 | 334 | ||
343 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 335 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
344 | target_stop_task(task, &flags); | 336 | target_stop_cmd(cmd, &flags); |
345 | 337 | ||
346 | if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) { | 338 | if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) { |
347 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 339 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
348 | pr_debug("LUN_RESET: Skipping task: %p, dev: %p for" | 340 | pr_debug("LUN_RESET: Skipping cmd: %p, dev: %p for" |
349 | " t_task_cdbs_ex_left: %d\n", task, dev, | 341 | " t_task_cdbs_ex_left: %d\n", cmd, dev, |
350 | atomic_read(&cmd->t_task_cdbs_ex_left)); | 342 | atomic_read(&cmd->t_task_cdbs_ex_left)); |
351 | continue; | 343 | continue; |
352 | } | 344 | } |
@@ -354,7 +346,7 @@ static void core_tmr_drain_task_list( | |||
354 | 346 | ||
355 | if (!(cmd->transport_state & CMD_T_ACTIVE)) { | 347 | if (!(cmd->transport_state & CMD_T_ACTIVE)) { |
356 | pr_debug("LUN_RESET: got CMD_T_ACTIVE for" | 348 | pr_debug("LUN_RESET: got CMD_T_ACTIVE for" |
357 | " task: %p, t_fe_count: %d dev: %p\n", task, | 349 | " cdb: %p, t_fe_count: %d dev: %p\n", cmd, |
358 | fe_count, dev); | 350 | fe_count, dev); |
359 | cmd->transport_state |= CMD_T_ABORTED; | 351 | cmd->transport_state |= CMD_T_ABORTED; |
360 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 352 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
@@ -362,8 +354,8 @@ static void core_tmr_drain_task_list( | |||
362 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count); | 354 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count); |
363 | continue; | 355 | continue; |
364 | } | 356 | } |
365 | pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for task: %p," | 357 | pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for cdb: %p," |
366 | " t_fe_count: %d dev: %p\n", task, fe_count, dev); | 358 | " t_fe_count: %d dev: %p\n", cmd, fe_count, dev); |
367 | cmd->transport_state |= CMD_T_ABORTED; | 359 | cmd->transport_state |= CMD_T_ABORTED; |
368 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 360 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
369 | 361 | ||
@@ -464,7 +456,7 @@ int core_tmr_lun_reset( | |||
464 | dev->transport->name, tas); | 456 | dev->transport->name, tas); |
465 | 457 | ||
466 | core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); | 458 | core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list); |
467 | core_tmr_drain_task_list(dev, prout_cmd, tmr_nacl, tas, | 459 | core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas, |
468 | preempt_and_abort_list); | 460 | preempt_and_abort_list); |
469 | core_tmr_drain_cmd_list(dev, prout_cmd, tmr_nacl, tas, | 461 | core_tmr_drain_cmd_list(dev, prout_cmd, tmr_nacl, tas, |
470 | preempt_and_abort_list); | 462 | preempt_and_abort_list); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index a2246359e6f4..4ee33954697e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -444,32 +444,24 @@ EXPORT_SYMBOL(transport_deregister_session); | |||
444 | /* | 444 | /* |
445 | * Called with cmd->t_state_lock held. | 445 | * Called with cmd->t_state_lock held. |
446 | */ | 446 | */ |
447 | static void transport_all_task_dev_remove_state(struct se_cmd *cmd) | 447 | static void target_remove_from_state_list(struct se_cmd *cmd) |
448 | { | 448 | { |
449 | struct se_device *dev = cmd->se_dev; | 449 | struct se_device *dev = cmd->se_dev; |
450 | struct se_task *task; | ||
451 | unsigned long flags; | 450 | unsigned long flags; |
452 | 451 | ||
453 | if (!dev) | 452 | if (!dev) |
454 | return; | 453 | return; |
455 | 454 | ||
456 | task = cmd->t_task; | 455 | if (cmd->transport_state & CMD_T_BUSY) |
457 | if (task) { | 456 | return; |
458 | if (task->task_flags & TF_ACTIVE) | ||
459 | return; | ||
460 | |||
461 | spin_lock_irqsave(&dev->execute_task_lock, flags); | ||
462 | if (task->t_state_active) { | ||
463 | pr_debug("Removed ITT: 0x%08x dev: %p task[%p]\n", | ||
464 | cmd->se_tfo->get_task_tag(cmd), dev, task); | ||
465 | 457 | ||
466 | list_del(&task->t_state_list); | 458 | spin_lock_irqsave(&dev->execute_task_lock, flags); |
467 | atomic_dec(&cmd->t_task_cdbs_ex_left); | 459 | if (cmd->state_active) { |
468 | task->t_state_active = false; | 460 | list_del(&cmd->state_list); |
469 | } | 461 | atomic_dec(&cmd->t_task_cdbs_ex_left); |
470 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | 462 | cmd->state_active = false; |
471 | } | 463 | } |
472 | 464 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | |
473 | } | 465 | } |
474 | 466 | ||
475 | /* transport_cmd_check_stop(): | 467 | /* transport_cmd_check_stop(): |
@@ -498,7 +490,7 @@ static int transport_cmd_check_stop( | |||
498 | 490 | ||
499 | cmd->transport_state &= ~CMD_T_ACTIVE; | 491 | cmd->transport_state &= ~CMD_T_ACTIVE; |
500 | if (transport_off == 2) | 492 | if (transport_off == 2) |
501 | transport_all_task_dev_remove_state(cmd); | 493 | target_remove_from_state_list(cmd); |
502 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 494 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
503 | 495 | ||
504 | complete(&cmd->transport_lun_stop_comp); | 496 | complete(&cmd->transport_lun_stop_comp); |
@@ -514,7 +506,7 @@ static int transport_cmd_check_stop( | |||
514 | cmd->se_tfo->get_task_tag(cmd)); | 506 | cmd->se_tfo->get_task_tag(cmd)); |
515 | 507 | ||
516 | if (transport_off == 2) | 508 | if (transport_off == 2) |
517 | transport_all_task_dev_remove_state(cmd); | 509 | target_remove_from_state_list(cmd); |
518 | 510 | ||
519 | /* | 511 | /* |
520 | * Clear struct se_cmd->se_lun before the transport_off == 2 handoff | 512 | * Clear struct se_cmd->se_lun before the transport_off == 2 handoff |
@@ -530,7 +522,7 @@ static int transport_cmd_check_stop( | |||
530 | if (transport_off) { | 522 | if (transport_off) { |
531 | cmd->transport_state &= ~CMD_T_ACTIVE; | 523 | cmd->transport_state &= ~CMD_T_ACTIVE; |
532 | if (transport_off == 2) { | 524 | if (transport_off == 2) { |
533 | transport_all_task_dev_remove_state(cmd); | 525 | target_remove_from_state_list(cmd); |
534 | /* | 526 | /* |
535 | * Clear struct se_cmd->se_lun before the transport_off == 2 | 527 | * Clear struct se_cmd->se_lun before the transport_off == 2 |
536 | * handoff to fabric module. | 528 | * handoff to fabric module. |
@@ -578,7 +570,7 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) | |||
578 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 570 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
579 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | 571 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { |
580 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; | 572 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; |
581 | transport_all_task_dev_remove_state(cmd); | 573 | target_remove_from_state_list(cmd); |
582 | } | 574 | } |
583 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 575 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
584 | 576 | ||
@@ -711,7 +703,7 @@ void transport_complete_task(struct se_task *task, int success) | |||
711 | unsigned long flags; | 703 | unsigned long flags; |
712 | 704 | ||
713 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 705 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
714 | task->task_flags &= ~TF_ACTIVE; | 706 | cmd->transport_state &= ~CMD_T_BUSY; |
715 | 707 | ||
716 | /* | 708 | /* |
717 | * See if any sense data exists, if so set the TASK_SENSE flag. | 709 | * See if any sense data exists, if so set the TASK_SENSE flag. |
@@ -721,7 +713,6 @@ void transport_complete_task(struct se_task *task, int success) | |||
721 | if (dev && dev->transport->transport_complete) { | 713 | if (dev && dev->transport->transport_complete) { |
722 | if (dev->transport->transport_complete(task) != 0) { | 714 | if (dev->transport->transport_complete(task) != 0) { |
723 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | 715 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; |
724 | task->task_flags |= TF_HAS_SENSE; | ||
725 | success = 1; | 716 | success = 1; |
726 | } | 717 | } |
727 | } | 718 | } |
@@ -730,9 +721,9 @@ void transport_complete_task(struct se_task *task, int success) | |||
730 | * See if we are waiting for outstanding struct se_task | 721 | * See if we are waiting for outstanding struct se_task |
731 | * to complete for an exception condition | 722 | * to complete for an exception condition |
732 | */ | 723 | */ |
733 | if (task->task_flags & TF_REQUEST_STOP) { | 724 | if (cmd->transport_state & CMD_T_REQUEST_STOP) { |
734 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 725 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
735 | complete(&task->task_stop_comp); | 726 | complete(&cmd->task_stop_comp); |
736 | return; | 727 | return; |
737 | } | 728 | } |
738 | 729 | ||
@@ -781,144 +772,75 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
781 | } | 772 | } |
782 | EXPORT_SYMBOL(target_complete_cmd); | 773 | EXPORT_SYMBOL(target_complete_cmd); |
783 | 774 | ||
784 | /* | 775 | static void target_add_to_state_list(struct se_cmd *cmd) |
785 | * Called by transport_add_tasks_from_cmd() once a struct se_cmd's | ||
786 | * struct se_task list are ready to be added to the active execution list | ||
787 | * struct se_device | ||
788 | |||
789 | * Called with se_dev_t->execute_task_lock called. | ||
790 | */ | ||
791 | static inline int transport_add_task_check_sam_attr( | ||
792 | struct se_task *task, | ||
793 | struct se_device *dev) | ||
794 | { | 776 | { |
795 | /* | 777 | struct se_device *dev = cmd->se_dev; |
796 | * No SAM Task attribute emulation enabled, add to tail of | 778 | unsigned long flags; |
797 | * execution queue | ||
798 | */ | ||
799 | if (dev->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) { | ||
800 | list_add_tail(&task->t_execute_list, &dev->execute_task_list); | ||
801 | return 0; | ||
802 | } | ||
803 | /* | ||
804 | * HEAD_OF_QUEUE attribute for received CDB, which means | ||
805 | * the first task that is associated with a struct se_cmd goes to | ||
806 | * head of the struct se_device->execute_task_list. | ||
807 | */ | ||
808 | if (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG) { | ||
809 | list_add(&task->t_execute_list, &dev->execute_task_list); | ||
810 | 779 | ||
811 | pr_debug("Set HEAD_OF_QUEUE for task CDB: 0x%02x" | 780 | spin_lock_irqsave(&dev->execute_task_lock, flags); |
812 | " in execution queue\n", | 781 | if (!cmd->state_active) { |
813 | task->task_se_cmd->t_task_cdb[0]); | 782 | list_add_tail(&cmd->state_list, &dev->state_list); |
814 | return 1; | 783 | cmd->state_active = true; |
815 | } | 784 | } |
816 | /* | 785 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); |
817 | * For ORDERED, SIMPLE or UNTAGGED attribute tasks once they have been | ||
818 | * transitioned from Dermant -> Active state, and are added to the end | ||
819 | * of the struct se_device->execute_task_list | ||
820 | */ | ||
821 | list_add_tail(&task->t_execute_list, &dev->execute_task_list); | ||
822 | return 0; | ||
823 | } | 786 | } |
824 | 787 | ||
825 | /* __transport_add_task_to_execute_queue(): | 788 | static void __target_add_to_execute_list(struct se_cmd *cmd) |
826 | * | ||
827 | * Called with se_dev_t->execute_task_lock called. | ||
828 | */ | ||
829 | static void __transport_add_task_to_execute_queue( | ||
830 | struct se_task *task, | ||
831 | struct se_device *dev) | ||
832 | { | 789 | { |
833 | int head_of_queue; | 790 | struct se_device *dev = cmd->se_dev; |
834 | 791 | bool head_of_queue = false; | |
835 | head_of_queue = transport_add_task_check_sam_attr(task, dev); | ||
836 | atomic_inc(&dev->execute_tasks); | ||
837 | 792 | ||
838 | if (task->t_state_active) | 793 | if (!list_empty(&cmd->execute_list)) |
839 | return; | 794 | return; |
840 | /* | ||
841 | * Determine if this task needs to go to HEAD_OF_QUEUE for the | ||
842 | * state list as well. Running with SAM Task Attribute emulation | ||
843 | * will always return head_of_queue == 0 here | ||
844 | */ | ||
845 | if (head_of_queue) | ||
846 | list_add(&task->t_state_list, &dev->state_task_list); | ||
847 | else | ||
848 | list_add_tail(&task->t_state_list, &dev->state_task_list); | ||
849 | 795 | ||
850 | task->t_state_active = true; | 796 | if (dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED && |
797 | cmd->sam_task_attr == MSG_HEAD_TAG) | ||
798 | head_of_queue = true; | ||
851 | 799 | ||
852 | pr_debug("Added ITT: 0x%08x task[%p] to dev: %p\n", | 800 | if (head_of_queue) |
853 | task->task_se_cmd->se_tfo->get_task_tag(task->task_se_cmd), | 801 | list_add(&cmd->execute_list, &dev->execute_list); |
854 | task, dev); | 802 | else |
855 | } | 803 | list_add_tail(&cmd->execute_list, &dev->execute_list); |
856 | |||
857 | static void transport_add_tasks_to_state_queue(struct se_cmd *cmd) | ||
858 | { | ||
859 | struct se_device *dev = cmd->se_dev; | ||
860 | struct se_task *task; | ||
861 | unsigned long flags; | ||
862 | |||
863 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
864 | task = cmd->t_task; | ||
865 | if (task) { | ||
866 | if (task->task_flags & TF_ACTIVE) | ||
867 | goto out; | ||
868 | 804 | ||
869 | spin_lock(&dev->execute_task_lock); | 805 | atomic_inc(&dev->execute_tasks); |
870 | if (!task->t_state_active) { | ||
871 | list_add_tail(&task->t_state_list, | ||
872 | &dev->state_task_list); | ||
873 | task->t_state_active = true; | ||
874 | 806 | ||
875 | pr_debug("Added ITT: 0x%08x task[%p] to dev: %p\n", | 807 | if (cmd->state_active) |
876 | task->task_se_cmd->se_tfo->get_task_tag( | 808 | return; |
877 | task->task_se_cmd), task, dev); | ||
878 | } | ||
879 | spin_unlock(&dev->execute_task_lock); | ||
880 | } | ||
881 | out: | ||
882 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
883 | } | ||
884 | 809 | ||
885 | static void __transport_add_tasks_from_cmd(struct se_cmd *cmd) | 810 | if (head_of_queue) |
886 | { | 811 | list_add(&cmd->state_list, &dev->state_list); |
887 | struct se_task *task; | 812 | else |
813 | list_add_tail(&cmd->state_list, &dev->state_list); | ||
888 | 814 | ||
889 | task = cmd->t_task; | 815 | cmd->state_active = true; |
890 | if (task && list_empty(&task->t_execute_list)) | ||
891 | __transport_add_task_to_execute_queue(task, cmd->se_dev); | ||
892 | } | 816 | } |
893 | 817 | ||
894 | static void transport_add_tasks_from_cmd(struct se_cmd *cmd) | 818 | static void target_add_to_execute_list(struct se_cmd *cmd) |
895 | { | 819 | { |
896 | unsigned long flags; | 820 | unsigned long flags; |
897 | struct se_device *dev = cmd->se_dev; | 821 | struct se_device *dev = cmd->se_dev; |
898 | 822 | ||
899 | spin_lock_irqsave(&dev->execute_task_lock, flags); | 823 | spin_lock_irqsave(&dev->execute_task_lock, flags); |
900 | __transport_add_tasks_from_cmd(cmd); | 824 | __target_add_to_execute_list(cmd); |
901 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | 825 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); |
902 | } | 826 | } |
903 | 827 | ||
904 | void __transport_remove_task_from_execute_queue(struct se_task *task, | 828 | void __target_remove_from_execute_list(struct se_cmd *cmd) |
905 | struct se_device *dev) | ||
906 | { | 829 | { |
907 | list_del_init(&task->t_execute_list); | 830 | list_del_init(&cmd->execute_list); |
908 | atomic_dec(&dev->execute_tasks); | 831 | atomic_dec(&cmd->se_dev->execute_tasks); |
909 | } | 832 | } |
910 | 833 | ||
911 | static void transport_remove_task_from_execute_queue( | 834 | static void target_remove_from_execute_list(struct se_cmd *cmd) |
912 | struct se_task *task, | ||
913 | struct se_device *dev) | ||
914 | { | 835 | { |
836 | struct se_device *dev = cmd->se_dev; | ||
915 | unsigned long flags; | 837 | unsigned long flags; |
916 | 838 | ||
917 | if (WARN_ON(list_empty(&task->t_execute_list))) | 839 | if (WARN_ON(list_empty(&cmd->execute_list))) |
918 | return; | 840 | return; |
919 | 841 | ||
920 | spin_lock_irqsave(&dev->execute_task_lock, flags); | 842 | spin_lock_irqsave(&dev->execute_task_lock, flags); |
921 | __transport_remove_task_from_execute_queue(task, dev); | 843 | __target_remove_from_execute_list(cmd); |
922 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); | 844 | spin_unlock_irqrestore(&dev->execute_task_lock, flags); |
923 | } | 845 | } |
924 | 846 | ||
@@ -1342,9 +1264,9 @@ struct se_device *transport_add_device_to_core_hba( | |||
1342 | INIT_LIST_HEAD(&dev->dev_list); | 1264 | INIT_LIST_HEAD(&dev->dev_list); |
1343 | INIT_LIST_HEAD(&dev->dev_sep_list); | 1265 | INIT_LIST_HEAD(&dev->dev_sep_list); |
1344 | INIT_LIST_HEAD(&dev->dev_tmr_list); | 1266 | INIT_LIST_HEAD(&dev->dev_tmr_list); |
1345 | INIT_LIST_HEAD(&dev->execute_task_list); | 1267 | INIT_LIST_HEAD(&dev->execute_list); |
1346 | INIT_LIST_HEAD(&dev->delayed_cmd_list); | 1268 | INIT_LIST_HEAD(&dev->delayed_cmd_list); |
1347 | INIT_LIST_HEAD(&dev->state_task_list); | 1269 | INIT_LIST_HEAD(&dev->state_list); |
1348 | INIT_LIST_HEAD(&dev->qf_cmd_list); | 1270 | INIT_LIST_HEAD(&dev->qf_cmd_list); |
1349 | spin_lock_init(&dev->execute_task_lock); | 1271 | spin_lock_init(&dev->execute_task_lock); |
1350 | spin_lock_init(&dev->delayed_cmd_lock); | 1272 | spin_lock_init(&dev->delayed_cmd_lock); |
@@ -1482,10 +1404,13 @@ void transport_init_se_cmd( | |||
1482 | INIT_LIST_HEAD(&cmd->se_qf_node); | 1404 | INIT_LIST_HEAD(&cmd->se_qf_node); |
1483 | INIT_LIST_HEAD(&cmd->se_queue_node); | 1405 | INIT_LIST_HEAD(&cmd->se_queue_node); |
1484 | INIT_LIST_HEAD(&cmd->se_cmd_list); | 1406 | INIT_LIST_HEAD(&cmd->se_cmd_list); |
1407 | INIT_LIST_HEAD(&cmd->execute_list); | ||
1408 | INIT_LIST_HEAD(&cmd->state_list); | ||
1485 | init_completion(&cmd->transport_lun_fe_stop_comp); | 1409 | init_completion(&cmd->transport_lun_fe_stop_comp); |
1486 | init_completion(&cmd->transport_lun_stop_comp); | 1410 | init_completion(&cmd->transport_lun_stop_comp); |
1487 | init_completion(&cmd->t_transport_stop_comp); | 1411 | init_completion(&cmd->t_transport_stop_comp); |
1488 | init_completion(&cmd->cmd_wait_comp); | 1412 | init_completion(&cmd->cmd_wait_comp); |
1413 | init_completion(&cmd->task_stop_comp); | ||
1489 | spin_lock_init(&cmd->t_state_lock); | 1414 | spin_lock_init(&cmd->t_state_lock); |
1490 | cmd->transport_state = CMD_T_DEV_ACTIVE; | 1415 | cmd->transport_state = CMD_T_DEV_ACTIVE; |
1491 | 1416 | ||
@@ -1495,6 +1420,8 @@ void transport_init_se_cmd( | |||
1495 | cmd->data_direction = data_direction; | 1420 | cmd->data_direction = data_direction; |
1496 | cmd->sam_task_attr = task_attr; | 1421 | cmd->sam_task_attr = task_attr; |
1497 | cmd->sense_buffer = sense_buffer; | 1422 | cmd->sense_buffer = sense_buffer; |
1423 | |||
1424 | cmd->state_active = false; | ||
1498 | } | 1425 | } |
1499 | EXPORT_SYMBOL(transport_init_se_cmd); | 1426 | EXPORT_SYMBOL(transport_init_se_cmd); |
1500 | 1427 | ||
@@ -1855,72 +1782,31 @@ int transport_generic_handle_tmr( | |||
1855 | EXPORT_SYMBOL(transport_generic_handle_tmr); | 1782 | EXPORT_SYMBOL(transport_generic_handle_tmr); |
1856 | 1783 | ||
1857 | /* | 1784 | /* |
1858 | * If the task is active, request it to be stopped and sleep until it | 1785 | * If the cmd is active, request it to be stopped and sleep until it |
1859 | * has completed. | 1786 | * has completed. |
1860 | */ | 1787 | */ |
1861 | bool target_stop_task(struct se_task *task, unsigned long *flags) | 1788 | bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) |
1862 | { | 1789 | { |
1863 | struct se_cmd *cmd = task->task_se_cmd; | ||
1864 | bool was_active = false; | 1790 | bool was_active = false; |
1865 | 1791 | ||
1866 | if (task->task_flags & TF_ACTIVE) { | 1792 | if (cmd->transport_state & CMD_T_BUSY) { |
1867 | task->task_flags |= TF_REQUEST_STOP; | 1793 | cmd->transport_state |= CMD_T_REQUEST_STOP; |
1868 | spin_unlock_irqrestore(&cmd->t_state_lock, *flags); | 1794 | spin_unlock_irqrestore(&cmd->t_state_lock, *flags); |
1869 | 1795 | ||
1870 | pr_debug("Task %p waiting to complete\n", task); | 1796 | pr_debug("cmd %p waiting to complete\n", cmd); |
1871 | wait_for_completion(&task->task_stop_comp); | 1797 | wait_for_completion(&cmd->task_stop_comp); |
1872 | pr_debug("Task %p stopped successfully\n", task); | 1798 | pr_debug("cmd %p stopped successfully\n", cmd); |
1873 | 1799 | ||
1874 | spin_lock_irqsave(&cmd->t_state_lock, *flags); | 1800 | spin_lock_irqsave(&cmd->t_state_lock, *flags); |
1875 | atomic_dec(&cmd->t_task_cdbs_left); | 1801 | atomic_dec(&cmd->t_task_cdbs_left); |
1876 | task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP); | 1802 | cmd->transport_state &= ~CMD_T_REQUEST_STOP; |
1803 | cmd->transport_state &= ~CMD_T_BUSY; | ||
1877 | was_active = true; | 1804 | was_active = true; |
1878 | } | 1805 | } |
1879 | 1806 | ||
1880 | return was_active; | 1807 | return was_active; |
1881 | } | 1808 | } |
1882 | 1809 | ||
1883 | static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) | ||
1884 | { | ||
1885 | struct se_task *task; | ||
1886 | unsigned long flags; | ||
1887 | int ret = 0; | ||
1888 | |||
1889 | pr_debug("ITT[0x%08x] - Stopping tasks\n", | ||
1890 | cmd->se_tfo->get_task_tag(cmd)); | ||
1891 | |||
1892 | /* | ||
1893 | * No tasks remain in the execution queue | ||
1894 | */ | ||
1895 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1896 | task = cmd->t_task; | ||
1897 | if (task) { | ||
1898 | pr_debug("Processing task %p\n", task); | ||
1899 | /* | ||
1900 | * If the struct se_task has not been sent and is not active, | ||
1901 | * remove the struct se_task from the execution queue. | ||
1902 | */ | ||
1903 | if (!(task->task_flags & (TF_ACTIVE | TF_SENT))) { | ||
1904 | spin_unlock_irqrestore(&cmd->t_state_lock, | ||
1905 | flags); | ||
1906 | transport_remove_task_from_execute_queue(task, | ||
1907 | cmd->se_dev); | ||
1908 | |||
1909 | pr_debug("Task %p removed from execute queue\n", task); | ||
1910 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1911 | goto out; | ||
1912 | } | ||
1913 | |||
1914 | if (!target_stop_task(task, &flags)) { | ||
1915 | pr_debug("Task %p - did nothing\n", task); | ||
1916 | ret++; | ||
1917 | } | ||
1918 | } | ||
1919 | out: | ||
1920 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1921 | return ret; | ||
1922 | } | ||
1923 | |||
1924 | /* | 1810 | /* |
1925 | * Handle SAM-esque emulation for generic transport request failures. | 1811 | * Handle SAM-esque emulation for generic transport request failures. |
1926 | */ | 1812 | */ |
@@ -2153,11 +2039,7 @@ static int transport_execute_tasks(struct se_cmd *cmd) | |||
2153 | add_tasks = transport_execute_task_attr(cmd); | 2039 | add_tasks = transport_execute_task_attr(cmd); |
2154 | if (!add_tasks) | 2040 | if (!add_tasks) |
2155 | goto execute_tasks; | 2041 | goto execute_tasks; |
2156 | /* | 2042 | |
2157 | * __transport_execute_tasks() -> __transport_add_tasks_from_cmd() | ||
2158 | * adds associated se_tasks while holding dev->execute_task_lock | ||
2159 | * before I/O dispath to avoid a double spinlock access. | ||
2160 | */ | ||
2161 | __transport_execute_tasks(se_dev, cmd); | 2043 | __transport_execute_tasks(se_dev, cmd); |
2162 | return 0; | 2044 | return 0; |
2163 | } | 2045 | } |
@@ -2167,36 +2049,27 @@ execute_tasks: | |||
2167 | return 0; | 2049 | return 0; |
2168 | } | 2050 | } |
2169 | 2051 | ||
2170 | /* | ||
2171 | * Called to check struct se_device tcq depth window, and once open pull struct se_task | ||
2172 | * from struct se_device->execute_task_list and | ||
2173 | * | ||
2174 | * Called from transport_processing_thread() | ||
2175 | */ | ||
2176 | static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *new_cmd) | 2052 | static int __transport_execute_tasks(struct se_device *dev, struct se_cmd *new_cmd) |
2177 | { | 2053 | { |
2178 | int error; | 2054 | int error; |
2179 | struct se_cmd *cmd = NULL; | 2055 | struct se_cmd *cmd = NULL; |
2180 | struct se_task *task = NULL; | ||
2181 | unsigned long flags; | 2056 | unsigned long flags; |
2182 | 2057 | ||
2183 | check_depth: | 2058 | check_depth: |
2184 | spin_lock_irq(&dev->execute_task_lock); | 2059 | spin_lock_irq(&dev->execute_task_lock); |
2185 | if (new_cmd != NULL) | 2060 | if (new_cmd != NULL) |
2186 | __transport_add_tasks_from_cmd(new_cmd); | 2061 | __target_add_to_execute_list(new_cmd); |
2187 | 2062 | ||
2188 | if (list_empty(&dev->execute_task_list)) { | 2063 | if (list_empty(&dev->execute_list)) { |
2189 | spin_unlock_irq(&dev->execute_task_lock); | 2064 | spin_unlock_irq(&dev->execute_task_lock); |
2190 | return 0; | 2065 | return 0; |
2191 | } | 2066 | } |
2192 | task = list_first_entry(&dev->execute_task_list, | 2067 | cmd = list_first_entry(&dev->execute_list, struct se_cmd, execute_list); |
2193 | struct se_task, t_execute_list); | 2068 | __target_remove_from_execute_list(cmd); |
2194 | __transport_remove_task_from_execute_queue(task, dev); | ||
2195 | spin_unlock_irq(&dev->execute_task_lock); | 2069 | spin_unlock_irq(&dev->execute_task_lock); |
2196 | 2070 | ||
2197 | cmd = task->task_se_cmd; | ||
2198 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2071 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2199 | task->task_flags |= (TF_ACTIVE | TF_SENT); | 2072 | cmd->transport_state |= CMD_T_BUSY; |
2200 | cmd->transport_state |= CMD_T_SENT; | 2073 | cmd->transport_state |= CMD_T_SENT; |
2201 | 2074 | ||
2202 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2075 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
@@ -2204,14 +2077,14 @@ check_depth: | |||
2204 | if (cmd->execute_cmd) | 2077 | if (cmd->execute_cmd) |
2205 | error = cmd->execute_cmd(cmd); | 2078 | error = cmd->execute_cmd(cmd); |
2206 | else | 2079 | else |
2207 | error = dev->transport->do_task(task); | 2080 | error = dev->transport->do_task(cmd->t_task); |
2081 | |||
2208 | if (error != 0) { | 2082 | if (error != 0) { |
2209 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2083 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2210 | task->task_flags &= ~TF_ACTIVE; | 2084 | cmd->transport_state &= ~CMD_T_BUSY; |
2211 | cmd->transport_state &= ~CMD_T_SENT; | 2085 | cmd->transport_state &= ~CMD_T_SENT; |
2212 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2086 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2213 | 2087 | ||
2214 | transport_stop_tasks_for_cmd(cmd); | ||
2215 | transport_generic_request_failure(cmd); | 2088 | transport_generic_request_failure(cmd); |
2216 | } | 2089 | } |
2217 | 2090 | ||
@@ -2454,42 +2327,38 @@ static int transport_get_sense_data(struct se_cmd *cmd) | |||
2454 | return 0; | 2327 | return 0; |
2455 | } | 2328 | } |
2456 | 2329 | ||
2457 | task = cmd->t_task; | 2330 | if (!cmd->t_task) |
2458 | if (task) { | 2331 | goto out; |
2459 | if (!(task->task_flags & TF_HAS_SENSE)) | ||
2460 | goto out; | ||
2461 | |||
2462 | if (!dev->transport->get_sense_buffer) { | ||
2463 | pr_err("dev->transport->get_sense_buffer" | ||
2464 | " is NULL\n"); | ||
2465 | goto out; | ||
2466 | } | ||
2467 | 2332 | ||
2468 | sense_buffer = dev->transport->get_sense_buffer(task); | 2333 | if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) |
2469 | if (!sense_buffer) { | 2334 | goto out; |
2470 | pr_err("ITT[0x%08x]_TASK[%p]: Unable to locate" | ||
2471 | " sense buffer for task with sense\n", | ||
2472 | cmd->se_tfo->get_task_tag(cmd), task); | ||
2473 | goto out; | ||
2474 | } | ||
2475 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
2476 | 2335 | ||
2477 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, | 2336 | if (!dev->transport->get_sense_buffer) { |
2478 | TRANSPORT_SENSE_BUFFER); | 2337 | pr_err("dev->transport->get_sense_buffer is NULL\n"); |
2338 | goto out; | ||
2339 | } | ||
2479 | 2340 | ||
2480 | memcpy(&buffer[offset], sense_buffer, | 2341 | sense_buffer = dev->transport->get_sense_buffer(task); |
2481 | TRANSPORT_SENSE_BUFFER); | 2342 | if (!sense_buffer) { |
2482 | cmd->scsi_status = task->task_scsi_status; | 2343 | pr_err("ITT[0x%08x]_TASK[%p]: Unable to locate" |
2483 | /* Automatically padded */ | 2344 | " sense buffer for task with sense\n", |
2484 | cmd->scsi_sense_length = | 2345 | cmd->se_tfo->get_task_tag(cmd), task); |
2485 | (TRANSPORT_SENSE_BUFFER + offset); | 2346 | goto out; |
2486 | |||
2487 | pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x" | ||
2488 | " and sense\n", | ||
2489 | dev->se_hba->hba_id, dev->transport->name, | ||
2490 | cmd->scsi_status); | ||
2491 | return 0; | ||
2492 | } | 2347 | } |
2348 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
2349 | |||
2350 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
2351 | |||
2352 | memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); | ||
2353 | cmd->scsi_status = task->task_scsi_status; | ||
2354 | |||
2355 | /* Automatically padded */ | ||
2356 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
2357 | |||
2358 | pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", | ||
2359 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
2360 | return 0; | ||
2361 | |||
2493 | out: | 2362 | out: |
2494 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2363 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2495 | return -1; | 2364 | return -1; |
@@ -3234,7 +3103,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
3234 | cmd_p->t_task_cdb[0], | 3103 | cmd_p->t_task_cdb[0], |
3235 | cmd_p->sam_task_attr, cmd_p->se_ordered_id); | 3104 | cmd_p->sam_task_attr, cmd_p->se_ordered_id); |
3236 | 3105 | ||
3237 | transport_add_tasks_from_cmd(cmd_p); | 3106 | target_add_to_execute_list(cmd_p); |
3238 | new_active_tasks++; | 3107 | new_active_tasks++; |
3239 | 3108 | ||
3240 | spin_lock(&dev->delayed_cmd_lock); | 3109 | spin_lock(&dev->delayed_cmd_lock); |
@@ -3413,7 +3282,7 @@ static void transport_free_dev_tasks(struct se_cmd *cmd) | |||
3413 | struct se_task *task; | 3282 | struct se_task *task; |
3414 | 3283 | ||
3415 | task = cmd->t_task; | 3284 | task = cmd->t_task; |
3416 | if (task && !(task->task_flags & TF_ACTIVE)) | 3285 | if (task && !(cmd->transport_state & CMD_T_BUSY)) |
3417 | cmd->se_dev->transport->free_task(task); | 3286 | cmd->se_dev->transport->free_task(task); |
3418 | } | 3287 | } |
3419 | 3288 | ||
@@ -3492,7 +3361,7 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
3492 | 3361 | ||
3493 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | 3362 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { |
3494 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; | 3363 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; |
3495 | transport_all_task_dev_remove_state(cmd); | 3364 | target_remove_from_state_list(cmd); |
3496 | free_tasks = 1; | 3365 | free_tasks = 1; |
3497 | } | 3366 | } |
3498 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 3367 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
@@ -3709,9 +3578,6 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3709 | goto out_fail; | 3578 | goto out_fail; |
3710 | } | 3579 | } |
3711 | 3580 | ||
3712 | INIT_LIST_HEAD(&task->t_execute_list); | ||
3713 | INIT_LIST_HEAD(&task->t_state_list); | ||
3714 | init_completion(&task->task_stop_comp); | ||
3715 | task->task_se_cmd = cmd; | 3581 | task->task_se_cmd = cmd; |
3716 | task->task_data_direction = cmd->data_direction; | 3582 | task->task_data_direction = cmd->data_direction; |
3717 | task->task_sg = cmd->t_data_sg; | 3583 | task->task_sg = cmd->t_data_sg; |
@@ -3733,7 +3599,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3733 | * thread a second time) | 3599 | * thread a second time) |
3734 | */ | 3600 | */ |
3735 | if (cmd->data_direction == DMA_TO_DEVICE) { | 3601 | if (cmd->data_direction == DMA_TO_DEVICE) { |
3736 | transport_add_tasks_to_state_queue(cmd); | 3602 | target_add_to_state_list(cmd); |
3737 | return transport_generic_write_pending(cmd); | 3603 | return transport_generic_write_pending(cmd); |
3738 | } | 3604 | } |
3739 | /* | 3605 | /* |
@@ -3966,8 +3832,10 @@ EXPORT_SYMBOL(target_wait_for_sess_cmds); | |||
3966 | */ | 3832 | */ |
3967 | static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) | 3833 | static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) |
3968 | { | 3834 | { |
3835 | struct se_task *task = cmd->t_task; | ||
3969 | unsigned long flags; | 3836 | unsigned long flags; |
3970 | int ret; | 3837 | int ret = 0; |
3838 | |||
3971 | /* | 3839 | /* |
3972 | * If the frontend has already requested this struct se_cmd to | 3840 | * If the frontend has already requested this struct se_cmd to |
3973 | * be stopped, we can safely ignore this struct se_cmd. | 3841 | * be stopped, we can safely ignore this struct se_cmd. |
@@ -3987,7 +3855,18 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun) | |||
3987 | 3855 | ||
3988 | wake_up_interruptible(&cmd->se_dev->dev_queue_obj.thread_wq); | 3856 | wake_up_interruptible(&cmd->se_dev->dev_queue_obj.thread_wq); |
3989 | 3857 | ||
3990 | ret = transport_stop_tasks_for_cmd(cmd); | 3858 | // XXX: audit task_flags checks. |
3859 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
3860 | if ((cmd->transport_state & CMD_T_BUSY) && | ||
3861 | (cmd->transport_state & CMD_T_SENT)) { | ||
3862 | if (!target_stop_cmd(cmd, &flags)) | ||
3863 | ret++; | ||
3864 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
3865 | } else { | ||
3866 | spin_unlock_irqrestore(&cmd->t_state_lock, | ||
3867 | flags); | ||
3868 | target_remove_from_execute_list(cmd); | ||
3869 | } | ||
3991 | 3870 | ||
3992 | pr_debug("ConfigFS: cmd: %p stop tasks ret:" | 3871 | pr_debug("ConfigFS: cmd: %p stop tasks ret:" |
3993 | " %d\n", cmd, ret); | 3872 | " %d\n", cmd, ret); |
@@ -4062,7 +3941,7 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun) | |||
4062 | goto check_cond; | 3941 | goto check_cond; |
4063 | } | 3942 | } |
4064 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; | 3943 | cmd->transport_state &= ~CMD_T_DEV_ACTIVE; |
4065 | transport_all_task_dev_remove_state(cmd); | 3944 | target_remove_from_state_list(cmd); |
4066 | spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags); | 3945 | spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags); |
4067 | 3946 | ||
4068 | transport_free_dev_tasks(cmd); | 3947 | transport_free_dev_tasks(cmd); |
@@ -4178,7 +4057,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) | |||
4178 | wait_for_completion(&cmd->transport_lun_fe_stop_comp); | 4057 | wait_for_completion(&cmd->transport_lun_fe_stop_comp); |
4179 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 4058 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
4180 | 4059 | ||
4181 | transport_all_task_dev_remove_state(cmd); | 4060 | target_remove_from_state_list(cmd); |
4182 | /* | 4061 | /* |
4183 | * At this point, the frontend who was the originator of this | 4062 | * At this point, the frontend who was the originator of this |
4184 | * struct se_cmd, now owns the structure and can be released through | 4063 | * struct se_cmd, now owns the structure and can be released through |
@@ -4599,7 +4478,7 @@ get_cmd: | |||
4599 | } | 4478 | } |
4600 | 4479 | ||
4601 | out: | 4480 | out: |
4602 | WARN_ON(!list_empty(&dev->state_task_list)); | 4481 | WARN_ON(!list_empty(&dev->state_list)); |
4603 | WARN_ON(!list_empty(&dev->dev_queue_obj.qobj_list)); | 4482 | WARN_ON(!list_empty(&dev->dev_queue_obj.qobj_list)); |
4604 | dev->process_thread = NULL; | 4483 | dev->process_thread = NULL; |
4605 | return 0; | 4484 | return 0; |