Use the kernel's std kref for refcounting. Signed-off-by: Andy Grover <agrover@xxxxxxxxxx> --- drivers/target/target_core_device.c | 12 ++---------- drivers/target/target_core_internal.h | 10 ++++++++++ drivers/target/target_core_pr.c | 12 ++++-------- include/target/target_core_base.h | 2 +- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 3350467..1954b0f 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -472,6 +472,7 @@ static struct se_port *core_alloc_port(struct se_device *dev) atomic_set(&port->sep_tg_pt_secondary_offline, 0); spin_lock_init(&port->sep_alua_lock); mutex_init(&port->sep_tg_pt_md_mutex); + kref_init(&port->refcount); spin_lock(&dev->se_port_lock); if (dev->dev_port_count == 0x0000ffff) { @@ -555,20 +556,11 @@ static void core_export_port( static void core_release_port(struct se_device *dev, struct se_port *port) __releases(&dev->se_port_lock) __acquires(&dev->se_port_lock) { - /* - * Wait for any port reference for PR ALL_TG_PT=1 operation - * to complete in __core_scsi3_alloc_registration() - */ - spin_unlock(&dev->se_port_lock); - if (atomic_read(&port->sep_tg_pt_ref_cnt)) - cpu_relax(); - spin_lock(&dev->se_port_lock); - core_alua_free_tg_pt_gp_mem(port); list_del(&port->sep_node); dev->dev_port_count--; - kfree(port); + put_port(port); } int core_dev_export( diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 47b63b0..b11512c 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -60,6 +60,16 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name); int target_configure_device(struct se_device *dev); void target_free_device(struct se_device *); +static inline void release_port(struct kref *ref) +{ + struct se_port *port = container_of(ref, struct se_port, refcount); + + kfree(port); +} + +#define get_port(x) kref_get(&x->refcount) +#define put_port(x) kref_put(&x->refcount, release_port) + /* target_core_hba.c */ struct se_hba *core_alloc_hba(const char *, u32, u32); int core_delete_hba(struct se_hba *); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d141c7f..fc6029b 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -674,8 +674,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( */ spin_lock(&dev->se_port_lock); list_for_each_entry_safe(port, port_tmp, &dev->dev_sep_list, sep_node) { - atomic_inc(&port->sep_tg_pt_ref_cnt); - smp_mb__after_atomic_inc(); + get_port(port); spin_unlock(&dev->se_port_lock); spin_lock_bh(&port->sep_alua_lock); @@ -722,8 +721,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( if (ret < 0) { pr_err("core_scsi3_lunacl_depend" "_item() failed\n"); - atomic_dec(&port->sep_tg_pt_ref_cnt); - smp_mb__after_atomic_dec(); + put_port(port); atomic_dec(&deve_tmp->pr_ref_count); smp_mb__after_atomic_dec(); goto out; @@ -739,8 +737,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( nacl_tmp, deve_tmp, NULL, sa_res_key, all_tg_pt, aptpl); if (!pr_reg_atp) { - atomic_dec(&port->sep_tg_pt_ref_cnt); - smp_mb__after_atomic_dec(); + put_port(port); atomic_dec(&deve_tmp->pr_ref_count); smp_mb__after_atomic_dec(); core_scsi3_lunacl_undepend_item(deve_tmp); @@ -754,8 +751,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( spin_unlock_bh(&port->sep_alua_lock); spin_lock(&dev->se_port_lock); - atomic_dec(&port->sep_tg_pt_ref_cnt); - smp_mb__after_atomic_dec(); + put_port(port); } spin_unlock(&dev->se_port_lock); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 6c517cd..f0bc5c1 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -773,7 +773,7 @@ struct se_port { /* Used for ALUA Target Port Groups membership */ atomic_t sep_tg_pt_secondary_offline; /* Used for PR ALL_TG_PT=1 */ - atomic_t sep_tg_pt_ref_cnt; + struct kref refcount; spinlock_t sep_alua_lock; struct mutex sep_tg_pt_md_mutex; struct t10_alua_tg_pt_gp_member *sep_alua_tg_pt_gp_mem; -- 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