[PATCH 12/32] target: Convert t10_pr_registration to kref

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Free struct when kref becomes 0.

Signed-off-by: Andy Grover <agrover@xxxxxxxxxx>
---
 drivers/target/target_core_pr.c   |   99 +++++++++++++++---------------------
 include/target/target_core_base.h |    2 +-
 2 files changed, 42 insertions(+), 59 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 9155df0..17a4c3b 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -75,6 +75,17 @@ enum preempt_type {
 	PREEMPT_AND_ABORT,
 };
 
+static void release_pr_reg(struct kref *kref)
+{
+	struct t10_pr_registration *pr_reg = container_of(kref,
+							  struct t10_pr_registration, refcount);
+
+	kmem_cache_free(t10_pr_reg_cache, pr_reg);
+}
+
+#define get_pr_reg(x) kref_get(&x->refcount)
+#define put_pr_reg(x) kref_put(&x->refcount, release_pr_reg)
+
 static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *,
 			struct t10_pr_registration *, int);
 
@@ -109,7 +120,6 @@ target_scsi2_reservation_check(struct se_cmd *cmd)
 
 static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
 					struct se_node_acl *, struct se_session *);
-static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
 
 static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
 {
@@ -144,17 +154,17 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
 		 * as defined in SPC-2.
 		 */
 		if (pr_reg->pr_res_holder) {
-			core_scsi3_put_pr_reg(pr_reg);
+			put_pr_reg(pr_reg);
 			return 1;
 		}
 		if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
 		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
 		    (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
 		    (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
-			core_scsi3_put_pr_reg(pr_reg);
+			put_pr_reg(pr_reg);
 			return 1;
 		}
-		core_scsi3_put_pr_reg(pr_reg);
+		put_pr_reg(pr_reg);
 		conflict = 1;
 	} else {
 		/*
@@ -611,7 +621,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
 	INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
 	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_list);
 	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list);
-	atomic_set(&pr_reg->pr_res_holders, 0);
+	kref_init(&pr_reg->refcount);
 	pr_reg->pr_reg_nacl = nacl;
 	pr_reg->pr_reg_deve = deve;
 	pr_reg->pr_res_mapped_lun = deve->mapped_lun;
@@ -795,7 +805,7 @@ int core_scsi3_alloc_aptpl_registration(
 	INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
 	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_list);
 	INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list);
-	atomic_set(&pr_reg->pr_res_holders, 0);
+	kref_init(&pr_reg->refcount);
 	pr_reg->pr_reg_nacl = NULL;
 	pr_reg->pr_reg_deve = NULL;
 	pr_reg->pr_res_mapped_lun = mapped_lun;
@@ -1102,8 +1112,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
 				if (dev->dev_attrib.enforce_pr_isids)
 					continue;
 			}
-			atomic_inc(&pr_reg->pr_res_holders);
-			smp_mb__after_atomic_inc();
+			get_pr_reg(pr_reg);
 			spin_unlock(&pr_tmpl->registration_lock);
 			return pr_reg;
 		}
@@ -1117,8 +1126,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
 		if (strcmp(isid, pr_reg->pr_reg_isid))
 			continue;
 
-		atomic_inc(&pr_reg->pr_res_holders);
-		smp_mb__after_atomic_inc();
+		get_pr_reg(pr_reg);
 		spin_unlock(&pr_tmpl->registration_lock);
 		return pr_reg;
 	}
@@ -1145,12 +1153,6 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(
 	return __core_scsi3_locate_pr_reg(dev, nacl, isid_ptr);
 }
 
-static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg)
-{
-	atomic_dec(&pr_reg->pr_res_holders);
-	smp_mb__after_atomic_dec();
-}
-
 static int core_scsi3_check_implicit_release(
 	struct se_device *dev,
 	struct t10_pr_registration *pr_reg)
@@ -1213,7 +1215,6 @@ static void __core_scsi3_free_registration(
 {
 	struct target_core_fabric_ops *tfo =
 			pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo;
-	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	char i_buf[PR_REG_ISID_ID_LEN];
 
 	memset(i_buf, 0, PR_REG_ISID_ID_LEN);
@@ -1227,20 +1228,7 @@ static void __core_scsi3_free_registration(
 	 * so call core_scsi3_put_pr_reg() to decrement our reference.
 	 */
 	if (dec_holders)
-		core_scsi3_put_pr_reg(pr_reg);
-	/*
-	 * Wait until all reference from any other I_T nexuses for this
-	 * *pr_reg have been released.  Because list_del() is called above,
-	 * the last core_scsi3_put_pr_reg(pr_reg) will release this reference
-	 * count back to zero, and we release *pr_reg.
-	 */
-	while (atomic_read(&pr_reg->pr_res_holders) != 0) {
-		spin_unlock(&pr_tmpl->registration_lock);
-		pr_debug("SPC-3 PR [%s] waiting for pr_res_holders\n",
-				tfo->get_fabric_name());
-		cpu_relax();
-		spin_lock(&pr_tmpl->registration_lock);
-	}
+		put_pr_reg(pr_reg);
 
 	pr_debug("SPC-3 PR [%s] Service Action: UNREGISTER Initiator"
 		" Node: %s%s\n", tfo->get_fabric_name(),
@@ -1254,17 +1242,14 @@ static void __core_scsi3_free_registration(
 		" 0x%08x\n", tfo->get_fabric_name(), pr_reg->pr_res_key,
 		pr_reg->pr_res_generation);
 
-	if (!preempt_and_abort_list) {
-		pr_reg->pr_reg_deve = NULL;
-		pr_reg->pr_reg_nacl = NULL;
-		kmem_cache_free(t10_pr_reg_cache, pr_reg);
-		return;
-	}
 	/*
 	 * For PREEMPT_AND_ABORT, the list of *pr_reg in preempt_and_abort_list
 	 * are released once the ABORT_TASK_SET has completed..
 	 */
-	list_add_tail(&pr_reg->pr_reg_abort_list, preempt_and_abort_list);
+	if (preempt_and_abort_list)
+		list_add_tail(&pr_reg->pr_reg_abort_list, preempt_and_abort_list);
+	else
+		put_pr_reg(pr_reg);
 }
 
 void core_scsi3_free_pr_reg_from_nacl(
@@ -1653,7 +1638,7 @@ core_scsi3_decode_spec_i_port(
 		pr_reg_e = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
 					iport_ptr);
 		if (pr_reg_e) {
-			core_scsi3_put_pr_reg(pr_reg_e);
+			put_pr_reg(pr_reg_e);
 			core_scsi3_lunacl_undepend_item(dest_se_deve);
 			core_scsi3_nodeacl_undepend_item(dest_node_acl);
 			core_scsi3_tpg_undepend_item(dest_tpg);
@@ -2181,7 +2166,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
 	ret = core_scsi3_update_and_write_aptpl(dev, aptpl);
 
 out:
-	core_scsi3_put_pr_reg(pr_reg);
+	put_pr_reg(pr_reg);
 	return ret;
 }
 
@@ -2359,7 +2344,7 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key)
 
 	ret = 0;
 out_put_pr_reg:
-	core_scsi3_put_pr_reg(pr_reg);
+	put_pr_reg(pr_reg);
 	return ret;
 }
 
@@ -2573,7 +2558,7 @@ write_aptpl:
 		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
 
 out_put_pr_reg:
-	core_scsi3_put_pr_reg(pr_reg);
+	put_pr_reg(pr_reg);
 	return ret;
 }
 
@@ -2613,7 +2598,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key)
 			" res_key: 0x%016Lx does not match"
 			" existing SA REGISTER res_key:"
 			" 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
-		core_scsi3_put_pr_reg(pr_reg_n);
+		put_pr_reg(pr_reg_n);
 		return TCM_RESERVATION_CONFLICT;
 	}
 	/*
@@ -2757,12 +2742,12 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 		return TCM_RESERVATION_CONFLICT;
 	}
 	if (pr_reg_n->pr_res_key != res_key) {
-		core_scsi3_put_pr_reg(pr_reg_n);
+		put_pr_reg(pr_reg_n);
 		return TCM_RESERVATION_CONFLICT;
 	}
 	if (scope != PR_SCOPE_LU_SCOPE) {
 		pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
-		core_scsi3_put_pr_reg(pr_reg_n);
+		put_pr_reg(pr_reg_n);
 		return TCM_INVALID_PARAMETER_LIST;
 	}
 
@@ -2775,7 +2760,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 
 	if (!all_reg && !sa_res_key) {
 		spin_unlock(&dev->dev_reservation_lock);
-		core_scsi3_put_pr_reg(pr_reg_n);
+		put_pr_reg(pr_reg_n);
 		return TCM_INVALID_PARAMETER_LIST;
 	}
 	/*
@@ -2869,7 +2854,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 		 */
 		if (!released_regs) {
 			spin_unlock(&dev->dev_reservation_lock);
-			core_scsi3_put_pr_reg(pr_reg_n);
+			put_pr_reg(pr_reg_n);
 			return TCM_RESERVATION_CONFLICT;
 		}
 		/*
@@ -2891,7 +2876,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 		if (pr_tmpl->pr_aptpl_active)
 			core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
 
-		core_scsi3_put_pr_reg(pr_reg_n);
+		put_pr_reg(pr_reg_n);
 		core_scsi3_pr_generation(cmd->se_dev);
 		return 0;
 	}
@@ -3020,7 +3005,7 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
 	if (pr_tmpl->pr_aptpl_active)
 		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
 
-	core_scsi3_put_pr_reg(pr_reg_n);
+	put_pr_reg(pr_reg_n);
 	core_scsi3_pr_generation(cmd->se_dev);
 	return 0;
 }
@@ -3442,13 +3427,13 @@ after_iport_check:
 		__core_scsi3_free_registration(dev, pr_reg, NULL, 1);
 		spin_unlock(&pr_tmpl->registration_lock);
 	} else
-		core_scsi3_put_pr_reg(pr_reg);
+		put_pr_reg(pr_reg);
 
 	core_scsi3_update_and_write_aptpl(cmd->se_dev, aptpl);
 
 	transport_kunmap_data_sg(cmd);
 
-	core_scsi3_put_pr_reg(dest_pr_reg);
+	put_pr_reg(dest_pr_reg);
 	return 0;
 out:
 	if (buf)
@@ -3460,7 +3445,7 @@ out:
 	core_scsi3_tpg_undepend_item(dest_se_tpg);
 
 out_put_pr_reg:
-	core_scsi3_put_pr_reg(pr_reg);
+	put_pr_reg(pr_reg);
 	return ret;
 }
 
@@ -3862,8 +3847,7 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 		se_tpg = pr_reg->pr_reg_nacl->se_tpg;
 		add_desc_len = 0;
 
-		atomic_inc(&pr_reg->pr_res_holders);
-		smp_mb__after_atomic_inc();
+		get_pr_reg(pr_reg);
 		spin_unlock(&pr_tmpl->registration_lock);
 		/*
 		 * Determine expected length of $FABRIC_MOD specific
@@ -3876,8 +3860,7 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 			pr_warn("SPC-3 PRIN READ_FULL_STATUS ran"
 				" out of buffer: %d\n", cmd->data_length);
 			spin_lock(&pr_tmpl->registration_lock);
-			atomic_dec(&pr_reg->pr_res_holders);
-			smp_mb__after_atomic_dec();
+			put_pr_reg(pr_reg);
 			break;
 		}
 		/*
@@ -3938,8 +3921,8 @@ core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 				se_nacl, pr_reg, &format_code, &buf[off+4]);
 
 		spin_lock(&pr_tmpl->registration_lock);
-		atomic_dec(&pr_reg->pr_res_holders);
-		smp_mb__after_atomic_dec();
+		put_pr_reg(pr_reg);
+
 		/*
 		 * Set the ADDITIONAL DESCRIPTOR LENGTH
 		 */
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 6bf1da9..513429a 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -363,7 +363,7 @@ struct t10_pr_registration {
 	u32 pr_res_generation;
 	u64 pr_reg_bin_isid;
 	u64 pr_res_key;
-	atomic_t pr_res_holders;
+	struct kref refcount;
 	struct se_node_acl *pr_reg_nacl;
 	struct se_dev_entry *pr_reg_deve;
 	struct se_lun *pr_reg_tg_pt_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




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux