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

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.comSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent becd9be6
...@@ -324,8 +324,18 @@ static int iscsi_login_zero_tsih_s1( ...@@ -324,8 +324,18 @@ static int iscsi_login_zero_tsih_s1(
goto free_ops; 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; return 0;
free_se_sess:
transport_free_session(sess->se_sess);
free_ops: free_ops:
kfree(sess->sess_ops); kfree(sess->sess_ops);
free_id: free_id:
......
...@@ -138,7 +138,6 @@ int init_se_kmem_caches(void); ...@@ -138,7 +138,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 *,
......
...@@ -228,7 +228,7 @@ static void target_release_cmd_refcnt(struct percpu_ref *ref) ...@@ -228,7 +228,7 @@ static void target_release_cmd_refcnt(struct percpu_ref *ref)
wake_up(&cmd_cnt->refcnt_wq); 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; struct target_cmd_counter *cmd_cnt;
int rc; int rc;
...@@ -252,6 +252,7 @@ static struct target_cmd_counter *target_alloc_cmd_counter(void) ...@@ -252,6 +252,7 @@ static struct target_cmd_counter *target_alloc_cmd_counter(void)
kfree(cmd_cnt); kfree(cmd_cnt);
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(target_alloc_cmd_counter);
static void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt) 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) ...@@ -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. * 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_list);
INIT_LIST_HEAD(&se_sess->sess_acl_list); INIT_LIST_HEAD(&se_sess->sess_acl_list);
spin_lock_init(&se_sess->sess_cmd_lock); 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); 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 * transport_alloc_session - allocate a session object and initialize it
* @sup_prot_ops: bitmask that defines which T10-PI modes are supported. * @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) ...@@ -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 *transport_alloc_session(enum target_prot_op sup_prot_ops)
{ {
struct se_session *se_sess; struct se_session *se_sess;
int ret;
se_sess = kmem_cache_zalloc(se_sess_cache, GFP_KERNEL); se_sess = kmem_cache_zalloc(se_sess_cache, GFP_KERNEL);
if (!se_sess) { if (!se_sess) {
...@@ -304,11 +294,7 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops) ...@@ -304,11 +294,7 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
" se_sess_cache\n"); " se_sess_cache\n");
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
ret = transport_init_session(se_sess); transport_init_session(se_sess);
if (ret < 0) {
kmem_cache_free(se_sess_cache, se_sess);
return ERR_PTR(ret);
}
se_sess->sup_prot_ops = sup_prot_ops; se_sess->sup_prot_ops = sup_prot_ops;
return se_sess; return se_sess;
...@@ -474,8 +460,13 @@ target_setup_session(struct se_portal_group *tpg, ...@@ -474,8 +460,13 @@ target_setup_session(struct se_portal_group *tpg,
int (*callback)(struct se_portal_group *, int (*callback)(struct se_portal_group *,
struct se_session *, void *)) struct se_session *, void *))
{ {
struct target_cmd_counter *cmd_cnt;
struct se_session *sess; 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 * If the fabric driver is using percpu-ida based pre allocation
* of I/O descriptor tags, go ahead and perform that setup now.. * of I/O descriptor tags, go ahead and perform that setup now..
...@@ -485,29 +476,36 @@ target_setup_session(struct se_portal_group *tpg, ...@@ -485,29 +476,36 @@ target_setup_session(struct se_portal_group *tpg,
else else
sess = transport_alloc_session(prot_op); sess = transport_alloc_session(prot_op);
if (IS_ERR(sess)) if (IS_ERR(sess)) {
return sess; rc = PTR_ERR(sess);
goto free_cnt;
}
sess->cmd_cnt = cmd_cnt;
sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg, sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
(unsigned char *)initiatorname); (unsigned char *)initiatorname);
if (!sess->se_node_acl) { if (!sess->se_node_acl) {
transport_free_session(sess); rc = -EACCES;
return ERR_PTR(-EACCES); goto free_sess;
} }
/* /*
* Go ahead and perform any remaining fabric setup that is * Go ahead and perform any remaining fabric setup that is
* required before transport_register_session(). * required before transport_register_session().
*/ */
if (callback != NULL) { if (callback != NULL) {
int rc = callback(tpg, sess, private); rc = callback(tpg, sess, private);
if (rc) { if (rc)
transport_free_session(sess); goto free_sess;
return ERR_PTR(rc);
}
} }
transport_register_session(tpg, sess->se_node_acl, sess, private); transport_register_session(tpg, sess->se_node_acl, sess, private);
return sess; 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); EXPORT_SYMBOL(target_setup_session);
...@@ -632,7 +630,8 @@ void transport_free_session(struct se_session *se_sess) ...@@ -632,7 +630,8 @@ void transport_free_session(struct se_session *se_sess)
sbitmap_queue_free(&se_sess->sess_tag_pool); sbitmap_queue_free(&se_sess->sess_tag_pool);
kvfree(se_sess->sess_cmd_map); 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); kmem_cache_free(se_sess_cache, se_sess);
} }
EXPORT_SYMBOL(transport_free_session); EXPORT_SYMBOL(transport_free_session);
......
...@@ -461,8 +461,6 @@ static const struct target_core_fabric_ops xcopy_pt_tfo = { ...@@ -461,8 +461,6 @@ static const struct target_core_fabric_ops xcopy_pt_tfo = {
int target_xcopy_setup_pt(void) int target_xcopy_setup_pt(void)
{ {
int ret;
xcopy_wq = alloc_workqueue("xcopy_wq", WQ_MEM_RECLAIM, 0); xcopy_wq = alloc_workqueue("xcopy_wq", WQ_MEM_RECLAIM, 0);
if (!xcopy_wq) { if (!xcopy_wq) {
pr_err("Unable to allocate xcopy_wq\n"); pr_err("Unable to allocate xcopy_wq\n");
...@@ -479,9 +477,7 @@ int target_xcopy_setup_pt(void) ...@@ -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_list);
INIT_LIST_HEAD(&xcopy_pt_nacl.acl_sess_list); INIT_LIST_HEAD(&xcopy_pt_nacl.acl_sess_list);
memset(&xcopy_pt_sess, 0, sizeof(struct se_session)); memset(&xcopy_pt_sess, 0, sizeof(struct se_session));
ret = transport_init_session(&xcopy_pt_sess); transport_init_session(&xcopy_pt_sess);
if (ret < 0)
goto destroy_wq;
xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg; xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg;
xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess; xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess;
...@@ -490,19 +486,12 @@ int target_xcopy_setup_pt(void) ...@@ -490,19 +486,12 @@ int target_xcopy_setup_pt(void)
xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl; xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl;
return 0; return 0;
destroy_wq:
destroy_workqueue(xcopy_wq);
xcopy_wq = NULL;
return ret;
} }
void target_xcopy_release_pt(void) void target_xcopy_release_pt(void)
{ {
if (xcopy_wq) { if (xcopy_wq)
destroy_workqueue(xcopy_wq); destroy_workqueue(xcopy_wq);
transport_uninit_session(&xcopy_pt_sess);
}
} }
/* /*
......
...@@ -133,7 +133,9 @@ struct se_session *target_setup_session(struct se_portal_group *, ...@@ -133,7 +133,9 @@ struct se_session *target_setup_session(struct se_portal_group *,
struct se_session *, void *)); struct se_session *, void *));
void target_remove_session(struct se_session *); 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); struct se_session *transport_alloc_session(enum target_prot_op);
int transport_alloc_session_tags(struct se_session *, unsigned int, int transport_alloc_session_tags(struct se_session *, unsigned int,
unsigned int); unsigned int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment