Loading drivers/base/memory.c +19 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/mutex.h> #include <linux/stat.h> #include <linux/slab.h> #include <linux/memblock.h> #include <linux/atomic.h> #include <linux/uaccess.h> Loading Loading @@ -494,6 +495,18 @@ static ssize_t show_allocated_bytes(struct device *dev, return snprintf(buf, 100, "%lu\n", used); } static ssize_t show_aligned_blocks_addr(struct device *dev, struct device_attribute *attr, char *buf) { return memblock_dump_aligned_blocks_addr(buf); } static ssize_t show_aligned_blocks_num(struct device *dev, struct device_attribute *attr, char *buf) { return memblock_dump_aligned_blocks_num(buf); } #endif static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); Loading @@ -502,6 +515,8 @@ static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL); #ifdef CONFIG_MEMORY_HOTPLUG static DEVICE_ATTR(allocated_bytes, 0444, show_allocated_bytes, NULL); static DEVICE_ATTR(aligned_blocks_addr, 0444, show_aligned_blocks_addr, NULL); static DEVICE_ATTR(aligned_blocks_num, 0444, show_aligned_blocks_num, NULL); #endif /* Loading Loading @@ -886,6 +901,10 @@ static struct attribute *memory_root_attrs[] = { &dev_attr_block_size_bytes.attr, &dev_attr_auto_online_blocks.attr, #ifdef CONFIG_MEMORY_HOTPLUG &dev_attr_aligned_blocks_addr.attr, &dev_attr_aligned_blocks_num.attr, #endif NULL }; Loading include/linux/memblock.h +4 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,10 @@ int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); int memblock_mark_nomap(phys_addr_t base, phys_addr_t size); int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); #ifdef CONFIG_MEMORY_HOTPLUG int memblock_dump_aligned_blocks_addr(char *buf); int memblock_dump_aligned_blocks_num(char *buf); #endif ulong choose_memblock_flags(void); /* Low level functions */ Loading mm/memblock.c +111 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/debugfs.h> #include <linux/seq_file.h> #include <linux/memblock.h> #include <linux/memory.h> #include <asm/sections.h> #include <linux/io.h> Loading Loading @@ -1777,6 +1778,116 @@ static int __init early_memblock(char *p) } early_param("memblock", early_memblock); #ifdef CONFIG_MEMORY_HOTPLUG static phys_addr_t no_hotplug_area[8]; static phys_addr_t aligned_blocks[32]; static int __init early_no_hotplug_area(char *p) { phys_addr_t base, size; int idx = 0; char *endp = p; while (1) { base = memparse(endp, &endp); if (base && (*endp == ',')) { size = memparse(endp + 1, &endp); if (size) { no_hotplug_area[idx++] = base; no_hotplug_area[idx++] = base+size; if ((*endp == ';') && (idx <= 6)) endp++; else break; } else break; } else break; } return 0; } early_param("no_hotplug_area", early_no_hotplug_area); static bool __init memblock_in_no_hotplug_area(phys_addr_t addr) { int idx = 0; while (idx < 8) { if (!no_hotplug_area[idx]) break; if ((addr + MIN_MEMORY_BLOCK_SIZE <= no_hotplug_area[idx]) || (addr >= no_hotplug_area[idx+1])) { idx += 2; continue; } return true; } return false; } static int __init early_dyn_memhotplug(char *p) { int idx = 0; phys_addr_t addr, rgn_end; struct memblock_region *rgn; int blk = 0; while ((idx++) < memblock.memory.cnt) { rgn = &memblock.memory.regions[idx]; addr = ALIGN(rgn->base, MIN_MEMORY_BLOCK_SIZE); rgn_end = rgn->base + rgn->size; while (addr + MIN_MEMORY_BLOCK_SIZE <= rgn_end) { if (!memblock_in_no_hotplug_area(addr)) { aligned_blocks[blk++] = addr; memblock_remove(addr, MIN_MEMORY_BLOCK_SIZE); } addr += MIN_MEMORY_BLOCK_SIZE; } } return 0; } early_param("dyn_memhotplug", early_dyn_memhotplug); int memblock_dump_aligned_blocks_addr(char *buf) { int idx = 0; int size = 0; if (aligned_blocks[idx]) { size += snprintf(buf+size, 32, "0x%llx", aligned_blocks[idx]); idx++; } while (aligned_blocks[idx]) { size += snprintf(buf+size, 32, ",0x%llx", aligned_blocks[idx]); idx++; } return size; } int memblock_dump_aligned_blocks_num(char *buf) { int idx = 0; int size = 0; if (aligned_blocks[idx]) { size += snprintf(buf+size, 16, "%d", (int)(aligned_blocks[idx] >> SECTION_SIZE_BITS)); idx++; } while (aligned_blocks[idx]) { size += snprintf(buf+size, 16, ",%d", (int)(aligned_blocks[idx] >> SECTION_SIZE_BITS)); idx++; } return size; } #endif #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_ARCH_DISCARD_MEMBLOCK) static int memblock_debug_show(struct seq_file *m, void *private) Loading Loading
drivers/base/memory.c +19 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/mutex.h> #include <linux/stat.h> #include <linux/slab.h> #include <linux/memblock.h> #include <linux/atomic.h> #include <linux/uaccess.h> Loading Loading @@ -494,6 +495,18 @@ static ssize_t show_allocated_bytes(struct device *dev, return snprintf(buf, 100, "%lu\n", used); } static ssize_t show_aligned_blocks_addr(struct device *dev, struct device_attribute *attr, char *buf) { return memblock_dump_aligned_blocks_addr(buf); } static ssize_t show_aligned_blocks_num(struct device *dev, struct device_attribute *attr, char *buf) { return memblock_dump_aligned_blocks_num(buf); } #endif static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); Loading @@ -502,6 +515,8 @@ static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL); #ifdef CONFIG_MEMORY_HOTPLUG static DEVICE_ATTR(allocated_bytes, 0444, show_allocated_bytes, NULL); static DEVICE_ATTR(aligned_blocks_addr, 0444, show_aligned_blocks_addr, NULL); static DEVICE_ATTR(aligned_blocks_num, 0444, show_aligned_blocks_num, NULL); #endif /* Loading Loading @@ -886,6 +901,10 @@ static struct attribute *memory_root_attrs[] = { &dev_attr_block_size_bytes.attr, &dev_attr_auto_online_blocks.attr, #ifdef CONFIG_MEMORY_HOTPLUG &dev_attr_aligned_blocks_addr.attr, &dev_attr_aligned_blocks_num.attr, #endif NULL }; Loading
include/linux/memblock.h +4 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,10 @@ int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); int memblock_mark_nomap(phys_addr_t base, phys_addr_t size); int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); #ifdef CONFIG_MEMORY_HOTPLUG int memblock_dump_aligned_blocks_addr(char *buf); int memblock_dump_aligned_blocks_num(char *buf); #endif ulong choose_memblock_flags(void); /* Low level functions */ Loading
mm/memblock.c +111 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/debugfs.h> #include <linux/seq_file.h> #include <linux/memblock.h> #include <linux/memory.h> #include <asm/sections.h> #include <linux/io.h> Loading Loading @@ -1777,6 +1778,116 @@ static int __init early_memblock(char *p) } early_param("memblock", early_memblock); #ifdef CONFIG_MEMORY_HOTPLUG static phys_addr_t no_hotplug_area[8]; static phys_addr_t aligned_blocks[32]; static int __init early_no_hotplug_area(char *p) { phys_addr_t base, size; int idx = 0; char *endp = p; while (1) { base = memparse(endp, &endp); if (base && (*endp == ',')) { size = memparse(endp + 1, &endp); if (size) { no_hotplug_area[idx++] = base; no_hotplug_area[idx++] = base+size; if ((*endp == ';') && (idx <= 6)) endp++; else break; } else break; } else break; } return 0; } early_param("no_hotplug_area", early_no_hotplug_area); static bool __init memblock_in_no_hotplug_area(phys_addr_t addr) { int idx = 0; while (idx < 8) { if (!no_hotplug_area[idx]) break; if ((addr + MIN_MEMORY_BLOCK_SIZE <= no_hotplug_area[idx]) || (addr >= no_hotplug_area[idx+1])) { idx += 2; continue; } return true; } return false; } static int __init early_dyn_memhotplug(char *p) { int idx = 0; phys_addr_t addr, rgn_end; struct memblock_region *rgn; int blk = 0; while ((idx++) < memblock.memory.cnt) { rgn = &memblock.memory.regions[idx]; addr = ALIGN(rgn->base, MIN_MEMORY_BLOCK_SIZE); rgn_end = rgn->base + rgn->size; while (addr + MIN_MEMORY_BLOCK_SIZE <= rgn_end) { if (!memblock_in_no_hotplug_area(addr)) { aligned_blocks[blk++] = addr; memblock_remove(addr, MIN_MEMORY_BLOCK_SIZE); } addr += MIN_MEMORY_BLOCK_SIZE; } } return 0; } early_param("dyn_memhotplug", early_dyn_memhotplug); int memblock_dump_aligned_blocks_addr(char *buf) { int idx = 0; int size = 0; if (aligned_blocks[idx]) { size += snprintf(buf+size, 32, "0x%llx", aligned_blocks[idx]); idx++; } while (aligned_blocks[idx]) { size += snprintf(buf+size, 32, ",0x%llx", aligned_blocks[idx]); idx++; } return size; } int memblock_dump_aligned_blocks_num(char *buf) { int idx = 0; int size = 0; if (aligned_blocks[idx]) { size += snprintf(buf+size, 16, "%d", (int)(aligned_blocks[idx] >> SECTION_SIZE_BITS)); idx++; } while (aligned_blocks[idx]) { size += snprintf(buf+size, 16, ",%d", (int)(aligned_blocks[idx] >> SECTION_SIZE_BITS)); idx++; } return size; } #endif #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_ARCH_DISCARD_MEMBLOCK) static int memblock_debug_show(struct seq_file *m, void *private) Loading