Skip to content

Commit

Permalink
target: move the state and execute lists to the command
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed May 6, 2012
1 parent 785fdf7 commit cf572a9
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 297 deletions.
5 changes: 2 additions & 3 deletions drivers/target/target_core_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ void release_se_kmem_caches(void);
u32 scsi_get_new_index(scsi_index_t);
void transport_subsystem_check_init(void);
void transport_cmd_finish_abort(struct se_cmd *, int);
void __transport_remove_task_from_execute_queue(struct se_task *,
struct se_device *);
void __target_remove_from_execute_list(struct se_cmd *);
unsigned char *transport_dump_cmd_direction(struct se_cmd *);
void transport_dump_dev_state(struct se_device *, char *, int *);
void transport_dump_dev_info(struct se_device *, struct se_lun *,
Expand All @@ -114,7 +113,7 @@ void transport_dump_vpd_proto_id(struct t10_vpd *, unsigned char *, int);
int transport_dump_vpd_assoc(struct t10_vpd *, unsigned char *, int);
int transport_dump_vpd_ident_type(struct t10_vpd *, unsigned char *, int);
int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int);
bool target_stop_task(struct se_task *task, unsigned long *flags);
bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags);
int transport_clear_lun_from_sessions(struct se_lun *);
void transport_send_task_abort(struct se_cmd *);

Expand Down
54 changes: 23 additions & 31 deletions drivers/target/target_core_tmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,20 +244,21 @@ static void core_tmr_drain_tmr_list(
}
}

static void core_tmr_drain_task_list(
static void core_tmr_drain_state_list(
struct se_device *dev,
struct se_cmd *prout_cmd,
struct se_node_acl *tmr_nacl,
int tas,
struct list_head *preempt_and_abort_list)
{
LIST_HEAD(drain_task_list);
struct se_cmd *cmd;
struct se_task *task, *task_tmp;
struct se_cmd *cmd, *next;
unsigned long flags;
int fe_count;

/*
* Complete outstanding struct se_task CDBs with TASK_ABORTED SAM status.
* Complete outstanding commands with TASK_ABORTED SAM status.
*
* This is following sam4r17, section 5.6 Aborting commands, Table 38
* for TMR LUN_RESET:
*
Expand All @@ -278,45 +279,36 @@ static void core_tmr_drain_task_list(
* in the Control Mode Page.
*/
spin_lock_irqsave(&dev->execute_task_lock, flags);
list_for_each_entry_safe(task, task_tmp, &dev->state_task_list,
t_state_list) {
if (!task->task_se_cmd) {
pr_err("task->task_se_cmd is NULL!\n");
continue;
}
cmd = task->task_se_cmd;

list_for_each_entry_safe(cmd, next, &dev->state_list, state_list) {
/*
* For PREEMPT_AND_ABORT usage, only process commands
* with a matching reservation key.
*/
if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
continue;

/*
* Not aborting PROUT PREEMPT_AND_ABORT CDB..
*/
if (prout_cmd == cmd)
continue;

list_move_tail(&task->t_state_list, &drain_task_list);
task->t_state_active = false;
/*
* Remove from task execute list before processing drain_task_list
*/
if (!list_empty(&task->t_execute_list))
__transport_remove_task_from_execute_queue(task, dev);
list_move_tail(&cmd->state_list, &drain_task_list);
cmd->state_active = false;

if (!list_empty(&cmd->execute_list))
__target_remove_from_execute_list(cmd);
}
spin_unlock_irqrestore(&dev->execute_task_lock, flags);

while (!list_empty(&drain_task_list)) {
task = list_entry(drain_task_list.next, struct se_task, t_state_list);
list_del(&task->t_state_list);
cmd = task->task_se_cmd;
cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
list_del(&cmd->state_list);

pr_debug("LUN_RESET: %s cmd: %p task: %p"
pr_debug("LUN_RESET: %s cmd: %p"
" ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state: %d"
"cdb: 0x%02x\n",
(preempt_and_abort_list) ? "Preempt" : "", cmd, task,
(preempt_and_abort_list) ? "Preempt" : "", cmd,
cmd->se_tfo->get_task_tag(cmd), 0,
cmd->se_tfo->get_cmd_state(cmd), cmd->t_state,
cmd->t_task_cdb[0]);
Expand All @@ -341,29 +333,29 @@ static void core_tmr_drain_task_list(
cancel_work_sync(&cmd->work);

spin_lock_irqsave(&cmd->t_state_lock, flags);
target_stop_task(task, &flags);
target_stop_cmd(cmd, &flags);

if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
pr_debug("LUN_RESET: Skipping task: %p, dev: %p for"
" t_task_cdbs_ex_left: %d\n", task, dev,
pr_debug("LUN_RESET: Skipping cmd: %p, dev: %p for"
" t_task_cdbs_ex_left: %d\n", cmd, dev,
atomic_read(&cmd->t_task_cdbs_ex_left));
continue;
}
fe_count = atomic_read(&cmd->t_fe_count);

if (!(cmd->transport_state & CMD_T_ACTIVE)) {
pr_debug("LUN_RESET: got CMD_T_ACTIVE for"
" task: %p, t_fe_count: %d dev: %p\n", task,
" cdb: %p, t_fe_count: %d dev: %p\n", cmd,
fe_count, dev);
cmd->transport_state |= CMD_T_ABORTED;
spin_unlock_irqrestore(&cmd->t_state_lock, flags);

core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count);
continue;
}
pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for task: %p,"
" t_fe_count: %d dev: %p\n", task, fe_count, dev);
pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for cdb: %p,"
" t_fe_count: %d dev: %p\n", cmd, fe_count, dev);
cmd->transport_state |= CMD_T_ABORTED;
spin_unlock_irqrestore(&cmd->t_state_lock, flags);

Expand Down Expand Up @@ -464,7 +456,7 @@ int core_tmr_lun_reset(
dev->transport->name, tas);

core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
core_tmr_drain_task_list(dev, prout_cmd, tmr_nacl, tas,
core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas,
preempt_and_abort_list);
core_tmr_drain_cmd_list(dev, prout_cmd, tmr_nacl, tas,
preempt_and_abort_list);
Expand Down
Loading

0 comments on commit cf572a9

Please sign in to comment.