Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d689c137 authored by Dan Williams's avatar Dan Williams Committed by Greg Kroah-Hartman
Browse files

tools/testing/nvdimm: Align test resources to 128M



[ Upstream commit e3f5df762d4a6ef6326c3c09bc9f89ea8a2eab2c ]

In preparation for libnvdimm growing new restrictions to detect section
conflicts between persistent memory regions, enable nfit_test to
allocate aligned resources. Use a gen_pool to allocate nfit_test's fake
resources in a separate address space from the virtual translation of
the same.

Reviewed-by: default avatarVishal Verma <vishal.l.verma@intel.com>
Tested-by: default avatarVishal Verma <vishal.l.verma@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 878275fa
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/dma-mapping.h>
#include <linux/workqueue.h>
#include <linux/libnvdimm.h>
#include <linux/genalloc.h>
#include <linux/vmalloc.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -213,6 +214,8 @@ struct nfit_test {

static struct workqueue_struct *nfit_wq;

static struct gen_pool *nfit_pool;

static struct nfit_test *to_nfit_test(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
@@ -1130,6 +1133,9 @@ static void release_nfit_res(void *data)
	list_del(&nfit_res->list);
	spin_unlock(&nfit_test_lock);

	if (resource_size(&nfit_res->res) >= DIMM_SIZE)
		gen_pool_free(nfit_pool, nfit_res->res.start,
				resource_size(&nfit_res->res));
	vfree(nfit_res->buf);
	kfree(nfit_res);
}
@@ -1142,7 +1148,7 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,
			GFP_KERNEL);
	int rc;

	if (!buf || !nfit_res)
	if (!buf || !nfit_res || !*dma)
		goto err;
	rc = devm_add_action(dev, release_nfit_res, nfit_res);
	if (rc)
@@ -1162,6 +1168,8 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,

	return nfit_res->buf;
 err:
	if (*dma && size >= DIMM_SIZE)
		gen_pool_free(nfit_pool, *dma, size);
	if (buf)
		vfree(buf);
	kfree(nfit_res);
@@ -1170,8 +1178,15 @@ static void *__test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma,

static void *test_alloc(struct nfit_test *t, size_t size, dma_addr_t *dma)
{
	struct genpool_data_align data = {
		.align = SZ_128M,
	};
	void *buf = vmalloc(size);

	if (size >= DIMM_SIZE)
		*dma = gen_pool_alloc_algo(nfit_pool, size,
				gen_pool_first_fit_align, &data);
	else
		*dma = (unsigned long) buf;
	return __test_alloc(t, size, dma, buf);
}
@@ -2837,6 +2852,17 @@ static __init int nfit_test_init(void)
		goto err_register;
	}

	nfit_pool = gen_pool_create(ilog2(SZ_4M), NUMA_NO_NODE);
	if (!nfit_pool) {
		rc = -ENOMEM;
		goto err_register;
	}

	if (gen_pool_add(nfit_pool, SZ_4G, SZ_4G, NUMA_NO_NODE)) {
		rc = -ENOMEM;
		goto err_register;
	}

	for (i = 0; i < NUM_NFITS; i++) {
		struct nfit_test *nfit_test;
		struct platform_device *pdev;
@@ -2892,6 +2918,9 @@ static __init int nfit_test_init(void)
	return 0;

 err_register:
	if (nfit_pool)
		gen_pool_destroy(nfit_pool);

	destroy_workqueue(nfit_wq);
	for (i = 0; i < NUM_NFITS; i++)
		if (instances[i])
@@ -2915,6 +2944,8 @@ static __exit void nfit_test_exit(void)
	platform_driver_unregister(&nfit_test_driver);
	nfit_test_teardown();

	gen_pool_destroy(nfit_pool);

	for (i = 0; i < NUM_NFITS; i++)
		put_device(&instances[i]->pdev.dev);
	class_destroy(nfit_test_dimm);