Commit ae2fb3cb authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge patch series "target: TMF and recovery fixes"

Mike Christie <michael.christie@oracle.com> says:

The following patches apply over Martin's 6.4 branches and Linus's tree.
They fix a couple regressions in iscsit that occur when there are TMRs
executing and a connection is closed. It also includes Dimitry's fixes in
related code paths for cmd cleanup when ERL2 is used and the write pending
hang during conn cleanup.

This version of the patchset brings it back to just regressions and fixes
for bugs we have a lot of users hitting. I'm going to fix isert and get it
hooked into iscsit properly in a second patchset, because this one was
getting so large. I've also moved my cleanup type of patches for a 3rd
patchset.

Link: https://lore.kernel.org/r/20230319015620.96006-1-michael.christie@oracle.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 5c8c74ef ea87981a
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -2506,8 +2506,8 @@ isert_wait4cmds(struct iscsit_conn *conn)
	isert_info("iscsit_conn %p\n", conn);
	isert_info("iscsit_conn %p\n", conn);


	if (conn->sess) {
	if (conn->sess) {
		target_stop_session(conn->sess->se_sess);
		target_stop_cmd_counter(conn->cmd_cnt);
		target_wait_for_sess_cmds(conn->sess->se_sess);
		target_wait_for_cmds(conn->cmd_cnt);
	}
	}
}
}


+38 −13
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@
#include <target/target_core_base.h>
#include <target/target_core_base.h>
#include <target/target_core_fabric.h>
#include <target/target_core_fabric.h>


#include <target/target_core_backend.h>
#include <target/iscsi/iscsi_target_core.h>
#include <target/iscsi/iscsi_target_core.h>
#include "iscsi_target_parameters.h"
#include "iscsi_target_parameters.h"
#include "iscsi_target_seq_pdu_list.h"
#include "iscsi_target_seq_pdu_list.h"
@@ -1192,7 +1193,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
	__target_init_cmd(&cmd->se_cmd, &iscsi_ops,
	__target_init_cmd(&cmd->se_cmd, &iscsi_ops,
			  conn->sess->se_sess, be32_to_cpu(hdr->data_length),
			  conn->sess->se_sess, be32_to_cpu(hdr->data_length),
			  cmd->data_direction, sam_task_attr,
			  cmd->data_direction, sam_task_attr,
			 cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun));
			  cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun),
			  conn->cmd_cnt);


	pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
	pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
@@ -2055,7 +2057,8 @@ iscsit_handle_task_mgt_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
	__target_init_cmd(&cmd->se_cmd, &iscsi_ops,
	__target_init_cmd(&cmd->se_cmd, &iscsi_ops,
			  conn->sess->se_sess, 0, DMA_NONE,
			  conn->sess->se_sess, 0, DMA_NONE,
			  TCM_SIMPLE_TAG, cmd->sense_buffer + 2,
			  TCM_SIMPLE_TAG, cmd->sense_buffer + 2,
			  scsilun_to_int(&hdr->lun));
			  scsilun_to_int(&hdr->lun),
			  conn->cmd_cnt);


	target_get_sess_cmd(&cmd->se_cmd, true);
	target_get_sess_cmd(&cmd->se_cmd, true);


@@ -4218,9 +4221,12 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
	list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
	list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
		struct se_cmd *se_cmd = &cmd->se_cmd;
		struct se_cmd *se_cmd = &cmd->se_cmd;


		if (se_cmd->se_tfo != NULL) {
		if (!se_cmd->se_tfo)
			continue;

		spin_lock_irq(&se_cmd->t_state_lock);
		spin_lock_irq(&se_cmd->t_state_lock);
		if (se_cmd->transport_state & CMD_T_ABORTED) {
		if (se_cmd->transport_state & CMD_T_ABORTED) {
			if (!(se_cmd->transport_state & CMD_T_TAS))
				/*
				/*
				 * LIO's abort path owns the cleanup for this,
				 * LIO's abort path owns the cleanup for this,
				 * so put it back on the list and let
				 * so put it back on the list and let
@@ -4231,8 +4237,17 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
		} else {
		} else {
			se_cmd->transport_state |= CMD_T_FABRIC_STOP;
			se_cmd->transport_state |= CMD_T_FABRIC_STOP;
		}
		}

		if (cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) {
			/*
			 * We never submitted the cmd to LIO core, so we have
			 * to tell LIO to perform the completion process.
			 */
			spin_unlock_irq(&se_cmd->t_state_lock);
			spin_unlock_irq(&se_cmd->t_state_lock);
			target_complete_cmd(&cmd->se_cmd, SAM_STAT_TASK_ABORTED);
			continue;
		}
		}
		spin_unlock_irq(&se_cmd->t_state_lock);
	}
	}
	spin_unlock_bh(&conn->cmd_lock);
	spin_unlock_bh(&conn->cmd_lock);


