* [PATCH 1/5] libnvdimm, namespace: release labels properly on error
@ 2019-01-28 0:30 Wei Yang
2019-01-28 0:30 ` [PATCH 2/5] libnvdimm, namespace: remove special handling when count == 0 Wei Yang
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Wei Yang @ 2019-01-28 0:30 UTC (permalink / raw)
To: linux-nvdimm; +Cc: zwisler
In init_active_labels(), it iterates on ndr_mappings to create its
corresponding labels. When there is an error, it is supposed to release
those labels created. But current implementation doesn't handle this
well in two aspects:
* when error happens during ndd check, labels are not released
* just labels on current nd_mapping released, previous ones are lost
This patch extracts labels releasing code to error branch and release
labels on all nd_mapping besides only current one. By goto error branch
on error, it release all labels allocated.
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
drivers/nvdimm/namespace_devs.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 9471b9ca04f5..234c0c79726a 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2451,7 +2451,7 @@ static struct device **create_namespaces(struct nd_region *nd_region)
static int init_active_labels(struct nd_region *nd_region)
{
- int i;
+ int i, errno = -ENOMEM;
for (i = 0; i < nd_region->ndr_mappings; i++) {
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
@@ -2476,7 +2476,8 @@ static int init_active_labels(struct nd_region *nd_region)
dev_name(&nd_mapping->nvdimm->dev),
test_bit(NDD_LOCKED, &nvdimm->flags)
? "locked" : "disabled");
- return -ENXIO;
+ errno = -ENXIO;
+ goto error;
}
nd_mapping->ndd = ndd;
atomic_inc(&nvdimm->busy);
@@ -2500,16 +2501,20 @@ static int init_active_labels(struct nd_region *nd_region)
mutex_unlock(&nd_mapping->lock);
}
- if (j >= count)
- continue;
+ if (j < count)
+ goto error;
+ }
+
+ return 0;
+error:
+ for (; i >= 0; i--) {
+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
mutex_lock(&nd_mapping->lock);
nd_mapping_free_labels(nd_mapping);
mutex_unlock(&nd_mapping->lock);
- return -ENOMEM;
}
-
- return 0;
+ return errno;
}
int nd_region_register_namespaces(struct nd_region *nd_region, int *err)
--
2.19.1
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] libnvdimm, namespace: remove special handling when count == 0
2019-01-28 0:30 [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
@ 2019-01-28 0:30 ` Wei Yang
2019-01-28 0:30 ` [PATCH 3/5] libnvdimm, label: return nd_label directly instead of calculating it again Wei Yang
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Wei Yang @ 2019-01-28 0:30 UTC (permalink / raw)
To: linux-nvdimm; +Cc: zwisler
This is reasonable to continue directly when count == 0, while this case
could be merged in following for loop.
count == 0, j == 0 => j >= count, loop continues.
This patch just removes the special handling to make the code look more
neat.
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
drivers/nvdimm/namespace_devs.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 234c0c79726a..0d64c4b38a56 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2485,8 +2485,6 @@ static int init_active_labels(struct nd_region *nd_region)
count = nd_label_active_count(ndd);
dev_dbg(ndd->dev, "count: %d\n", count);
- if (!count)
- continue;
for (j = 0; j < count; j++) {
struct nd_namespace_label *label;
--
2.19.1
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] libnvdimm, label: return nd_label directly instead of calculating it again
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 ` 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
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Wei Yang @ 2019-01-28 0:30 UTC (permalink / raw)
To: linux-nvdimm; +Cc: zwisler
In nd_label_active(), we get nd_label from label area. While it is not
necessary to calculate it a second time.
This patch return nd_label directly.
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
drivers/nvdimm/label.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 750dbaa6ce82..63b7d40fe9d4 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -587,7 +587,7 @@ struct nd_namespace_label *nd_label_active(struct nvdimm_drvdata *ndd, int n)
continue;
if (n-- == 0)
- return to_label(ndd, slot);
+ return nd_label;
}
return NULL;
--
2.19.1
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] libnvdimm, namespace: extract __init_active_labels to initialize labels for one nd_mapping
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 ` Wei Yang
2019-01-28 0:30 ` [PATCH 5/5] libnvdimm, namespace: allocate devs for namespace just once Wei Yang
2019-02-01 6:42 ` [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
4 siblings, 0 replies; 6+ messages in thread
From: Wei Yang @ 2019-01-28 0:30 UTC (permalink / raw)
To: linux-nvdimm; +Cc: zwisler
This is a preparation for next patch, so that init_active_labels not too
huge.
Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
---
drivers/nvdimm/namespace_devs.c | 41 ++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 0d64c4b38a56..cdf3049bd2b9 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2449,6 +2449,29 @@ static struct device **create_namespaces(struct nd_region *nd_region)
return devs;
}
+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;
+ int j;
+
+ for (j = 0; j < count; j++) {
+ struct nd_namespace_label *label;
+
+ label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
+ if (!label_ent)
+ break;
+ label = nd_label_active(ndd, j);
+ label_ent->label = label;
+
+ mutex_lock(&nd_mapping->lock);
+ list_add_tail(&label_ent->list, &nd_mapping->labels);
+ mutex_unlock(&nd_mapping->lock);
+ }
+
+ return j;
+}
+
static int init_active_labels(struct nd_region *nd_region)
{
int i, errno = -ENOMEM;
@@ -2457,8 +2480,7 @@ static int init_active_labels(struct nd_region *nd_region)
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
struct nvdimm *nvdimm = nd_mapping->nvdimm;
- struct nd_label_ent *label_ent;
- int count, j;
+ int count;
/*
* If the dimm is disabled then we may need to prevent
@@ -2485,21 +2507,8 @@ static int init_active_labels(struct nd_region *nd_region)
count = nd_label_active_count(ndd);
dev_dbg(ndd->dev, "count: %d\n", count);
- for (j = 0; j < count; j++) {
- struct nd_namespace_label *label;
-
- label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
- if (!label_ent)
- break;
- label = nd_label_active(ndd, j);
- label_ent->label = label;
-
- mutex_lock(&nd_mapping->lock);
- list_add_tail(&label_ent->list, &nd_mapping->labels);
- mutex_unlock(&nd_mapping->lock);
- }
- if (j < count)
+ if (__init_active_labels(nd_mapping, count) < count)
goto error;
}
--
2.19.1
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] libnvdimm, namespace: allocate devs for namespace just once
2019-01-28 0:30 [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
` (2 preceding siblings ...)
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
2019-02-01 6:42 ` [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
4 siblings, 0 replies; 6+ messages in thread
From: Wei Yang @ 2019-01-28 0:30 UTC (permalink / raw)
To: linux-nvdimm; +Cc: zwisler
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/5] libnvdimm, namespace: release labels properly on error
2019-01-28 0:30 [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
` (3 preceding siblings ...)
2019-01-28 0:30 ` [PATCH 5/5] libnvdimm, namespace: allocate devs for namespace just once Wei Yang
@ 2019-02-01 6:42 ` Wei Yang
4 siblings, 0 replies; 6+ messages in thread
From: Wei Yang @ 2019-02-01 6:42 UTC (permalink / raw)
To: Wei Yang; +Cc: zwisler, linux-nvdimm
On Mon, Jan 28, 2019 at 08:30:14AM +0800, Wei Yang wrote:
>In init_active_labels(), it iterates on ndr_mappings to create its
>corresponding labels. When there is an error, it is supposed to release
>those labels created. But current implementation doesn't handle this
>well in two aspects:
>
> * when error happens during ndd check, labels are not released
> * just labels on current nd_mapping released, previous ones are lost
>
>This patch extracts labels releasing code to error branch and release
>labels on all nd_mapping besides only current one. By goto error branch
>on error, it release all labels allocated.
Is my understanding correct?
>
>Signed-off-by: Wei Yang <richardw.yang@linux.intel.com>
>---
> drivers/nvdimm/namespace_devs.c | 19 ++++++++++++-------
> 1 file changed, 12 insertions(+), 7 deletions(-)
>
>diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
>index 9471b9ca04f5..234c0c79726a 100644
>--- a/drivers/nvdimm/namespace_devs.c
>+++ b/drivers/nvdimm/namespace_devs.c
>@@ -2451,7 +2451,7 @@ static struct device **create_namespaces(struct nd_region *nd_region)
>
> static int init_active_labels(struct nd_region *nd_region)
> {
>- int i;
>+ int i, errno = -ENOMEM;
>
> for (i = 0; i < nd_region->ndr_mappings; i++) {
> struct nd_mapping *nd_mapping = &nd_region->mapping[i];
>@@ -2476,7 +2476,8 @@ static int init_active_labels(struct nd_region *nd_region)
> dev_name(&nd_mapping->nvdimm->dev),
> test_bit(NDD_LOCKED, &nvdimm->flags)
> ? "locked" : "disabled");
>- return -ENXIO;
>+ errno = -ENXIO;
>+ goto error;
> }
> nd_mapping->ndd = ndd;
> atomic_inc(&nvdimm->busy);
>@@ -2500,16 +2501,20 @@ static int init_active_labels(struct nd_region *nd_region)
> mutex_unlock(&nd_mapping->lock);
> }
>
>- if (j >= count)
>- continue;
>+ if (j < count)
>+ goto error;
>+ }
>+
>+ return 0;
>
>+error:
>+ for (; i >= 0; i--) {
>+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
> mutex_lock(&nd_mapping->lock);
> nd_mapping_free_labels(nd_mapping);
> mutex_unlock(&nd_mapping->lock);
>- return -ENOMEM;
> }
>-
>- return 0;
>+ return errno;
> }
>
> int nd_region_register_namespaces(struct nd_region *nd_region, int *err)
>--
>2.19.1
--
Wei Yang
Help you, Help me
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-02-01 6:42 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH 5/5] libnvdimm, namespace: allocate devs for namespace just once Wei Yang
2019-02-01 6:42 ` [PATCH 1/5] libnvdimm, namespace: release labels properly on error Wei Yang
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.