Since this protection may break userspace tools, it should be an opt-in until those tools have time to update to the new daxN.M/hotplug interface instead of memory blocks.
Suggested-by: Dan Williams <[email protected]> Signed-off-by: Gregory Price <[email protected]> --- drivers/dax/Kconfig | 18 ++++++++++++++++++ drivers/dax/kmem.c | 29 ++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig index d656e4c0eb84..cc13c22eb8f8 100644 --- a/drivers/dax/Kconfig +++ b/drivers/dax/Kconfig @@ -78,4 +78,22 @@ config DEV_DAX_KMEM Say N if unsure. +config DEV_DAX_KMEM_PROTECTED + bool "Protect DAX_KMEM memory blocks being changed" + depends on DEV_DAX_KMEM + default n + help + Prevents actions from outside the KMEM DAX driver from changing + DAX KMEM memory block states. For example, the memory block + sysfs functions (online, state) will return -EBUSY, and normal + calls to memory_hotplug functions from other drivers and kernel + sources will fail. + + This may break existing memory block management patterns that + depend on offlining DAX KMEM blocks from userland before unbinding + the driver. Use this only if your tools have been updated to use + the daxN.M/hotplug interface. + + Say N if unsure. + endif diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c index f3562f65376c..094b8a51099e 100644 --- a/drivers/dax/kmem.c +++ b/drivers/dax/kmem.c @@ -184,6 +184,21 @@ static int dax_kmem_memory_notifier_cb(struct notifier_block *nb, return NOTIFY_BAD; } +static int dax_kmem_register_notifier(struct dax_kmem_data *data) +{ + if (!IS_ENABLED(DEV_DAX_KMEM_PROTECTED)) + return 0; + data->mem_nb.notifier_call = dax_kmem_memory_notifier_cb; + return register_memory_notifier(&data->mem_nb); +} + +static void dax_kmem_unregister_notifier(struct dax_kmem_data *data) +{ + if (!IS_ENABLED(DEV_DAX_KMEM_PROTECTED)) + return; + unregister_memory_notifier(&data->mem_nb); +} + /** * dax_kmem_do_hotplug - hotplug memory for dax kmem device * @dev_dax: the dev_dax instance @@ -563,13 +578,9 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) if (rc < 0) goto err_resources; - /* Register memory notifier to block external operations */ - data->mem_nb.notifier_call = dax_kmem_memory_notifier_cb; - rc = register_memory_notifier(&data->mem_nb); - if (rc) { - dev_warn(dev, "failed to register memory notifier\n"); + rc = dax_kmem_register_notifier(data); + if (rc) goto err_notifier; - } /* * Hotplug using the system default policy - this preserves backwards @@ -595,7 +606,7 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) return 0; err_hotplug: - unregister_memory_notifier(&data->mem_nb); + dax_kmem_unregister_notifier(data); err_notifier: dax_kmem_cleanup_resources(dev_dax, data); err_resources: @@ -619,7 +630,7 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax) device_remove_file(dev, &dev_attr_hotplug); dax_kmem_cleanup_resources(dev_dax, data); - unregister_memory_notifier(&data->mem_nb); + dax_kmem_unregister_notifier(data); memory_group_unregister(data->mgid); kfree(data->res_name); kfree(data); @@ -640,7 +651,7 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax) struct dax_kmem_data *data = dev_get_drvdata(dev); device_remove_file(dev, &dev_attr_hotplug); - unregister_memory_notifier(&data->mem_nb); + dax_kmem_unregister_notifier(data); /* * Without hotremove purposely leak the request_mem_region() for the -- 2.52.0

