All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wei Yang <richardw.yang@linux.intel.com>
To: linux-nvdimm@lists.01.org
Cc: zwisler@kernel.org
Subject: [PATCH 5/5] libnvdimm, namespace: allocate devs for namespace just once
Date: Mon, 28 Jan 2019 08:30:18 +0800	[thread overview]
Message-ID: <20190128003018.4087-5-richardw.yang@linux.intel.com> (raw)
In-Reply-To: <20190128003018.4087-1-richardw.yang@linux.intel.com>

Current scan_labels() will allocate devs for namespace step by step. The
logic is correct while it requires:

  * more interaction with mm subsystem
  * memcpy for each new allocation

Since each namespace has different uuid for its label, we can calculate
the number of possible namespace during label initialization and
allocate devs for namespace just once.

This patch achieve the effect by:

  * add a labels_uuid_num field in nd_mapping
  * record number of different label uuid in labels_uuid_num
  * allocate devs for namespace based on labels_uuid_num

After that, we could clean up the memory allocation in scan_labels().

Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
 drivers/nvdimm/namespace_devs.c | 29 +++++++++++++++++------------
 drivers/nvdimm/nd.h             |  1 +
 drivers/nvdimm/region_devs.c    |  1 +
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index cdf3049bd2b9..53ac2716b2b4 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2293,10 +2293,14 @@ static struct device **scan_labels(struct nd_region *nd_region)
 	struct nd_mapping *nd_mapping = &nd_region->mapping[0];
 	resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1;
 
+	devs = kcalloc(nd_mapping->labels_uuid_num + 2,
+		       sizeof(dev), GFP_KERNEL);
+	if (!devs)
+		return NULL;
+
 	/* "safe" because create_namespace_pmem() might list_move() label_ent */
 	list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
 		struct nd_namespace_label *nd_label = label_ent->label;
-		struct device **__devs;
 		u32 flags;
 
 		if (!nd_label)
@@ -2317,12 +2321,6 @@ static struct device **scan_labels(struct nd_region *nd_region)
 			goto err;
 		if (i < count)
 			continue;
-		__devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL);
-		if (!__devs)
-			goto err;
-		memcpy(__devs, devs, sizeof(dev) * count);
-		kfree(devs);
-		devs = __devs;
 
 		if (is_nd_blk(&nd_region->dev))
 			dev = create_namespace_blk(nd_region, nd_label, count);
@@ -2358,9 +2356,6 @@ static struct device **scan_labels(struct nd_region *nd_region)
 		/* Publish a zero-sized namespace for userspace to configure. */
 		nd_mapping_free_labels(nd_mapping);
 
-		devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
-		if (!devs)
-			goto err;
 		if (is_nd_blk(&nd_region->dev)) {
 			struct nd_namespace_blk *nsblk;
 
@@ -2452,11 +2447,12 @@ static struct device **create_namespaces(struct nd_region *nd_region)
 static int __init_active_labels(struct nd_mapping *nd_mapping, int count)
 {
 	struct nvdimm_drvdata *ndd = nd_mapping->ndd;
-	struct nd_label_ent *label_ent;
+	struct nd_label_ent *label_ent, *e;
 	int j;
 
 	for (j = 0; j < count; j++) {
-		struct nd_namespace_label *label;
+		struct nd_namespace_label *label, *l;
+		int new_uuid = 1;
 
 		label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
 		if (!label_ent)
@@ -2465,6 +2461,15 @@ static int __init_active_labels(struct nd_mapping *nd_mapping, int count)
 		label_ent->label = label;
 
 		mutex_lock(&nd_mapping->lock);
+		list_for_each_entry(e, &nd_mapping->labels, list) {
+			l = e->label;
+
+			if (!memcmp(label->uuid, l->uuid, NSLABEL_UUID_LEN)) {
+				new_uuid = 0;
+				break;
+			}
+		}
+		nd_mapping->labels_uuid_num += new_uuid;
 		list_add_tail(&label_ent->list, &nd_mapping->labels);
 		mutex_unlock(&nd_mapping->lock);
 	}
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index e79cc8e5c114..b143a67a1a34 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -128,6 +128,7 @@ struct nd_mapping {
 	u64 start;
 	u64 size;
 	int position;
+	int labels_uuid_num;
 	struct list_head labels;
 	struct mutex lock;
 	/*
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index e7377f1028ef..cb10cd2045ef 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -1049,6 +1049,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
 		nd_region->mapping[i].size = mapping->size;
 		nd_region->mapping[i].position = mapping->position;
 		INIT_LIST_HEAD(&nd_region->mapping[i].labels);
+		nd_region->mapping[i].labels_uuid_num = 0;
 		mutex_init(&nd_region->mapping[i].lock);
 
 		get_device(&nvdimm->dev);
-- 
2.19.1

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

  parent reply	other threads:[~2019-01-28  0:31 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-28  0:30 [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
2019-01-28  0:30 ` [PATCH 2/5] libnvdimm, namespace: remove special handling when count == 0 Wei Yang
2019-01-28  0:30 ` [PATCH 3/5] libnvdimm, label: return nd_label directly instead of calculating it again Wei Yang
2019-01-28  0:30 ` [PATCH 4/5] libnvdimm, namespace: extract __init_active_labels to initialize labels for one nd_mapping Wei Yang
2019-01-28  0:30 ` Wei Yang [this message]
2019-02-01  6:42 ` [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190128003018.4087-5-richardw.yang@linux.intel.com \
    --to=richardw.yang@linux.intel.com \
    --cc=linux-nvdimm@lists.01.org \
    --cc=zwisler@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.