[PATCH 5/8] target: simplify subsystem registration and lookup

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

 



Move the subsystem registration and lookup into target_core_hba.c, and
make the list of subsystems local to the file.  Get rid of the sub_api_hba_cnt
field and instead to proper reference counting of the module inside the
subsystem_mutex to make it non-racy vs module removal.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Index: lio-core/drivers/target/target_core_hba.c
===================================================================
--- lio-core.orig/drivers/target/target_core_hba.c	2010-11-23 22:36:42.000000000 +0100
+++ lio-core/drivers/target/target_core_hba.c	2010-11-23 22:43:18.977254087 +0100
@@ -44,10 +43,63 @@
 
 #include "target_core_hba.h"
 
+static LIST_HEAD(subsystem_list);
+static DEFINE_MUTEX(subsystem_mutex);
+
+int transport_subsystem_register(struct se_subsystem_api *sub_api)
+{
+	struct se_subsystem_api *s;
+
+	INIT_LIST_HEAD(&sub_api->sub_api_list);
+
+	mutex_lock(&subsystem_mutex);
+	list_for_each_entry(s, &subsystem_list, sub_api_list) {
+		if (!(strcmp(s->name, sub_api->name))) {
+			printk(KERN_ERR "%p is already registered with"
+				" duplicate name %s, unable to process"
+				" request\n", s, s->name);
+			mutex_unlock(&subsystem_mutex);
+			return -EEXIST;
+		}
+	}
+	list_add_tail(&sub_api->sub_api_list, &subsystem_list);
+	mutex_unlock(&subsystem_mutex);
+
+	printk(KERN_INFO "TCM: Registered subsystem plugin: %s struct module:"
+			" %p\n", sub_api->name, sub_api->owner);
+	return 0;
+}
+EXPORT_SYMBOL(transport_subsystem_register);
+
+void transport_subsystem_release(struct se_subsystem_api *sub_api)
+{
+	mutex_lock(&subsystem_mutex);
+	list_del(&sub_api->sub_api_list);
+	mutex_unlock(&subsystem_mutex);
+}
+EXPORT_SYMBOL(transport_subsystem_release);
+
+static struct se_subsystem_api *core_get_backend(const char *sub_name)
+{
+	struct se_subsystem_api *s;
+
+	mutex_lock(&subsystem_mutex);
+	list_for_each_entry(s, &subsystem_list, sub_api_list) {
+		if (!strcmp(s->name, sub_name))
+			goto found;
+	}
+	mutex_unlock(&subsystem_mutex);
+	return NULL;
+found:
+	if (s->owner && !try_module_get(s->owner))
+		s = NULL;
+	mutex_unlock(&subsystem_mutex);
+	return s;
+}
+
 struct se_hba *
 core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
 {
-	struct se_subsystem_api *t;
 	struct se_hba *hba;
 	int ret = 0;
 
@@ -68,30 +120,13 @@ core_alloc_hba(const char *plugin_name,
 	atomic_set(&hba->max_queue_depth, 0);
 	atomic_set(&hba->left_queue_depth, 0);
 
-	t = transport_core_get_sub_by_name(plugin_name);
-	if (!t) {
+	hba->transport = core_get_backend(plugin_name);
+	if (!hba->transport) {
 		ret = -EINVAL;
 		goto out_free_hba;
 	}
 
-	hba->transport = t;
-
-	/*
-	 * Get TCM subsystem api struct module reference to struct se_hba
-	 */
-	if (t->owner) {
-		/*
-		 * Grab a struct module reference count for subsystem plugin
-		 */
-		if (!try_module_get(t->owner)) {
-			printk(KERN_ERR "try_module_get() failed for %s\n",
-				t->owner->name);
-			ret = -EINVAL;
-			goto out_put_subsystem;
-		}
-	}
-
-	ret = t->attach_hba(hba, plugin_dep_id);
+	ret = hba->transport->attach_hba(hba, plugin_dep_id);
 	if (ret < 0)
 		goto out_module_put;
 
@@ -106,11 +141,9 @@ core_alloc_hba(const char *plugin_name,
 	return hba;
 
 out_module_put:
-	if (t->owner)
-		module_put(t->owner);
-out_put_subsystem:
+	if (hba->transport->owner)
+		module_put(hba->transport->owner);
 	hba->transport = NULL;
-	transport_core_put_sub(t);
 out_free_hba:
 	kfree(hba);
 	return ERR_PTR(ret);
@@ -134,11 +167,6 @@ core_delete_hba(struct se_hba *hba)
 	spin_unlock(&hba->device_lock);
 
 	hba->transport->detach_hba(hba);
-	if (hba->transport->owner)
-		module_put(hba->transport->owner);
-
-	if (!(hba->hba_flags & HBA_FLAGS_INTERNAL_USE))
-		transport_core_put_sub(hba->transport);
 
 	spin_lock(&se_global->hba_lock);
 	list_del(&hba->hba_list);
@@ -149,6 +177,8 @@ core_delete_hba(struct se_hba *hba)
 	printk(KERN_INFO "CORE_HBA[%d] - Detached HBA from Generic Target"
 			" Core\n", hba->hba_id);
 
+	if (hba->transport->owner)
+		module_put(hba->transport->owner);
 	kfree(hba);
 	return 0;
 }
Index: lio-core/drivers/target/target_core_transport.c
===================================================================
--- lio-core.orig/drivers/target/target_core_transport.c	2010-11-23 22:34:07.000000000 +0100
+++ lio-core/drivers/target/target_core_transport.c	2010-11-23 22:37:25.121253389 +0100
@@ -289,13 +289,11 @@ int init_se_global(void)
 	INIT_LIST_HEAD(&global->g_se_tpg_list);
 	INIT_LIST_HEAD(&global->g_hba_list);
 	INIT_LIST_HEAD(&global->g_se_dev_list);
-	INIT_LIST_HEAD(&global->g_sub_api_list);
 	spin_lock_init(&global->g_device_lock);
 	spin_lock_init(&global->hba_lock);
 	spin_lock_init(&global->se_tpg_lock);
 	spin_lock_init(&global->lu_gps_lock);
 	spin_lock_init(&global->plugin_class_lock);
-	mutex_init(&global->g_sub_api_mutex);
 
 	se_cmd_cache = kmem_cache_create("se_cmd_cache",
 			sizeof(struct se_cmd), __alignof__(struct se_cmd), 0, NULL);
@@ -472,64 +470,6 @@ int transport_subsystem_check_init(void)
 	return 0;
 }
 
-int transport_subsystem_register(
-	struct se_subsystem_api *sub_api)
-{
-	struct se_subsystem_api *s;
-
-	INIT_LIST_HEAD(&sub_api->sub_api_list);
-
-	mutex_lock(&se_global->g_sub_api_mutex);
-	list_for_each_entry(s, &se_global->g_sub_api_list, sub_api_list) {
-		if (!(strcmp(s->name, sub_api->name))) {
-			printk(KERN_ERR "%p is already registered with"
-				" duplicate name %s, unable to process"
-				" request\n", s, s->name);
-			mutex_unlock(&se_global->g_sub_api_mutex);
-			return -EEXIST;
-		}
-	}
-	list_add_tail(&sub_api->sub_api_list, &se_global->g_sub_api_list);
-	mutex_unlock(&se_global->g_sub_api_mutex);
-
-	printk(KERN_INFO "TCM: Registered subsystem plugin: %s struct module:"
-			" %p\n", sub_api->name, sub_api->owner);
-	return 0;
-}
-EXPORT_SYMBOL(transport_subsystem_register);
-
-void transport_subsystem_release(struct se_subsystem_api *sub_api)
-{
-	mutex_lock(&se_global->g_sub_api_mutex);
-	list_del(&sub_api->sub_api_list);
-	mutex_unlock(&se_global->g_sub_api_mutex);
-}
-EXPORT_SYMBOL(transport_subsystem_release);
-
-struct se_subsystem_api *transport_core_get_sub_by_name(const char *sub_name)
-{
-	struct se_subsystem_api *s;
-
-	mutex_lock(&se_global->g_sub_api_mutex);
-	list_for_each_entry(s, &se_global->g_sub_api_list, sub_api_list) {
-		if (!(strcmp(s->name, sub_name))) {
-			atomic_inc(&s->sub_api_hba_cnt);
-			smp_mb__after_atomic_inc();
-			mutex_unlock(&se_global->g_sub_api_mutex);
-			return s;
-		}
-	}
-	mutex_unlock(&se_global->g_sub_api_mutex);
-
-	return NULL;
-}
-
-void transport_core_put_sub(struct se_subsystem_api *s)
-{
-	atomic_dec(&s->sub_api_hba_cnt);
-	smp_mb__after_atomic_dec();
-}
-
 struct se_session *transport_init_session(void)
 {
 	struct se_session *se_sess;
Index: lio-core/include/target/target_core_base.h
===================================================================
--- lio-core.orig/include/target/target_core_base.h	2010-11-23 22:34:08.000000000 +0100
+++ lio-core/include/target/target_core_base.h	2010-11-23 22:37:20.333253110 +0100
@@ -983,12 +983,10 @@ struct se_global {
 	struct list_head	g_se_tpg_list;
 	struct list_head	g_hba_list;
 	struct list_head	g_se_dev_list;
-	struct list_head	g_sub_api_list;
 	struct se_hba		*g_lun0_hba;
 	struct se_subsystem_dev *g_lun0_su_dev;
 	struct se_device	*g_lun0_dev;
 	struct t10_alua_lu_gp	*default_lu_gp;
-	struct mutex		g_sub_api_mutex;
 	spinlock_t		g_device_lock;
 	spinlock_t		hba_lock;
 	spinlock_t		se_tpg_lock;
Index: lio-core/include/target/target_core_transport.h
===================================================================
--- lio-core.orig/include/target/target_core_transport.h	2010-11-23 22:34:08.000000000 +0100
+++ lio-core/include/target/target_core_transport.h	2010-11-23 22:38:54.534253179 +0100
@@ -130,8 +130,6 @@ extern int transport_subsystem_check_ini
 extern int transport_subsystem_register(struct se_subsystem_api *);
 extern void transport_subsystem_release(struct se_subsystem_api *);
 extern void transport_load_plugins(void);
-extern struct se_subsystem_api *transport_core_get_sub_by_name(const char *);
-extern void transport_core_put_sub(struct se_subsystem_api *);
 extern struct se_session *transport_init_session(void);
 extern void __transport_register_session(struct se_portal_group *,
 					struct se_node_acl *,
@@ -238,10 +236,6 @@ struct se_subsystem_api {
 	 */
 	struct module *owner;
 	/*
-	 * Counter for struct se_hba reference
-	 */
-	atomic_t sub_api_hba_cnt;
-	/*
 	 * Used for global se_subsystem_api list_head
 	 */
 	struct list_head sub_api_list;

--
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