@@ -4243,6 +4258,16 @@ static void iscsit_release_commands_from_conn(struct iscsit_conn *conn)
		iscsit_free_cmd(cmd, true);
		iscsit_free_cmd(cmd, true);


	}
	}

	/*
	 * Wait on commands that were cleaned up via the aborted_task path.
	 * LLDs that implement iscsit_wait_conn will already have waited for
	 * commands.
	 */
	if (!conn->conn_transport->iscsit_wait_conn) {
		target_stop_cmd_counter(conn->cmd_cnt);
		target_wait_for_cmds(conn->cmd_cnt);
	}
}
}


static void iscsit_stop_timers_for_cmds(
static void iscsit_stop_timers_for_cmds(
@@ -4517,6 +4542,9 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)
	iscsit_stop_time2retain_timer(sess);
	iscsit_stop_time2retain_timer(sess);
	spin_unlock_bh(&se_tpg->session_lock);
	spin_unlock_bh(&se_tpg->session_lock);


	if (sess->sess_ops->ErrorRecoveryLevel == 2)
		iscsit_free_connection_recovery_entries(sess);

	/*
	/*
	 * transport_deregister_session_configfs() will clear the
	 * transport_deregister_session_configfs() will clear the
	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
@@ -4540,9 +4568,6 @@ int iscsit_close_session(struct iscsit_session *sess, bool can_sleep)


	transport_deregister_session(sess->se_sess);
	transport_deregister_session(sess->se_sess);


	if (sess->sess_ops->ErrorRecoveryLevel == 2)
		iscsit_free_connection_recovery_entries(sess);

	iscsit_free_all_ooo_cmdsns(sess);
	iscsit_free_all_ooo_cmdsns(sess);


	spin_lock_bh(&se_tpg->session_lock);
	spin_lock_bh(&se_tpg->session_lock);
+7 −0
Original line number Original line Diff line number Diff line
@@ -1147,8 +1147,14 @@ static struct iscsit_conn *iscsit_alloc_conn(struct iscsi_np *np)
		goto free_conn_cpumask;
		goto free_conn_cpumask;
	}
	}


	conn->cmd_cnt = target_alloc_cmd_counter();
	if (!conn->cmd_cnt)
		goto free_conn_allowed_cpumask;

	return conn;
	return conn;


free_conn_allowed_cpumask:
	free_cpumask_var(conn->allowed_cpumask);
free_conn_cpumask:
free_conn_cpumask:
	free_cpumask_var(conn->conn_cpumask);
	free_cpumask_var(conn->conn_cpumask);
free_conn_ops:
free_conn_ops:
@@ -1162,6 +1168,7 @@ static struct iscsit_conn *iscsit_alloc_conn(struct iscsi_np *np)


void iscsit_free_conn(struct iscsit_conn *conn)
void iscsit_free_conn(struct iscsit_conn *conn)
{
{
	target_free_cmd_counter(conn->cmd_cnt);
	free_cpumask_var(conn->allowed_cpumask);
	free_cpumask_var(conn->allowed_cpumask);
	free_cpumask_var(conn->conn_cpumask);
	free_cpumask_var(conn->conn_cpumask);
	kfree(conn->conn_ops);
	kfree(conn->conn_ops);
+1 −0
Original line number Original line Diff line number Diff line
@@ -741,6 +741,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
	spin_lock_init(&dev->t10_alua.lba_map_lock);
	spin_lock_init(&dev->t10_alua.lba_map_lock);


	INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work);
	INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work);
	mutex_init(&dev->lun_reset_mutex);


	dev->t10_wwn.t10_dev = dev;
	dev->t10_wwn.t10_dev = dev;
	/*
	/*
+0 −1
Original line number Original line Diff line number Diff line
@@ -139,7 +139,6 @@ int init_se_kmem_caches(void);
void	release_se_kmem_caches(void);
void	release_se_kmem_caches(void);
u32	scsi_get_new_index(scsi_index_t);
u32	scsi_get_new_index(scsi_index_t);
void	transport_subsystem_check_init(void);
void	transport_subsystem_check_init(void);
void	transport_uninit_session(struct se_session *);
unsigned char *transport_dump_cmd_direction(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_state(struct se_device *, char *, int *);
void	transport_dump_dev_info(struct se_device *, struct se_lun *,
void	transport_dump_dev_info(struct se_device *, struct se_lun *,
Loading