s390/mm: prevent memory offline for memory blocks with cma areas
Memory blocks that contain areas for the contiguous memory allocator (cma) should not be allowed to go offline. Otherwise this would render cma completely useless. This might make sense on other architectures where memory might be taken offline due to hardware errors, but not on architectures which support memory hotplug for load balancing. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
16f4864171
commit
34ad7cdc1b
|
@ -26,6 +26,7 @@
|
|||
#include <linux/poison.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/cma.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <asm/processor.h>
|
||||
|
@ -167,6 +168,58 @@ unsigned long memory_block_size_bytes(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
||||
|
||||
#ifdef CONFIG_CMA
|
||||
|
||||
/* Prevent memory blocks which contain cma regions from going offline */
|
||||
|
||||
struct s390_cma_mem_data {
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
};
|
||||
|
||||
static int s390_cma_check_range(struct cma *cma, void *data)
|
||||
{
|
||||
struct s390_cma_mem_data *mem_data;
|
||||
unsigned long start, end;
|
||||
|
||||
mem_data = data;
|
||||
start = cma_get_base(cma);
|
||||
end = start + cma_get_size(cma);
|
||||
if (end < mem_data->start)
|
||||
return 0;
|
||||
if (start >= mem_data->end)
|
||||
return 0;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static int s390_cma_mem_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct s390_cma_mem_data mem_data;
|
||||
struct memory_notify *arg;
|
||||
int rc = 0;
|
||||
|
||||
arg = data;
|
||||
mem_data.start = arg->start_pfn << PAGE_SHIFT;
|
||||
mem_data.end = mem_data.start + (arg->nr_pages << PAGE_SHIFT);
|
||||
if (action == MEM_GOING_OFFLINE)
|
||||
rc = cma_for_each_area(s390_cma_check_range, &mem_data);
|
||||
return notifier_from_errno(rc);
|
||||
}
|
||||
|
||||
static struct notifier_block s390_cma_mem_nb = {
|
||||
.notifier_call = s390_cma_mem_notifier,
|
||||
};
|
||||
|
||||
static int __init s390_cma_mem_init(void)
|
||||
{
|
||||
return register_memory_notifier(&s390_cma_mem_nb);
|
||||
}
|
||||
device_initcall(s390_cma_mem_init);
|
||||
|
||||
#endif /* CONFIG_CMA */
|
||||
|
||||
int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
|
||||
{
|
||||
unsigned long start_pfn = PFN_DOWN(start);
|
||||
|
|
Loading…
Reference in New Issue