Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

memory hotplug: Update phys_index to [start|end]_section_nr

Update the 'phys_index' property of a the memory_block struct to be
called start_section_nr, and add a end_section_nr property. The
data tracked here is the same but the updated naming is more in line
with what is stored here, namely the first and last section number
that the memory block spans.

The names presented to userspace remain the same, phys_index for
start_section_nr and end_phys_index for end_section_nr, to avoid breaking
anything in userspace.

This also updates the node sysfs code to be aware of the new capability for
a memory block to contain multiple memory sections and be aware of the memory
block structure name changes (start_section_nr). This requires an additional
parameter to unregister_mem_sect_under_nodes so that we know which memory
section of the memory block to unregister.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
Reviewed-by: Robin Holt <holt@sgi.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Nathan Fontenot and committed by
Greg Kroah-Hartman
d3360164 0c2c99b1

+45 -17
+31 -10
drivers/base/memory.c
··· 97 97 int error; 98 98 99 99 memory->sysdev.cls = &memory_sysdev_class; 100 - memory->sysdev.id = memory->phys_index / sections_per_block; 100 + memory->sysdev.id = memory->start_section_nr / sections_per_block; 101 101 102 102 error = sysdev_register(&memory->sysdev); 103 103 return error; ··· 138 138 * uses. 139 139 */ 140 140 141 - static ssize_t show_mem_phys_index(struct sys_device *dev, 141 + static ssize_t show_mem_start_phys_index(struct sys_device *dev, 142 142 struct sysdev_attribute *attr, char *buf) 143 143 { 144 144 struct memory_block *mem = 145 145 container_of(dev, struct memory_block, sysdev); 146 - return sprintf(buf, "%08lx\n", mem->phys_index / sections_per_block); 146 + unsigned long phys_index; 147 + 148 + phys_index = mem->start_section_nr / sections_per_block; 149 + return sprintf(buf, "%08lx\n", phys_index); 150 + } 151 + 152 + static ssize_t show_mem_end_phys_index(struct sys_device *dev, 153 + struct sysdev_attribute *attr, char *buf) 154 + { 155 + struct memory_block *mem = 156 + container_of(dev, struct memory_block, sysdev); 157 + unsigned long phys_index; 158 + 159 + phys_index = mem->end_section_nr / sections_per_block; 160 + return sprintf(buf, "%08lx\n", phys_index); 147 161 } 148 162 149 163 /* ··· 172 158 container_of(dev, struct memory_block, sysdev); 173 159 174 160 for (i = 0; i < sections_per_block; i++) { 175 - pfn = section_nr_to_pfn(mem->phys_index + i); 161 + pfn = section_nr_to_pfn(mem->start_section_nr + i); 176 162 ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); 177 163 } 178 164 ··· 289 275 mem->state = MEM_GOING_OFFLINE; 290 276 291 277 for (i = 0; i < sections_per_block; i++) { 292 - ret = memory_section_action(mem->phys_index + i, to_state); 278 + ret = memory_section_action(mem->start_section_nr + i, 279 + to_state); 293 280 if (ret) 294 281 break; 295 282 } 296 283 297 284 if (ret) { 298 285 for (i = 0; i < sections_per_block; i++) 299 - memory_section_action(mem->phys_index + i, 286 + memory_section_action(mem->start_section_nr + i, 300 287 from_state_req); 301 288 302 289 mem->state = from_state_req; ··· 345 330 return sprintf(buf, "%d\n", mem->phys_device); 346 331 } 347 332 348 - static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); 333 + static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); 334 + static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); 349 335 static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); 350 336 static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); 351 337 static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); ··· 538 522 return -ENOMEM; 539 523 540 524 scn_nr = __section_nr(section); 541 - mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block; 525 + mem->start_section_nr = 526 + base_memory_block_id(scn_nr) * sections_per_block; 527 + mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; 542 528 mem->state = state; 543 529 mem->section_count++; 544 530 mutex_init(&mem->state_mutex); 545 - start_pfn = section_nr_to_pfn(mem->phys_index); 531 + start_pfn = section_nr_to_pfn(mem->start_section_nr); 546 532 mem->phys_device = arch_get_memory_phys_device(start_pfn); 547 533 548 534 ret = register_memory(mem); 549 535 if (!ret) 550 536 ret = mem_create_simple_file(mem, phys_index); 537 + if (!ret) 538 + ret = mem_create_simple_file(mem, end_phys_index); 551 539 if (!ret) 552 540 ret = mem_create_simple_file(mem, state); 553 541 if (!ret) ··· 595 575 596 576 mutex_lock(&mem_sysfs_mutex); 597 577 mem = find_memory_block(section); 578 + unregister_mem_sect_under_nodes(mem, __section_nr(section)); 598 579 599 580 mem->section_count--; 600 581 if (mem->section_count == 0) { 601 - unregister_mem_sect_under_nodes(mem); 602 582 mem_remove_simple_file(mem, phys_index); 583 + mem_remove_simple_file(mem, end_phys_index); 603 584 mem_remove_simple_file(mem, state); 604 585 mem_remove_simple_file(mem, phys_device); 605 586 mem_remove_simple_file(mem, removable);
+8 -4
drivers/base/node.c
··· 375 375 return -EFAULT; 376 376 if (!node_online(nid)) 377 377 return 0; 378 - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); 379 - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; 378 + 379 + sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); 380 + sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); 381 + sect_end_pfn += PAGES_PER_SECTION - 1; 380 382 for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { 381 383 int page_nid; 382 384 ··· 402 400 } 403 401 404 402 /* unregister memory section under all nodes that it spans */ 405 - int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) 403 + int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, 404 + unsigned long phys_index) 406 405 { 407 406 NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); 408 407 unsigned long pfn, sect_start_pfn, sect_end_pfn; ··· 415 412 if (!unlinked_nodes) 416 413 return -ENOMEM; 417 414 nodes_clear(*unlinked_nodes); 418 - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); 415 + 416 + sect_start_pfn = section_nr_to_pfn(phys_index); 419 417 sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; 420 418 for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { 421 419 int nid;
+2 -1
include/linux/memory.h
··· 21 21 #include <linux/mutex.h> 22 22 23 23 struct memory_block { 24 - unsigned long phys_index; 24 + unsigned long start_section_nr; 25 + unsigned long end_section_nr; 25 26 unsigned long state; 26 27 int section_count; 27 28
+4 -2
include/linux/node.h
··· 39 39 extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); 40 40 extern int register_mem_sect_under_node(struct memory_block *mem_blk, 41 41 int nid); 42 - extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); 42 + extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, 43 + unsigned long phys_index); 43 44 44 45 #ifdef CONFIG_HUGETLBFS 45 46 extern void register_hugetlbfs_with_node(node_registration_func_t doregister, ··· 68 67 { 69 68 return 0; 70 69 } 71 - static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) 70 + static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, 71 + unsigned long phys_index) 72 72 { 73 73 return 0; 74 74 }