Re: [PATCH 15/25] device-dax: use the dev_pagemap internal refcount

From: Dan Williams
Date: Tue Jun 18 2019 - 15:49:18 EST


On Mon, Jun 17, 2019 at 5:28 AM Christoph Hellwig <hch@xxxxxx> wrote:
>
> The functionality is identical to the one currently open coded in
> device-dax.
>
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
> drivers/dax/dax-private.h | 4 ----
> drivers/dax/device.c | 43 ---------------------------------------
> 2 files changed, 47 deletions(-)

This needs the mock devm_memremap_pages() to setup the common
percpu_ref. Incremental patch attached:
From 875e71489c8485448a5b7df2d8a8b2ed77d2b555 Mon Sep 17 00:00:00 2001
From: Dan Williams <dan.j.williams@xxxxxxxxx>
Date: Tue, 18 Jun 2019 11:58:24 -0700
Subject: [PATCH] tools/testing/nvdimm: Support the 'internal' ref of
dev_pagemap

For users of the common percpu-ref implementation, like device-dax,
arrange for nfit_test to initialize the common parameters.

Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
---
tools/testing/nvdimm/test/iomap.c | 41 ++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index 3bc1c16c4ef9..9019dd8afbc1 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -108,8 +108,6 @@ static void nfit_test_kill(void *_pgmap)
{
struct dev_pagemap *pgmap = _pgmap;

- WARN_ON(!pgmap || !pgmap->ref);
-
if (pgmap->ops && pgmap->ops->kill)
pgmap->ops->kill(pgmap);
else
@@ -123,20 +121,45 @@ static void nfit_test_kill(void *_pgmap)
}
}

+static void dev_pagemap_percpu_release(struct percpu_ref *ref)
+{
+ struct dev_pagemap *pgmap =
+ container_of(ref, struct dev_pagemap, internal_ref);
+
+ complete(&pgmap->done);
+}
+
void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
{
+ int error;
resource_size_t offset = pgmap->res.start;
struct nfit_test_resource *nfit_res = get_nfit_res(offset);

- if (nfit_res) {
- int rc;
+ if (!nfit_res)
+ return devm_memremap_pages(dev, pgmap);

- rc = devm_add_action_or_reset(dev, nfit_test_kill, pgmap);
- if (rc)
- return ERR_PTR(rc);
- return nfit_res->buf + offset - nfit_res->res.start;
+ pgmap->dev = dev;
+ if (!pgmap->ref) {
+ if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup))
+ return ERR_PTR(-EINVAL);
+
+ init_completion(&pgmap->done);
+ error = percpu_ref_init(&pgmap->internal_ref,
+ dev_pagemap_percpu_release, 0, GFP_KERNEL);
+ if (error)
+ return ERR_PTR(error);
+ pgmap->ref = &pgmap->internal_ref;
+ } else {
+ if (!pgmap->ops || !pgmap->ops->kill || !pgmap->ops->cleanup) {
+ WARN(1, "Missing reference count teardown definition\n");
+ return ERR_PTR(-EINVAL);
+ }
}
- return devm_memremap_pages(dev, pgmap);
+
+ error = devm_add_action_or_reset(dev, nfit_test_kill, pgmap);
+ if (error)
+ return ERR_PTR(error);
+ return nfit_res->buf + offset - nfit_res->res.start;
}
EXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages);

--
2.20.1