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: Mike Christie <michael.christie@oracle.com> Link: https://lore.kernel.org/r/20230319015620.96006-3-michael.christie@oracle.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
becd9be606
commit
4edba7e4a8
5 changed files with 42 additions and 43 deletions
|
@ -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);
|
||||||
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)
|
||||||
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 @@ free_cmd_cnt:
|
||||||
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)
|
||||||
*
|
*
|
||||||
* 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)
|
||||||
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)
|
||||||
" 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,
|
||||||
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,
|
||||||
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)
|
||||||
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 = {
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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 *,
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue