Remove TRANSPORT_LUNFLAGS_INITIATOR_ACCESS and just look at if a
non-NULL value is in the node_acl->device_list for the given lun. Since
usually nowhere near all se_dev_entrys are used, this nets a sizable
reduction in memory use.

In core_disable_device_list_for_node, move all calls to functions
referencing deve inside the spinlock, since it's not safe to access deve
outside it. Skip reinitializing, since the deve is actually being freed.

Do not allocate device_list array separately, but include it in
se_node_acl.

Signed-off-by: Andy Grover <agro...@redhat.com>
---
 drivers/target/target_core_device.c          | 94 +++++++++++++++-------------
 drivers/target/target_core_fabric_configfs.c |  4 +-
 drivers/target/target_core_spc.c             |  2 +-
 drivers/target/target_core_tpg.c             | 41 +-----------
 include/target/target_core_base.h            |  7 +--
 5 files changed, 59 insertions(+), 89 deletions(-)

diff --git a/drivers/target/target_core_device.c 
b/drivers/target/target_core_device.c
index 6d91e4d..8a37471 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -67,7 +67,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 
unpacked_lun)
 
        spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags);
        se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun];
-       if (se_cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
+       if (se_cmd->se_deve) {
                struct se_dev_entry *deve = se_cmd->se_deve;
 
                deve->total_cmds++;
@@ -143,7 +143,6 @@ EXPORT_SYMBOL(transport_lookup_cmd_lun);
 
 int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 {
-       struct se_dev_entry *deve;
        struct se_lun *se_lun = NULL;
        struct se_session *se_sess = se_cmd->se_sess;
        struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
@@ -154,9 +153,9 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 
unpacked_lun)
 
        spin_lock_irqsave(&se_sess->se_node_acl->device_list_lock, flags);
        se_cmd->se_deve = se_sess->se_node_acl->device_list[unpacked_lun];
-       deve = se_cmd->se_deve;
+       if (se_cmd->se_deve) {
+               struct se_dev_entry *deve = se_cmd->se_deve;
 
-       if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
                se_tmr->tmr_lun = deve->se_lun;
                se_cmd->se_lun = deve->se_lun;
                se_lun = deve->se_lun;
@@ -204,7 +203,7 @@ struct se_dev_entry *core_get_se_deve_from_rtpi(
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                deve = nacl->device_list[i];
 
-               if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
+               if (!deve)
                        continue;
 
                lun = deve->se_lun;
@@ -243,14 +242,11 @@ int core_free_device_list_for_node(
        struct se_lun *lun;
        u32 i;
 
-       if (!nacl->device_list)
-               return 0;
-
        spin_lock_irq(&nacl->device_list_lock);
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                deve = nacl->device_list[i];
 
-               if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
+               if (!deve)
                        continue;
 
                if (!deve->se_lun) {
@@ -268,9 +264,6 @@ int core_free_device_list_for_node(
        }
        spin_unlock_irq(&nacl->device_list_lock);
 
-       array_free(nacl->device_list, TRANSPORT_MAX_LUNS_PER_TPG);
-       nacl->device_list = NULL;
-
        return 0;
 }
 
@@ -283,12 +276,14 @@ void core_update_device_list_access(
 
        spin_lock_irq(&nacl->device_list_lock);
        deve = nacl->device_list[mapped_lun];
-       if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) {
-               deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY;
-               deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE;
-       } else {
-               deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE;
-               deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY;
+       if (deve) {
+               if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) {
+                       deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY;
+                       deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE;
+               } else {
+                       deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE;
+                       deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY;
+               }
        }
        spin_unlock_irq(&nacl->device_list_lock);
 }
@@ -318,7 +313,7 @@ int core_enable_device_list_for_node(
         * transition.  This transition must be for the same struct se_lun
         * + mapped_lun that was setup in demo mode..
         */
-       if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
+       if (deve) {
                if (deve->se_lun_acl != NULL) {
                        pr_err("struct se_dev_entry->se_lun_acl"
                               " already set for demo mode -> explicit"
@@ -346,18 +341,27 @@ int core_enable_device_list_for_node(
                goto out;
        }
 
+       deve = kzalloc(sizeof(*deve), GFP_ATOMIC);
+       if (!deve) {
+               spin_unlock_irq(&nacl->device_list_lock);
+               return -ENOMEM;
+       }
+
+       nacl->device_list[mapped_lun] = deve;
+
+       atomic_set(&deve->ua_count, 0);
+       atomic_set(&deve->pr_ref_count, 0);
+       spin_lock_init(&deve->ua_lock);
+       INIT_LIST_HEAD(&deve->alua_port_list);
+       INIT_LIST_HEAD(&deve->ua_list);
        deve->se_lun = lun;
        deve->se_lun_acl = lun_acl;
        deve->mapped_lun = mapped_lun;
-       deve->lun_flags |= TRANSPORT_LUNFLAGS_INITIATOR_ACCESS;
 
-       if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) {
-               deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_ONLY;
+       if (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE)
                deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_WRITE;
-       } else {
-               deve->lun_flags &= ~TRANSPORT_LUNFLAGS_READ_WRITE;
+       else
                deve->lun_flags |= TRANSPORT_LUNFLAGS_READ_ONLY;
-       }
 
        deve->creation_time = get_jiffies_64();
        deve->attach_count++;
@@ -385,7 +389,23 @@ int core_disable_device_list_for_node(
        struct se_portal_group *tpg)
 {
        struct se_port *port = lun->lun_sep;
-       struct se_dev_entry *deve = nacl->device_list[mapped_lun];
+       struct se_dev_entry *deve;
+
+       core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl);
+
+       spin_lock_irq(&nacl->device_list_lock);
+       deve = nacl->device_list[mapped_lun];
+       if (!deve) {
+               spin_unlock_irq(&nacl->device_list_lock);
+               return 0;
+       }
+
+       /*
+        * 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();
 
        /*
         * If the MappedLUN entry is being disabled, the entry in
@@ -400,29 +420,19 @@ int core_disable_device_list_for_node(
         * NodeACL context specific PR metadata for demo-mode
         * MappedLUN *deve will be released below..
         */
-       spin_lock_bh(&port->sep_alua_lock);
+       spin_lock(&port->sep_alua_lock);
        list_del(&deve->alua_port_list);
-       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_unlock(&port->sep_alua_lock);
 
-       spin_lock_irq(&nacl->device_list_lock);
        /*
         * Disable struct se_dev_entry LUN ACL mapping
         */
        core_scsi3_ua_release_all(deve);
-       deve->se_lun = NULL;
-       deve->se_lun_acl = NULL;
-       deve->lun_flags = 0;
-       deve->creation_time = 0;
-       deve->attach_count--;
+       nacl->device_list[mapped_lun] = NULL;
+       kfree(deve);
+
        spin_unlock_irq(&nacl->device_list_lock);
 
-       core_scsi3_free_pr_reg_from_nacl(lun->lun_se_dev, nacl);
        return 0;
 }
 
@@ -443,7 +453,7 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct 
se_portal_group *tpg)
                spin_lock_irq(&nacl->device_list_lock);
                for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                        deve = nacl->device_list[i];
-                       if (lun != deve->se_lun)
+                       if (!deve || lun != deve->se_lun)
                                continue;
                        spin_unlock_irq(&nacl->device_list_lock);
 
diff --git a/drivers/target/target_core_fabric_configfs.c 
b/drivers/target/target_core_fabric_configfs.c
index 804e7f0..0955c948 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -113,7 +113,7 @@ static int target_fabric_mappedlun_link(
         */
        spin_lock_irq(&lacl->se_lun_nacl->device_list_lock);
        deve = lacl->se_lun_nacl->device_list[lacl->mapped_lun];
-       if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)
+       if (deve)
                lun_access = deve->lun_flags;
        else
                lun_access =
@@ -149,7 +149,7 @@ static int target_fabric_mappedlun_unlink(
        /*
         * Determine if the underlying MappedLUN has already been released..
         */
-       if (!deve->se_lun) {
+       if (!deve || !deve->se_lun) {
                spin_unlock_irq(&nacl->device_list_lock);
                return 0;
        }
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 43c5ca98..d91cce7 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -1239,7 +1239,7 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
        spin_lock_irq(&sess->se_node_acl->device_list_lock);
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                deve = sess->se_node_acl->device_list[i];
-               if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
+               if (!deve)
                        continue;
                /*
                 * We determine the correct LUN LIST LENGTH even once we
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 88fddcf..82a25e1 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -62,7 +62,7 @@ static void core_clear_initiator_node_from_tpg(
        for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
                deve = nacl->device_list[i];
 
-               if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
+               if (!deve)
                        continue;
 
                if (!deve->se_lun) {
@@ -214,35 +214,6 @@ static void *array_zalloc(int n, size_t size, gfp_t flags)
        return a;
 }
 
-/*      core_create_device_list_for_node():
- *
- *
- */
-static int core_create_device_list_for_node(struct se_node_acl *nacl)
-{
-       struct se_dev_entry *deve;
-       int i;
-
-       nacl->device_list = array_zalloc(TRANSPORT_MAX_LUNS_PER_TPG,
-                       sizeof(struct se_dev_entry), GFP_KERNEL);
-       if (!nacl->device_list) {
-               pr_err("Unable to allocate memory for"
-                       " struct se_node_acl->device_list\n");
-               return -ENOMEM;
-       }
-       for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
-               deve = nacl->device_list[i];
-
-               atomic_set(&deve->ua_count, 0);
-               atomic_set(&deve->pr_ref_count, 0);
-               spin_lock_init(&deve->ua_lock);
-               INIT_LIST_HEAD(&deve->alua_port_list);
-               INIT_LIST_HEAD(&deve->ua_list);
-       }
-
-       return 0;
-}
-
 /*     core_tpg_check_initiator_node_acl()
  *
  *
@@ -279,11 +250,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
 
        tpg->se_tpg_tfo->set_default_node_attributes(acl);
 
-       if (core_create_device_list_for_node(acl) < 0) {
-               tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl);
-               return NULL;
-       }
-
        if (core_set_queue_depth_for_node(tpg, acl) < 0) {
                core_free_device_list_for_node(acl, tpg);
                tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl);
@@ -405,11 +371,6 @@ struct se_node_acl *core_tpg_add_initiator_node_acl(
 
        tpg->se_tpg_tfo->set_default_node_attributes(acl);
 
-       if (core_create_device_list_for_node(acl) < 0) {
-               tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl);
-               return ERR_PTR(-ENOMEM);
-       }
-
        if (core_set_queue_depth_for_node(tpg, acl) < 0) {
                core_free_device_list_for_node(acl, tpg);
                tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl);
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index c9c7912..34e1ae4 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -174,9 +174,8 @@ enum se_cmd_flags_table {
 /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
 enum transport_lunflags_table {
        TRANSPORT_LUNFLAGS_NO_ACCESS            = 0x00,
-       TRANSPORT_LUNFLAGS_INITIATOR_ACCESS     = 0x01,
-       TRANSPORT_LUNFLAGS_READ_ONLY            = 0x02,
-       TRANSPORT_LUNFLAGS_READ_WRITE           = 0x04,
+       TRANSPORT_LUNFLAGS_READ_ONLY            = 0x01,
+       TRANSPORT_LUNFLAGS_READ_WRITE           = 0x02,
 };
 
 /*
@@ -584,7 +583,7 @@ struct se_node_acl {
        char                    acl_tag[MAX_ACL_TAG_SIZE];
        /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
        atomic_t                acl_pr_ref_count;
-       struct se_dev_entry     **device_list;
+       struct se_dev_entry     *device_list[TRANSPORT_MAX_LUNS_PER_TPG];
        struct se_session       *nacl_sess;
        struct se_portal_group *se_tpg;
        spinlock_t              device_list_lock;
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to