Commit 4edba7e4 authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen
Browse files

scsi: target: Move cmd counter allocation



iSCSI needs to allocate its cmd counter per connection for MCS support
where we need to stop and wait on commands running on a connection instead
of per session. This moves the cmd counter allocation to
target_setup_session() which is used by drivers that need the stop+wait
behavior per session.

xcopy doesn't need stop+wait at all, so we will be OK moving the cmd
counter allocation outside of transport_init_session().

Signed-off-by: default avatarMike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20230319015620.96006-3-michael.christie@oracle.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent becd9be6
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -324,8 +324,18 @@ static int iscsi_login_zero_tsih_s1(
		goto free_ops;
	}

	/*
	 * This is temp for iser. It will be moved to per conn in later
	 * patches for iscsi.
	 */
	sess->se_sess->cmd_cnt = target_alloc_cmd_counter();
	if (!sess->se_sess->cmd_cnt)
		goto free_se_sess;

	return 0;

free_se_sess:
	transport_free_session(sess->se_sess);
free_ops:
	kfree(sess->sess_ops);
free_id:
+0 −1
Original line number Diff line number Diff line
@@ -138,7 +138,6 @@ int init_se_kmem_caches(void);
void	release_se_kmem_caches(void);
u32	scsi_get_new_index(scsi_index_t);
void	transport_subsystem_check_init(void);
void	transport_uninit_session(struct se_session *);
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 *,
+27 −28
Original line number Diff line number Diff line
@@ -228,7 +228,7 @@ static void target_release_cmd_refcnt(struct percpu_ref *ref)
	wake_up(&cmd_cnt->refcnt_wq);
}

static struct target_cmd_counter *target_alloc_cmd_counter(void)
struct target_cmd_counter *target_alloc_cmd_counter(void)
{
	struct target_cmd_counter *cmd_cnt;
	int rc;
@@ -252,6 +252,7 @@ static struct target_cmd_counter *target_alloc_cmd_counter(void)
	kfree(cmd_cnt);
	return NULL;
}
EXPORT_SYMBOL_GPL(target_alloc_cmd_counter);

static void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt)
{
@@ -271,24 +272,14 @@ static void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt)
 *
 * The caller must have zero-initialized @se_sess before calling this function.
 */
int transport_init_session(struct se_session *se_sess)
void transport_init_session(struct se_session *se_sess)
{
	INIT_LIST_HEAD(&se_sess->sess_list);
	INIT_LIST_HEAD(&se_sess->sess_acl_list);
	spin_lock_init(&se_sess->sess_cmd_lock);
	se_sess->cmd_cnt = target_alloc_cmd_counter();
	if (!se_sess->cmd_cnt)
		return -ENOMEM;

	return  0;
}
EXPORT_SYMBOL(transport_init_session);

void transport_uninit_session(struct se_session *se_sess)
{
	target_free_cmd_counter(se_sess->cmd_cnt);
}

/**
 * transport_alloc_session - allocate a session object and initialize it
 * @sup_prot_ops: bitmask that defines which T10-PI modes are supported.
@@ -296,7 +287,6 @@ void transport_uninit_session(struct se_session *se_sess)
struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
{
	struct se_session *se_sess;
	int ret;

	se_sess = kmem_cache_zalloc(se_sess_cache, GFP_KERNEL);
	if (!se_sess) {
@@ -304,11 +294,7 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
				" se_sess_cache\n");
		return ERR_PTR(-ENOMEM);
	}
	ret = transport_init_session(se_sess);
	if (ret < 0) {
		kmem_cache_free(se_sess_cache, se_sess);
		return ERR_PTR(ret);
	}
	transport_init_session(se_sess);
	se_sess->sup_prot_ops = sup_prot_ops;

	return se_sess;
@@ -474,8 +460,13 @@ target_setup_session(struct se_portal_group *tpg,
		     int (*callback)(struct se_portal_group *,
				     struct se_session *, void *))
{
	struct target_cmd_counter *cmd_cnt;
	struct se_session *sess;
	int rc;

	cmd_cnt = target_alloc_cmd_counter();
	if (!cmd_cnt)
		return ERR_PTR(-ENOMEM);
	/*
	 * If the fabric driver is using percpu-ida based pre allocation
	 * of I/O descriptor tags, go ahead and perform that setup now..
@@ -485,29 +476,36 @@ target_setup_session(struct se_portal_group *tpg,
	else
		sess = transport_alloc_session(prot_op);

	if (IS_ERR(sess))
		return sess;
	if (IS_ERR(sess)) {
		rc = PTR_ERR(sess);
		goto free_cnt;
	}
	sess->cmd_cnt = cmd_cnt;

	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
					(unsigned char *)initiatorname);
	if (!sess->se_node_acl) {
		transport_free_session(sess);
		return ERR_PTR(-EACCES);
		rc = -EACCES;
		goto free_sess;
	}
	/*
	 * Go ahead and perform any remaining fabric setup that is
	 * required before transport_register_session().
	 */
	if (callback != NULL) {
		int rc = callback(tpg, sess, private);
		if (rc) {
			transport_free_session(sess);
			return ERR_PTR(rc);
		}
		rc = callback(tpg, sess, private);
		if (rc)
			goto free_sess;
	}

	transport_register_session(tpg, sess->se_node_acl, sess, private);
	return sess;

free_sess:
	transport_free_session(sess);
free_cnt:
	target_free_cmd_counter(cmd_cnt);
	return ERR_PTR(rc);
}
EXPORT_SYMBOL(target_setup_session);

@@ -632,7 +630,8 @@ void transport_free_session(struct se_session *se_sess)
		sbitmap_queue_free(&se_sess->sess_tag_pool);
		kvfree(se_sess->sess_cmd_map);
	}
	transport_uninit_session(se_sess);
	if (se_sess->cmd_cnt)
		target_free_cmd_counter(se_sess->cmd_cnt);
	kmem_cache_free(se_sess_cache, se_sess);
}
EXPORT_SYMBOL(transport_free_session);
+2 −13
Original line number Diff line number Diff line
@@ -461,8 +461,6 @@ static const struct target_core_fabric_ops xcopy_pt_tfo = {

int target_xcopy_setup_pt(void)
{
	int ret;

	xcopy_wq = alloc_workqueue("xcopy_wq", WQ_MEM_RECLAIM, 0);
	if (!xcopy_wq) {
		pr_err("Unable to allocate xcopy_wq\n");
@@ -479,9 +477,7 @@ int target_xcopy_setup_pt(void)
	INIT_LIST_HEAD(&xcopy_pt_nacl.acl_list);
	INIT_LIST_HEAD(&xcopy_pt_nacl.acl_sess_list);
	memset(&xcopy_pt_sess, 0, sizeof(struct se_session));
	ret = transport_init_session(&xcopy_pt_sess);
	if (ret < 0)
		goto destroy_wq;
	transport_init_session(&xcopy_pt_sess);

	xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg;
	xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess;
@@ -490,19 +486,12 @@ int target_xcopy_setup_pt(void)
	xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl;

	return 0;

destroy_wq:
	destroy_workqueue(xcopy_wq);
	xcopy_wq = NULL;
	return ret;
}

void target_xcopy_release_pt(void)
{
	if (xcopy_wq) {
	if (xcopy_wq)
		destroy_workqueue(xcopy_wq);
		transport_uninit_session(&xcopy_pt_sess);
	}
}

/*
+3 −1
Original line number Diff line number Diff line
@@ -133,7 +133,9 @@ struct se_session *target_setup_session(struct se_portal_group *,
				struct se_session *, void *));
void target_remove_session(struct se_session *);

int transport_init_session(struct se_session *se_sess);
struct target_cmd_counter *target_alloc_cmd_counter(void);

void transport_init_session(struct se_session *se_sess);
struct se_session *transport_alloc_session(enum target_prot_op);
int transport_alloc_session_tags(struct se_session *, unsigned int,
		unsigned int);