arm64: Add "remove" probe driver for memory hot-remove

Allows to remove sections of memory that have been previously offlined
from userspace.

This is symmetric to the "memory probe" interface, as described in
Documentation/memory-hotplug.txt. It can be used to manually notify the
OS that one memory section has been removed.

Please, remind that a memory section can only be removed after it has
been logically off-lined; trying to remove a section which has not been
previously off-lined is not supported and will have undefined (but most
likely very bad) behaviour.

To offline a section one can:

To use the remove interface to remove the section:

where 0xYYYYYY is the physical address of the memory section to remove.

Change-Id: I1ab2fafe17b2697a5c667feae25c4ac0655f394e
Signed-off-by: Andrea Reale <ar@linux.vnet.ibm.com>
Signed-off-by: Maciej Bielski <m.bielski@virtualopensystems.com>
Patch-mainline: linux-kernel @ 11 Apr 2017, 18:25
Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
Signed-off-by: Sudarshan Rajagopalan <sudaraja@codeaurora.org>
[isaacm@codeaurora.org: resolved merge conflicts due to API changes]
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
Andrea Reale 2017-04-28 14:20:16 +05:30 • committed by Isaac J. Manjarres
commit 791f0d4beb

View file

@ -519,7 +519,36 @@ out:
}
static DEVICE_ATTR_WO(probe);
#endif
#ifdef CONFIG_MEMORY_HOTREMOVE
static ssize_t remove_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
u64 phys_addr;
int nid, ret;
unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block;
ret = kstrtoull(buf, 0, &phys_addr);
if (ret)
return ret;
if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
return -EINVAL;
nid = memory_add_physaddr_to_nid(phys_addr);
ret = lock_device_hotplug_sysfs();
if (ret)
return ret;
remove_memory(nid, phys_addr,
MIN_MEMORY_BLOCK_SIZE * sections_per_block);
unlock_device_hotplug();
return count;
}
static DEVICE_ATTR_WO(remove);
#endif /* CONFIG_MEMORY_HOTREMOVE */
#endif /* CONFIG_ARCH_MEMORY_PROBE */
#ifdef CONFIG_MEMORY_FAILURE
/*
@ -775,6 +804,9 @@ bool is_memblock_offlined(struct memory_block *mem)
static struct attribute *memory_root_attrs[] = {
#ifdef CONFIG_ARCH_MEMORY_PROBE
&dev_attr_probe.attr,
#ifdef CONFIG_MEMORY_HOTREMOVE
&dev_attr_remove.attr,
#endif
#endif
#ifdef CONFIG_MEMORY_FAILURE