mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
soc: qcom: mem-offline: online only valid memory blocks
mem-offline driver onlines blocks between memory_limit to end of DDR, but for some cases when using large ram size, the range may not be contiguous. We online un-existed memory blocks in this case. Example - RAM Entry 0 : Base 0x0080000000 Size 0x0033E00000 RAM Entry 1 : Base 0x0200000000 Size 0x0200000000 RAM Entry 2 : Base 0x0800000000 Size 0x0100000000 RAM Entry 3 : Base 0x00C0000000 Size 0x0140000000 if offline-size is 5GB and total memory size is 18GB, we onlined also un-existed range [0x400000000,0x800000000] in mem_online_remaining_blocks(). To fix this, Do parsing the DT tree again and updated bitmap accordingly. Use this bitmap to online memory blocks. Change-Id: I5ea94a0ea9dca10e3a3311d6ea53a14302a41ae5 Signed-off-by: Zhenhua Huang <zhenhuah@codeaurora.org>
This commit is contained in:
parent
e18073515c
commit
df12e38f23
1 changed files with 68 additions and 0 deletions
|
|
@ -49,6 +49,7 @@ static bool is_rpm_controller;
|
|||
static bool has_pend_offline_req;
|
||||
static atomic_long_t totalram_pages_with_offline = ATOMIC_INIT(0);
|
||||
static struct workqueue_struct *migrate_wq;
|
||||
static unsigned long movable_bitmap;
|
||||
|
||||
#define MODULE_CLASS_NAME "mem-offline"
|
||||
#define MIGRATE_TIMEOUT_SEC (20)
|
||||
|
|
@ -752,6 +753,63 @@ static int mem_event_callback(struct notifier_block *self,
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int update_movable_bitmap(void)
|
||||
{
|
||||
struct device_node *node;
|
||||
struct property *prop;
|
||||
int len, num_cells, num_entries;
|
||||
u64 base, size, end, section_size;
|
||||
u64 movable_start, movable_end;
|
||||
int nr_address_cells, nr_size_cells;
|
||||
const __be32 *pos;
|
||||
|
||||
node = of_find_node_by_name(of_root, "memory");
|
||||
if (!node) {
|
||||
pr_err("mem-offine: memory node not found in DT\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nr_address_cells = of_n_addr_cells(of_root);
|
||||
nr_size_cells = of_n_size_cells(of_root);
|
||||
|
||||
prop = of_find_property(node, "reg", &len);
|
||||
|
||||
num_cells = len / sizeof(__be32);
|
||||
num_entries = num_cells / (nr_address_cells + nr_size_cells);
|
||||
|
||||
pos = prop->value;
|
||||
|
||||
section_size = MIN_MEMORY_BLOCK_SIZE;
|
||||
movable_start = memblock_end_of_DRAM();
|
||||
movable_end = bootloader_memory_limit - 1;
|
||||
|
||||
while (num_entries--) {
|
||||
u64 new_base, new_end;
|
||||
u64 new_start_bitmap, bitmap_size;
|
||||
|
||||
base = of_read_number(pos, nr_address_cells);
|
||||
size = of_read_number(pos + nr_address_cells, nr_size_cells);
|
||||
pos += nr_address_cells + nr_size_cells;
|
||||
end = base + size;
|
||||
|
||||
if (end <= movable_start)
|
||||
continue;
|
||||
|
||||
if (base < movable_start)
|
||||
new_base = movable_start;
|
||||
else
|
||||
new_base = base;
|
||||
new_end = end;
|
||||
|
||||
new_start_bitmap = (new_base - movable_start) / section_size;
|
||||
bitmap_size = (new_end - new_base) / section_size;
|
||||
bitmap_set(&movable_bitmap, new_start_bitmap, bitmap_size);
|
||||
}
|
||||
|
||||
pr_debug("mem-offline: movable_bitmap is %lx\n", movable_bitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mem_online_remaining_blocks(void)
|
||||
{
|
||||
unsigned long memblock_end_pfn = __phys_to_pfn(memblock_end_of_DRAM());
|
||||
|
|
@ -760,6 +818,7 @@ static int mem_online_remaining_blocks(void)
|
|||
unsigned int nid;
|
||||
phys_addr_t phys_addr;
|
||||
int fail = 0;
|
||||
int ret;
|
||||
|
||||
block_size = memory_block_size_bytes();
|
||||
sections_per_block = block_size / MIN_MEMORY_BLOCK_SIZE;
|
||||
|
|
@ -771,8 +830,17 @@ static int mem_online_remaining_blocks(void)
|
|||
pr_info("mem-offline: System booted with no zone movable memory blocks. Cannot perform memory offlining\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = update_movable_bitmap();
|
||||
if (ret < 0)
|
||||
return -ENODEV;
|
||||
|
||||
for (memblock = start_section_nr; memblock <= end_section_nr;
|
||||
memblock += sections_per_block) {
|
||||
|
||||
if (!test_bit(memblock - start_section_nr, &movable_bitmap))
|
||||
continue;
|
||||
|
||||
pfn = section_nr_to_pfn(memblock);
|
||||
phys_addr = __pfn_to_phys(pfn);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue