Skip to content

Commit a6c7f4c

Browse files
djbwrafaeljw
authored andcommitted
device-dax: Add a driver for "hmem" devices
Platform firmware like EFI/ACPI may publish "hmem" platform devices. Such a device is a performance differentiated memory range likely reserved for an application specific use case. The driver gives access to 100% of the capacity via a device-dax mmap instance by default. However, if over-subscription and other kernel memory management is desired the resulting dax device can be assigned to the core-mm via the kmem driver. This consumes "hmem" devices the producer of "hmem" devices is saved for a follow-on patch so that it can reference the new CONFIG_DEV_DAX_HMEM symbol to gate performing the enumeration work. Reported-by: kbuild test robot <[email protected]> Reviewed-by: Dave Hansen <[email protected]> Signed-off-by: Dan Williams <[email protected]> Acked-by: Thomas Gleixner <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 460370a commit a6c7f4c

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

drivers/dax/Kconfig

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,36 @@ config DEV_DAX_PMEM
3232

3333
Say M if unsure
3434

35+
config DEV_DAX_HMEM
36+
tristate "HMEM DAX: direct access to 'specific purpose' memory"
37+
depends on EFI_SOFT_RESERVE
38+
default DEV_DAX
39+
help
40+
EFI 2.8 platforms, and others, may advertise 'specific purpose'
41+
memory. For example, a high bandwidth memory pool. The
42+
indication from platform firmware is meant to reserve the
43+
memory from typical usage by default. This driver creates
44+
device-dax instances for these memory ranges, and that also
45+
enables the possibility to assign them to the DEV_DAX_KMEM
46+
driver to override the reservation and add them to kernel
47+
"System RAM" pool.
48+
49+
Say M if unsure.
50+
3551
config DEV_DAX_KMEM
3652
tristate "KMEM DAX: volatile-use of persistent memory"
3753
default DEV_DAX
3854
depends on DEV_DAX
3955
depends on MEMORY_HOTPLUG # for add_memory() and friends
4056
help
41-
Support access to persistent memory as if it were RAM. This
42-
allows easier use of persistent memory by unmodified
43-
applications.
57+
Support access to persistent, or other performance
58+
differentiated memory as if it were System RAM. This allows
59+
easier use of persistent memory by unmodified applications, or
60+
adds core kernel memory services to heterogeneous memory types
61+
(HMEM) marked "reserved" by platform firmware.
4462

4563
To use this feature, a DAX device must be unbound from the
46-
device_dax driver (PMEM DAX) and bound to this kmem driver
47-
on each boot.
64+
device_dax driver and bound to this kmem driver on each boot.
4865

4966
Say N if unsure.
5067

drivers/dax/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
obj-$(CONFIG_DAX) += dax.o
33
obj-$(CONFIG_DEV_DAX) += device_dax.o
44
obj-$(CONFIG_DEV_DAX_KMEM) += kmem.o
5+
obj-$(CONFIG_DEV_DAX_HMEM) += dax_hmem.o
56

67
dax-y := super.o
78
dax-y += bus.o
89
device_dax-y := device.o
10+
dax_hmem-y := hmem.o
911

1012
obj-y += pmem/

drivers/dax/hmem.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/platform_device.h>
3+
#include <linux/memregion.h>
4+
#include <linux/module.h>
5+
#include <linux/pfn_t.h>
6+
#include "bus.h"
7+
8+
static int dax_hmem_probe(struct platform_device *pdev)
9+
{
10+
struct device *dev = &pdev->dev;
11+
struct dev_pagemap pgmap = { };
12+
struct dax_region *dax_region;
13+
struct memregion_info *mri;
14+
struct dev_dax *dev_dax;
15+
struct resource *res;
16+
17+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
18+
if (!res)
19+
return -ENOMEM;
20+
21+
mri = dev->platform_data;
22+
memcpy(&pgmap.res, res, sizeof(*res));
23+
24+
dax_region = alloc_dax_region(dev, pdev->id, res, mri->target_node,
25+
PMD_SIZE, PFN_DEV|PFN_MAP);
26+
if (!dax_region)
27+
return -ENOMEM;
28+
29+
dev_dax = devm_create_dev_dax(dax_region, 0, &pgmap);
30+
if (IS_ERR(dev_dax))
31+
return PTR_ERR(dev_dax);
32+
33+
/* child dev_dax instances now own the lifetime of the dax_region */
34+
dax_region_put(dax_region);
35+
return 0;
36+
}
37+
38+
static int dax_hmem_remove(struct platform_device *pdev)
39+
{
40+
/* devm handles teardown */
41+
return 0;
42+
}
43+
44+
static struct platform_driver dax_hmem_driver = {
45+
.probe = dax_hmem_probe,
46+
.remove = dax_hmem_remove,
47+
.driver = {
48+
.name = "hmem",
49+
},
50+
};
51+
52+
module_platform_driver(dax_hmem_driver);
53+
54+
MODULE_ALIAS("platform:hmem*");
55+
MODULE_LICENSE("GPL v2");
56+
MODULE_AUTHOR("Intel Corporation");

include/linux/memregion.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include <linux/types.h>
55
#include <linux/errno.h>
66

7+
struct memregion_info {
8+
int target_node;
9+
};
10+
711
#ifdef CONFIG_MEMREGION
812
int memregion_alloc(gfp_t gfp);
913
void memregion_free(int id);

0 commit comments

Comments
 (0)