From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> This patch converts se_cmd->transport_wait_for_tasks(se_cmd, 1) usage to use transport_generic_free_cmd() directly in target-core and iscsi-target fabric usage. The includes: *) Removal of the optional transport_generic_free_cmd() call from within transport_generic_wait_for_tasks() *) Usage of existing SCF_SUPPORTED_SAM_OPCODE to determine when transport_generic_wait_for_tasks() processing may occur instead of checking se_cmd->transport_wait_for_tasks() *) Move transport_generic_wait_for_tasks() call ahead of core_dec_lacl_count() and transport_lun_remove_cmd() in transport_generic_free_cmd() to follow existing logic for iscsi-target w/ se_cmd->transport_wait_for_tasks(se_cmd, 1) *) Removal of se_cmd->transport_wait_for_tasks() function pointer *) Add EXPORT_SYMBOL for transport_generic_wait_for_tasks() For the case in iscsi_target_erl2.c:iscsit_prepare_cmds_for_realligance() where se_cmd->transport_wait_for_tasks(se_cmd, 0) is called, this patch adds a direct call to transport_generic_wait_for_tasks(). Reported-by: Christoph Hellwig <hch@xxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> --- drivers/target/iscsi/iscsi_target.c | 12 +---- drivers/target/iscsi/iscsi_target_erl2.c | 41 ++++++------------ drivers/target/target_core_transport.c | 65 ++++++++++-------------------- include/target/target_core_base.h | 1 - include/target/target_core_transport.h | 1 + 5 files changed, 39 insertions(+), 81 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 354a833..6751e59 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3940,7 +3940,6 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) { struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL; struct iscsi_session *sess = conn->sess; - struct se_cmd *se_cmd; /* * We expect this function to only ever be called from either RX or TX * thread context via iscsit_close_connection() once the other context @@ -3953,16 +3952,13 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); iscsit_increment_maxcmdsn(cmd, sess); - se_cmd = &cmd->se_cmd; /* * Special cases for active iSCSI TMR, and * transport_lookup_cmd_lun() failing from * iscsit_get_lun_for_cmd() in iscsit_handle_scsi_cmd(). */ - if (cmd->tmr_req && se_cmd->transport_wait_for_tasks) - se_cmd->transport_wait_for_tasks(se_cmd, 1); - else if (cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) - transport_release_cmd(se_cmd); + if (cmd->tmr_req) + transport_generic_free_cmd(&cmd->se_cmd, 0); else iscsit_release_cmd(cmd); @@ -3973,10 +3969,8 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) spin_unlock_bh(&conn->cmd_lock); iscsit_increment_maxcmdsn(cmd, sess); - se_cmd = &cmd->se_cmd; - if (se_cmd->transport_wait_for_tasks) - se_cmd->transport_wait_for_tasks(se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock_bh(&conn->cmd_lock); } diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 000356b..0af537a 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -143,12 +143,10 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) list_del(&cmd->i_list); cmd->conn = NULL; spin_unlock(&cr->conn_recovery_cmd_lock); - if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) || - !(cmd->se_cmd.transport_wait_for_tasks)) + if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) iscsit_release_cmd(cmd); else - cmd->se_cmd.transport_wait_for_tasks( - &cmd->se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock(&cr->conn_recovery_cmd_lock); } spin_unlock(&cr->conn_recovery_cmd_lock); @@ -170,12 +168,10 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) list_del(&cmd->i_list); cmd->conn = NULL; spin_unlock(&cr->conn_recovery_cmd_lock); - if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) || - !(cmd->se_cmd.transport_wait_for_tasks)) + if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) iscsit_release_cmd(cmd); else - cmd->se_cmd.transport_wait_for_tasks( - &cmd->se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock(&cr->conn_recovery_cmd_lock); } spin_unlock(&cr->conn_recovery_cmd_lock); @@ -260,12 +256,10 @@ void iscsit_discard_cr_cmds_by_expstatsn( iscsit_remove_cmd_from_connection_recovery(cmd, sess); spin_unlock(&cr->conn_recovery_cmd_lock); - if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) || - !(cmd->se_cmd.transport_wait_for_tasks)) + if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) iscsit_release_cmd(cmd); else - cmd->se_cmd.transport_wait_for_tasks( - &cmd->se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock(&cr->conn_recovery_cmd_lock); } spin_unlock(&cr->conn_recovery_cmd_lock); @@ -319,12 +313,10 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); - if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) || - !(cmd->se_cmd.transport_wait_for_tasks)) + if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) iscsit_release_cmd(cmd); else - cmd->se_cmd.transport_wait_for_tasks( - &cmd->se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock_bh(&conn->cmd_lock); } spin_unlock_bh(&conn->cmd_lock); @@ -378,12 +370,10 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); - if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) || - !(cmd->se_cmd.transport_wait_for_tasks)) + if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) iscsit_release_cmd(cmd); else - cmd->se_cmd.transport_wait_for_tasks( - &cmd->se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock_bh(&conn->cmd_lock); continue; } @@ -404,12 +394,10 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) list_del(&cmd->i_list); spin_unlock_bh(&conn->cmd_lock); - if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) || - !(cmd->se_cmd.transport_wait_for_tasks)) + if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) iscsit_release_cmd(cmd); else - cmd->se_cmd.transport_wait_for_tasks( - &cmd->se_cmd, 1); + transport_generic_free_cmd(&cmd->se_cmd, 1); spin_lock_bh(&conn->cmd_lock); continue; } @@ -434,9 +422,8 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) iscsit_free_all_datain_reqs(cmd); - if ((cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) && - cmd->se_cmd.transport_wait_for_tasks) - cmd->se_cmd.transport_wait_for_tasks(&cmd->se_cmd, 0); + if (cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) + transport_generic_wait_for_tasks(&cmd->se_cmd); /* * Add the struct iscsi_cmd to the connection recovery cmd list */ diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 113e4a3..66443ed 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1641,8 +1641,6 @@ static int transport_check_alloc_task_attr(struct se_cmd *cmd) return 0; } -static void transport_generic_wait_for_tasks(struct se_cmd *, int); - /* transport_generic_allocate_tasks(): * * Called from fabric RX Thread. @@ -1654,12 +1652,6 @@ int transport_generic_allocate_tasks( int ret; transport_generic_prepare_cdb(cdb); - - /* - * This is needed for early exceptions. - */ - cmd->transport_wait_for_tasks = &transport_generic_wait_for_tasks; - /* * Ensure that the received CDB is less than the max (252 + 8) bytes * for VARIABLE_LENGTH_CMD @@ -1822,11 +1814,6 @@ EXPORT_SYMBOL(transport_generic_handle_data); int transport_generic_handle_tmr( struct se_cmd *cmd) { - /* - * This is needed for early exceptions. - */ - cmd->transport_wait_for_tasks = &transport_generic_wait_for_tasks; - transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR); return 0; } @@ -2507,8 +2494,6 @@ void transport_new_cmd_failure(struct se_cmd *se_cmd) spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); } -static void transport_nop_wait_for_tasks(struct se_cmd *, int); - static inline u32 transport_get_sectors_6( unsigned char *cdb, struct se_cmd *cmd, @@ -2783,7 +2768,6 @@ static int transport_get_sense_data(struct se_cmd *cmd) static int transport_handle_reservation_conflict(struct se_cmd *cmd) { - cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks; cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; @@ -2884,8 +2868,6 @@ static int transport_generic_cmd_sequencer( * Check for an existing UNIT ATTENTION condition */ if (core_scsi3_ua_check(cmd, cdb) < 0) { - cmd->transport_wait_for_tasks = - &transport_nop_wait_for_tasks; cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; return -EINVAL; @@ -2895,7 +2877,6 @@ static int transport_generic_cmd_sequencer( */ ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq); if (ret != 0) { - cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks; /* * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; * The ALUA additional sense code qualifier (ASCQ) is determined @@ -3399,7 +3380,6 @@ static int transport_generic_cmd_sequencer( pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" " 0x%02x, sending CHECK_CONDITION.\n", cmd->se_tfo->get_fabric_name(), cdb[0]); - cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks; goto out_unsupported_cdb; } @@ -4310,14 +4290,14 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) transport_release_cmd(cmd); else { + if (wait_for_tasks) + transport_generic_wait_for_tasks(cmd); + core_dec_lacl_count(cmd->se_sess->se_node_acl, cmd); if (cmd->se_lun) transport_lun_remove_cmd(cmd); - if (wait_for_tasks && cmd->transport_wait_for_tasks) - cmd->transport_wait_for_tasks(cmd, 0); - transport_free_dev_tasks(cmd); transport_put_cmd(cmd); @@ -4325,13 +4305,6 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) } EXPORT_SYMBOL(transport_generic_free_cmd); -static void transport_nop_wait_for_tasks( - struct se_cmd *cmd, - int remove_cmd) -{ - return; -} - /* transport_lun_wait_for_tasks(): * * Called from ConfigFS context to stop the passed struct se_cmd to allow @@ -4506,16 +4479,23 @@ int transport_clear_lun_from_sessions(struct se_lun *lun) * Called from frontend or passthrough context to wait for storage engine * to pause and/or release frontend generated struct se_cmd. */ -static void transport_generic_wait_for_tasks( - struct se_cmd *cmd, - int remove_cmd) +void transport_generic_wait_for_tasks(struct se_cmd *cmd) { unsigned long flags; - if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && !(cmd->se_tmr_req)) - return; - spin_lock_irqsave(&cmd->t_state_lock, flags); + if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) && !(cmd->se_tmr_req)) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return; + } + /* + * Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE + * has been set in transport_set_supported_SAM_opcode(). + */ + if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE)) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return; + } /* * If we are already stopped due to an external event (ie: LUN shutdown) * sleep until the connection can have the passed struct se_cmd back. @@ -4555,8 +4535,10 @@ static void transport_generic_wait_for_tasks( atomic_set(&cmd->transport_lun_stop, 0); } if (!atomic_read(&cmd->t_transport_active) || - atomic_read(&cmd->t_transport_aborted)) - goto remove; + atomic_read(&cmd->t_transport_aborted)) { + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + return; + } atomic_set(&cmd->t_transport_stop, 1); @@ -4579,13 +4561,8 @@ static void transport_generic_wait_for_tasks( pr_debug("wait_for_tasks: Stopped wait_for_compltion(" "&cmd->t_transport_stop_comp) for ITT: 0x%08x\n", cmd->se_tfo->get_task_tag(cmd)); -remove: - spin_unlock_irqrestore(&cmd->t_state_lock, flags); - if (!remove_cmd) - return; - - transport_generic_free_cmd(cmd, 0); } +EXPORT_SYMBOL(transport_generic_wait_for_tasks); static int transport_get_sense_codes( struct se_cmd *cmd, diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 23f7720..800d929 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -480,7 +480,6 @@ struct se_cmd { struct target_core_fabric_ops *se_tfo; int (*transport_emulate_cdb)(struct se_cmd *); void (*transport_split_cdb)(unsigned long long, u32, unsigned char *); - void (*transport_wait_for_tasks)(struct se_cmd *, int); void (*transport_complete_callback)(struct se_cmd *); int (*transport_qf_callback)(struct se_cmd *); diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h index 549b6b3..7f41fb2 100644 --- a/include/target/target_core_transport.h +++ b/include/target/target_core_transport.h @@ -180,6 +180,7 @@ extern void __transport_stop_task_timer(struct se_task *, unsigned long *); extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, struct scatterlist *, u32); extern int transport_clear_lun_from_sessions(struct se_lun *); +extern void transport_generic_wait_for_tasks(struct se_cmd *); extern int transport_check_aborted_status(struct se_cmd *, int); extern int transport_send_check_condition_and_sense(struct se_cmd *, u8, int); extern void transport_send_task_abort(struct se_cmd *); -- 1.7.2.5 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html