Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91ddce1b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mm/memblock: fix a race between search and remove"

parents 1b1ec93f 4476e8d9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -184,8 +184,10 @@ static void removed_region_fixup(struct removed_region *dma_mem, int index)
		return;

	/* carve-out */
	memblock_region_resize_late_begin();
	memblock_free(dma_mem->base, dma_mem->nr_pages * PAGE_SIZE);
	memblock_remove(dma_mem->base, index * PAGE_SIZE);
	memblock_region_resize_late_end();

	/* clear page-mappings */
	base_pfn = dma_mem->base >> PAGE_SHIFT;
+2 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size);
void memblock_trim_memory(phys_addr_t align);
int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
void memblock_region_resize_late_begin(void);
void memblock_region_resize_late_end(void);

/* Low level functions */
int memblock_add_range(struct memblock_type *type,
+43 −1
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/memblock.h>
#include <linux/preempt.h>
#include <linux/seqlock.h>

#include <asm-generic/sections.h>
#include <linux/io.h>
@@ -31,6 +33,7 @@ static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIO
static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS] __initdata_memblock;
#endif

static seqcount_t memblock_seq;
struct memblock memblock __initdata_memblock = {
	.memory.regions		= memblock_memory_init_regions,
	.memory.cnt		= 1,	/* empty dummy entry */
@@ -1375,7 +1378,7 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
			      (phys_addr_t)ULLONG_MAX);
}

static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
static int __init_memblock __memblock_search(struct memblock_type *type, phys_addr_t addr)
{
	unsigned int left = 0, right = type->cnt;

@@ -1393,6 +1396,19 @@ static int __init_memblock memblock_search(struct memblock_type *type, phys_addr
	return -1;
}

static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
{
	int ret;
	unsigned long seq;

	do {
		seq = raw_read_seqcount_begin(&memblock_seq);
		ret = __memblock_search(type, addr);
	} while (unlikely(read_seqcount_retry(&memblock_seq, seq)));

	return ret;
}

int __init memblock_is_reserved(phys_addr_t addr)
{
	return memblock_search(&memblock.reserved, addr) != -1;
@@ -1541,6 +1557,32 @@ void __init memblock_allow_resize(void)
	memblock_can_resize = 1;
}

static void __init_memblock memblock_resize_late(int begin)
{
	static int memblock_can_resize_old;

	if (begin) {
		preempt_disable();
		memblock_can_resize_old = memblock_can_resize;
		memblock_can_resize = 0;
		raw_write_seqcount_begin(&memblock_seq);
	} else {
		raw_write_seqcount_end(&memblock_seq);
		memblock_can_resize = memblock_can_resize_old;
		preempt_enable();
	}
}

void __init_memblock memblock_region_resize_late_begin(void)
{
	memblock_resize_late(1);
}

void __init_memblock memblock_region_resize_late_end(void)
{
	memblock_resize_late(0);
}

static int __init early_memblock(char *p)
{
	if (p && strstr(p, "debug"))