libnvdimm/region: Register badblocks before namespaces [Linux 4.19.66]

This Linux kernel change "libnvdimm/region: Register badblocks before namespaces" is included in the Linux 4.19.66 release. This change is authored by Dan Williams <dan.j.williams [at] intel.com> on Mon Aug 5 18:32:02 2019 -0700. The commit for this change in Linux stable tree is 3248536 (patch) which is from upstream commit 700cd03. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 700cd03.

libnvdimm/region: Register badblocks before namespaces

commit 700cd033a82d466ad8f9615f9985525e45f8960a upstream.

Namespace activation expects to be able to reference region badblocks.
The following warning sometimes triggers when asynchronous namespace
activation races in front of the completion of namespace probing. Move
all possible namespace probing after region badblocks initialization.

Otherwise, lockdep sometimes catches the uninitialized state of the
badblocks seqlock with stack trace signatures like:

    INFO: trying to register non-static key.
    pmem2: detected capacity change from 0 to 136365211648
    the code is fine but needs lockdep annotation.
    turning off the locking correctness validator.
    CPU: 9 PID: 358 Comm: kworker/u80:5 Tainted: G           OE     5.2.0-rc4+ #3382
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
    Workqueue: events_unbound async_run_entry_fn
    Call Trace:
     dump_stack+0x85/0xc0
    pmem1.12: detected capacity change from 0 to 8589934592
     register_lock_class+0x56a/0x570
     ? check_object+0x140/0x270
     __lock_acquire+0x80/0x1710
     ? __mutex_lock+0x39d/0x910
     lock_acquire+0x9e/0x180
     ? nd_pfn_validate+0x28f/0x440 [libnvdimm]
     badblocks_check+0x93/0x1f0
     ? nd_pfn_validate+0x28f/0x440 [libnvdimm]
     nd_pfn_validate+0x28f/0x440 [libnvdimm]
     ? lockdep_hardirqs_on+0xf0/0x180
     nd_dax_probe+0x9a/0x120 [libnvdimm]
     nd_pmem_probe+0x6d/0x180 [nd_pmem]
     nvdimm_bus_probe+0x90/0x2c0 [libnvdimm]

Fixes: 48af2f7e52f4 ("libnvdimm, pfn: during init, clear errors...")
Cc: <stable@vger.kernel.org>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
Link: https://lore.kernel.org/r/156341208365.292348.1547528796026249120.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>

There are 22 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/nvdimm/region.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c
index b9ca003..f9130cc 100644
--- a/drivers/nvdimm/region.c
+++ b/drivers/nvdimm/region.c
@@ -42,17 +42,6 @@ static int nd_region_probe(struct device *dev)
    if (rc)
        return rc;

-   rc = nd_region_register_namespaces(nd_region, &err);
-   if (rc < 0)
-       return rc;
-
-   ndrd = dev_get_drvdata(dev);
-   ndrd->ns_active = rc;
-   ndrd->ns_count = rc + err;
-
-   if (rc && err && rc == err)
-       return -ENODEV;
-
    if (is_nd_pmem(&nd_region->dev)) {
        struct resource ndr_res;

@@ -68,6 +57,17 @@ static int nd_region_probe(struct device *dev)
        nvdimm_badblocks_populate(nd_region, &nd_region->bb, &ndr_res);
    }

+   rc = nd_region_register_namespaces(nd_region, &err);
+   if (rc < 0)
+       return rc;
+
+   ndrd = dev_get_drvdata(dev);
+   ndrd->ns_active = rc;
+   ndrd->ns_count = rc + err;
+
+   if (rc && err && rc == err)
+       return -ENODEV;
+
    nd_region->btt_seed = nd_btt_create(nd_region);
    nd_region->pfn_seed = nd_pfn_create(nd_region);
    nd_region->dax_seed = nd_dax_create(nd_region);

Leave a Reply

Your email address will not be published. Required fields are marked *