Signed-off-by: Andy Grover <agrover@xxxxxxxxxx> --- drivers/target/target_core_device.c | 12 +++------- drivers/target/target_core_internal.h | 12 ++++++++++ drivers/target/target_core_pr.c | 38 ++++++++++++-------------------- drivers/target/target_core_tpg.c | 2 +- include/target/target_core_base.h | 3 +- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 1954b0f..295b5e4 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -224,8 +224,7 @@ struct se_dev_entry *core_get_se_deve_from_rtpi( if (port->sep_rtpi != rtpi) continue; - atomic_inc(&deve->pr_ref_count); - smp_mb__after_atomic_inc(); + get_deve(deve); spin_unlock_irq(&nacl->device_list_lock); return deve; @@ -401,12 +400,6 @@ int core_disable_device_list_for_node( spin_lock_bh(&port->sep_alua_lock); list_del(&deve->alua_port_node); spin_unlock_bh(&port->sep_alua_lock); - /* - * Wait for any in process SPEC_I_PT=1 or REGISTER_AND_MOVE - * PR operation to complete. - */ - while (atomic_read(&deve->pr_ref_count) != 0) - cpu_relax(); spin_lock_irq(&nacl->device_list_lock); /* @@ -421,6 +414,9 @@ int core_disable_device_list_for_node( spin_unlock_irq(&nacl->device_list_lock); core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl); + + put_deve(deve); + return 0; } diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index b11512c..fddf44c 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -93,6 +93,18 @@ int core_tpg_post_addlun(struct se_portal_group *, struct se_lun *, struct se_lun *core_tpg_pre_dellun(struct se_portal_group *, u32 unpacked_lun); int core_tpg_post_dellun(struct se_portal_group *, struct se_lun *); +static inline void release_deve(struct kref *kref) +{ + struct se_dev_entry *deve = container_of(kref, + struct se_dev_entry, refcount); + + /* doesn't really get freed because device_list is a static array */ + deve->lun_flags &= ~TRANSPORT_LUNFLAGS_INITIATOR_ACCESS; +} + +#define get_deve(x) kref_get(&x->refcount) +#define put_deve(x) kref_put(&x->refcount, release_deve) + /* target_core_transport.c */ extern struct kmem_cache *se_tmr_req_cache; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index fc6029b..9155df0 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -708,8 +708,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( if (strcmp(nacl->initiatorname, nacl_tmp->initiatorname)) continue; - atomic_inc(&deve_tmp->pr_ref_count); - smp_mb__after_atomic_inc(); + get_deve(deve_tmp); spin_unlock_bh(&port->sep_alua_lock); /* * Grab a configfs group dependency that is released @@ -722,8 +721,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( pr_err("core_scsi3_lunacl_depend" "_item() failed\n"); put_port(port); - atomic_dec(&deve_tmp->pr_ref_count); - smp_mb__after_atomic_dec(); + put_deve(deve_tmp); goto out; } /* @@ -738,8 +736,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( sa_res_key, all_tg_pt, aptpl); if (!pr_reg_atp) { put_port(port); - atomic_dec(&deve_tmp->pr_ref_count); - smp_mb__after_atomic_dec(); + put_deve(deve_tmp); core_scsi3_lunacl_undepend_item(deve_tmp); goto out; } @@ -1399,22 +1396,17 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve) struct se_lun_acl *lun_acl = se_deve->se_lun_acl; struct se_node_acl *nacl; struct se_portal_group *tpg; - /* - * For nacl->dynamic_node_acl=1 - */ - if (!lun_acl) { - atomic_dec(&se_deve->pr_ref_count); - smp_mb__after_atomic_dec(); - return; - } - nacl = lun_acl->se_lun_nacl; - tpg = nacl->se_tpg; - configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys, - &lun_acl->se_lun_group.cg_item); + /* for non-demo-mode */ + if (lun_acl) { + nacl = lun_acl->se_lun_nacl; + tpg = nacl->se_tpg; - atomic_dec(&se_deve->pr_ref_count); - smp_mb__after_atomic_dec(); + configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys, + &lun_acl->se_lun_group.cg_item); + } + + put_deve(se_deve); } static sense_reason_t @@ -1642,8 +1634,7 @@ core_scsi3_decode_spec_i_port( if (core_scsi3_lunacl_depend_item(dest_se_deve)) { pr_err("core_scsi3_lunacl_depend_item()" " failed\n"); - atomic_dec(&dest_se_deve->pr_ref_count); - smp_mb__after_atomic_dec(); + put_deve(dest_se_deve); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; @@ -3306,8 +3297,7 @@ after_iport_check: if (core_scsi3_lunacl_depend_item(dest_se_deve)) { pr_err("core_scsi3_lunacl_depend_item() failed\n"); - atomic_dec(&dest_se_deve->pr_ref_count); - smp_mb__after_atomic_dec(); + put_deve(dest_se_deve); dest_se_deve = NULL; ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; goto out; diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 1fd90fc..8771b23 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -237,7 +237,7 @@ static int core_create_device_list_for_node(struct se_node_acl *nacl) deve = nacl->device_list[i]; atomic_set(&deve->ua_count, 0); - atomic_set(&deve->pr_ref_count, 0); + kref_init(&deve->refcount); spin_lock_init(&deve->ua_lock); INIT_LIST_HEAD(&deve->alua_port_node); INIT_LIST_HEAD(&deve->ua_list); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index f0bc5c1..6bf1da9 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -587,8 +587,7 @@ struct se_dev_entry { u64 read_bytes; u64 write_bytes; atomic_t ua_count; - /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ - atomic_t pr_ref_count; + struct kref refcount; struct se_lun_acl *se_lun_acl; spinlock_t ua_lock; struct se_lun *se_lun; -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html