hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAO4WG
--------------------------------------------
After a device is hot-added, the locality information which is initialized in the boot time will be removed after performing the hot-remove procedure. Let the hot-added device using the static HMAT locality information when _HMA is specificed and a empty buffer is returned, which means no update of the system locality information since boot time.
Signed-off-by: Zhang Zekun zhangzekun11@huawei.com --- drivers/acpi/acpi_memhotplug.c | 13 +++++++++++++ drivers/acpi/internal.h | 1 + drivers/acpi/numa/hmat.c | 17 +++++++++++++++++ 3 files changed, 31 insertions(+)
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index e9b9e2db32cf..1cd7b8489b62 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -224,6 +224,19 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) hotplug_mdev[node] = mem_device->device; num_enabled++; } + if (acpi_has_method(handle, "_HMA")) { + acpi_status status; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + status = acpi_evaluate_object(handle, "_HMA", NULL, &buffer); + if (ACPI_SUCCESS(status) && buffer.length) { + union acpi_object *obj = buffer.pointer; + + if (!obj->buffer.length) + hmat_restore_target(node); + } + } + if (!num_enabled) { dev_err(&mem_device->device->dev, "add_memory failed\n"); return -EINVAL; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 5ac34c0eeb47..82444a4cbf15 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -265,5 +265,6 @@ void acpi_init_lpit(void); #else static inline void acpi_init_lpit(void) { } #endif +void hmat_restore_target(int nid);
#endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 26453a945da4..5be7334c51f3 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -723,6 +723,23 @@ static void hmat_register_target_devices(struct memory_target *target) } }
+void hmat_restore_target(int nid) +{ + struct memory_target *target; + int pxm; + + pxm = node_to_pxm(nid); + target = find_mem_target(pxm); + if (!target) + return; + + mutex_lock(&target_lock); + hmat_register_target_cache(target); + hmat_register_target_perf(target, 0); + hmat_register_target_perf(target, 1); + mutex_unlock(&target_lock); +} + static void hmat_register_target(struct memory_target *target) { int nid = pxm_to_node(target->memory_pxm);