at v4.19 21 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Memory subsystem support 4 * 5 * Written by Matt Tolentino <matthew.e.tolentino@intel.com> 6 * Dave Hansen <haveblue@us.ibm.com> 7 * 8 * This file provides the necessary infrastructure to represent 9 * a SPARSEMEM-memory-model system's physical memory in /sysfs. 10 * All arch-independent code that assumes MEMORY_HOTPLUG requires 11 * SPARSEMEM should be contained here, or in mm/memory_hotplug.c. 12 */ 13 14#include <linux/module.h> 15#include <linux/init.h> 16#include <linux/topology.h> 17#include <linux/capability.h> 18#include <linux/device.h> 19#include <linux/memory.h> 20#include <linux/memory_hotplug.h> 21#include <linux/mm.h> 22#include <linux/mutex.h> 23#include <linux/stat.h> 24#include <linux/slab.h> 25 26#include <linux/atomic.h> 27#include <linux/uaccess.h> 28 29static DEFINE_MUTEX(mem_sysfs_mutex); 30 31#define MEMORY_CLASS_NAME "memory" 32 33#define to_memory_block(dev) container_of(dev, struct memory_block, dev) 34 35static int sections_per_block; 36 37static inline int base_memory_block_id(int section_nr) 38{ 39 return section_nr / sections_per_block; 40} 41 42static int memory_subsys_online(struct device *dev); 43static int memory_subsys_offline(struct device *dev); 44 45static struct bus_type memory_subsys = { 46 .name = MEMORY_CLASS_NAME, 47 .dev_name = MEMORY_CLASS_NAME, 48 .online = memory_subsys_online, 49 .offline = memory_subsys_offline, 50}; 51 52static BLOCKING_NOTIFIER_HEAD(memory_chain); 53 54int register_memory_notifier(struct notifier_block *nb) 55{ 56 return blocking_notifier_chain_register(&memory_chain, nb); 57} 58EXPORT_SYMBOL(register_memory_notifier); 59 60void unregister_memory_notifier(struct notifier_block *nb) 61{ 62 blocking_notifier_chain_unregister(&memory_chain, nb); 63} 64EXPORT_SYMBOL(unregister_memory_notifier); 65 66static ATOMIC_NOTIFIER_HEAD(memory_isolate_chain); 67 68int register_memory_isolate_notifier(struct notifier_block *nb) 69{ 70 return atomic_notifier_chain_register(&memory_isolate_chain, nb); 71} 72EXPORT_SYMBOL(register_memory_isolate_notifier); 73 74void unregister_memory_isolate_notifier(struct notifier_block *nb) 75{ 76 atomic_notifier_chain_unregister(&memory_isolate_chain, nb); 77} 78EXPORT_SYMBOL(unregister_memory_isolate_notifier); 79 80static void memory_block_release(struct device *dev) 81{ 82 struct memory_block *mem = to_memory_block(dev); 83 84 kfree(mem); 85} 86 87unsigned long __weak memory_block_size_bytes(void) 88{ 89 return MIN_MEMORY_BLOCK_SIZE; 90} 91 92static unsigned long get_memory_block_size(void) 93{ 94 unsigned long block_sz; 95 96 block_sz = memory_block_size_bytes(); 97 98 /* Validate blk_sz is a power of 2 and not less than section size */ 99 if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) { 100 WARN_ON(1); 101 block_sz = MIN_MEMORY_BLOCK_SIZE; 102 } 103 104 return block_sz; 105} 106 107/* 108 * use this as the physical section index that this memsection 109 * uses. 110 */ 111 112static ssize_t show_mem_start_phys_index(struct device *dev, 113 struct device_attribute *attr, char *buf) 114{ 115 struct memory_block *mem = to_memory_block(dev); 116 unsigned long phys_index; 117 118 phys_index = mem->start_section_nr / sections_per_block; 119 return sprintf(buf, "%08lx\n", phys_index); 120} 121 122/* 123 * Show whether the section of memory is likely to be hot-removable 124 */ 125static ssize_t show_mem_removable(struct device *dev, 126 struct device_attribute *attr, char *buf) 127{ 128 unsigned long i, pfn; 129 int ret = 1; 130 struct memory_block *mem = to_memory_block(dev); 131 132 if (mem->state != MEM_ONLINE) 133 goto out; 134 135 for (i = 0; i < sections_per_block; i++) { 136 if (!present_section_nr(mem->start_section_nr + i)) 137 continue; 138 pfn = section_nr_to_pfn(mem->start_section_nr + i); 139 ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); 140 } 141 142out: 143 return sprintf(buf, "%d\n", ret); 144} 145 146/* 147 * online, offline, going offline, etc. 148 */ 149static ssize_t show_mem_state(struct device *dev, 150 struct device_attribute *attr, char *buf) 151{ 152 struct memory_block *mem = to_memory_block(dev); 153 ssize_t len = 0; 154 155 /* 156 * We can probably put these states in a nice little array 157 * so that they're not open-coded 158 */ 159 switch (mem->state) { 160 case MEM_ONLINE: 161 len = sprintf(buf, "online\n"); 162 break; 163 case MEM_OFFLINE: 164 len = sprintf(buf, "offline\n"); 165 break; 166 case MEM_GOING_OFFLINE: 167 len = sprintf(buf, "going-offline\n"); 168 break; 169 default: 170 len = sprintf(buf, "ERROR-UNKNOWN-%ld\n", 171 mem->state); 172 WARN_ON(1); 173 break; 174 } 175 176 return len; 177} 178 179int memory_notify(unsigned long val, void *v) 180{ 181 return blocking_notifier_call_chain(&memory_chain, val, v); 182} 183 184int memory_isolate_notify(unsigned long val, void *v) 185{ 186 return atomic_notifier_call_chain(&memory_isolate_chain, val, v); 187} 188 189/* 190 * The probe routines leave the pages uninitialized, just as the bootmem code 191 * does. Make sure we do not access them, but instead use only information from 192 * within sections. 193 */ 194static bool pages_correctly_probed(unsigned long start_pfn) 195{ 196 unsigned long section_nr = pfn_to_section_nr(start_pfn); 197 unsigned long section_nr_end = section_nr + sections_per_block; 198 unsigned long pfn = start_pfn; 199 200 /* 201 * memmap between sections is not contiguous except with 202 * SPARSEMEM_VMEMMAP. We lookup the page once per section 203 * and assume memmap is contiguous within each section 204 */ 205 for (; section_nr < section_nr_end; section_nr++) { 206 if (WARN_ON_ONCE(!pfn_valid(pfn))) 207 return false; 208 209 if (!present_section_nr(section_nr)) { 210 pr_warn("section %ld pfn[%lx, %lx) not present", 211 section_nr, pfn, pfn + PAGES_PER_SECTION); 212 return false; 213 } else if (!valid_section_nr(section_nr)) { 214 pr_warn("section %ld pfn[%lx, %lx) no valid memmap", 215 section_nr, pfn, pfn + PAGES_PER_SECTION); 216 return false; 217 } else if (online_section_nr(section_nr)) { 218 pr_warn("section %ld pfn[%lx, %lx) is already online", 219 section_nr, pfn, pfn + PAGES_PER_SECTION); 220 return false; 221 } 222 pfn += PAGES_PER_SECTION; 223 } 224 225 return true; 226} 227 228/* 229 * MEMORY_HOTPLUG depends on SPARSEMEM in mm/Kconfig, so it is 230 * OK to have direct references to sparsemem variables in here. 231 * Must already be protected by mem_hotplug_begin(). 232 */ 233static int 234memory_block_action(unsigned long phys_index, unsigned long action, int online_type) 235{ 236 unsigned long start_pfn; 237 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; 238 int ret; 239 240 start_pfn = section_nr_to_pfn(phys_index); 241 242 switch (action) { 243 case MEM_ONLINE: 244 if (!pages_correctly_probed(start_pfn)) 245 return -EBUSY; 246 247 ret = online_pages(start_pfn, nr_pages, online_type); 248 break; 249 case MEM_OFFLINE: 250 ret = offline_pages(start_pfn, nr_pages); 251 break; 252 default: 253 WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " 254 "%ld\n", __func__, phys_index, action, action); 255 ret = -EINVAL; 256 } 257 258 return ret; 259} 260 261static int memory_block_change_state(struct memory_block *mem, 262 unsigned long to_state, unsigned long from_state_req) 263{ 264 int ret = 0; 265 266 if (mem->state != from_state_req) 267 return -EINVAL; 268 269 if (to_state == MEM_OFFLINE) 270 mem->state = MEM_GOING_OFFLINE; 271 272 ret = memory_block_action(mem->start_section_nr, to_state, 273 mem->online_type); 274 275 mem->state = ret ? from_state_req : to_state; 276 277 return ret; 278} 279 280/* The device lock serializes operations on memory_subsys_[online|offline] */ 281static int memory_subsys_online(struct device *dev) 282{ 283 struct memory_block *mem = to_memory_block(dev); 284 int ret; 285 286 if (mem->state == MEM_ONLINE) 287 return 0; 288 289 /* 290 * If we are called from store_mem_state(), online_type will be 291 * set >= 0 Otherwise we were called from the device online 292 * attribute and need to set the online_type. 293 */ 294 if (mem->online_type < 0) 295 mem->online_type = MMOP_ONLINE_KEEP; 296 297 /* Already under protection of mem_hotplug_begin() */ 298 ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); 299 300 /* clear online_type */ 301 mem->online_type = -1; 302 303 return ret; 304} 305 306static int memory_subsys_offline(struct device *dev) 307{ 308 struct memory_block *mem = to_memory_block(dev); 309 310 if (mem->state == MEM_OFFLINE) 311 return 0; 312 313 /* Can't offline block with non-present sections */ 314 if (mem->section_count != sections_per_block) 315 return -EINVAL; 316 317 return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); 318} 319 320static ssize_t 321store_mem_state(struct device *dev, 322 struct device_attribute *attr, const char *buf, size_t count) 323{ 324 struct memory_block *mem = to_memory_block(dev); 325 int ret, online_type; 326 327 ret = lock_device_hotplug_sysfs(); 328 if (ret) 329 return ret; 330 331 if (sysfs_streq(buf, "online_kernel")) 332 online_type = MMOP_ONLINE_KERNEL; 333 else if (sysfs_streq(buf, "online_movable")) 334 online_type = MMOP_ONLINE_MOVABLE; 335 else if (sysfs_streq(buf, "online")) 336 online_type = MMOP_ONLINE_KEEP; 337 else if (sysfs_streq(buf, "offline")) 338 online_type = MMOP_OFFLINE; 339 else { 340 ret = -EINVAL; 341 goto err; 342 } 343 344 /* 345 * Memory hotplug needs to hold mem_hotplug_begin() for probe to find 346 * the correct memory block to online before doing device_online(dev), 347 * which will take dev->mutex. Take the lock early to prevent an 348 * inversion, memory_subsys_online() callbacks will be implemented by 349 * assuming it's already protected. 350 */ 351 mem_hotplug_begin(); 352 353 switch (online_type) { 354 case MMOP_ONLINE_KERNEL: 355 case MMOP_ONLINE_MOVABLE: 356 case MMOP_ONLINE_KEEP: 357 mem->online_type = online_type; 358 ret = device_online(&mem->dev); 359 break; 360 case MMOP_OFFLINE: 361 ret = device_offline(&mem->dev); 362 break; 363 default: 364 ret = -EINVAL; /* should never happen */ 365 } 366 367 mem_hotplug_done(); 368err: 369 unlock_device_hotplug(); 370 371 if (ret < 0) 372 return ret; 373 if (ret) 374 return -EINVAL; 375 376 return count; 377} 378 379/* 380 * phys_device is a bad name for this. What I really want 381 * is a way to differentiate between memory ranges that 382 * are part of physical devices that constitute 383 * a complete removable unit or fru. 384 * i.e. do these ranges belong to the same physical device, 385 * s.t. if I offline all of these sections I can then 386 * remove the physical device? 387 */ 388static ssize_t show_phys_device(struct device *dev, 389 struct device_attribute *attr, char *buf) 390{ 391 struct memory_block *mem = to_memory_block(dev); 392 return sprintf(buf, "%d\n", mem->phys_device); 393} 394 395#ifdef CONFIG_MEMORY_HOTREMOVE 396static void print_allowed_zone(char *buf, int nid, unsigned long start_pfn, 397 unsigned long nr_pages, int online_type, 398 struct zone *default_zone) 399{ 400 struct zone *zone; 401 402 zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages); 403 if (zone != default_zone) { 404 strcat(buf, " "); 405 strcat(buf, zone->name); 406 } 407} 408 409static ssize_t show_valid_zones(struct device *dev, 410 struct device_attribute *attr, char *buf) 411{ 412 struct memory_block *mem = to_memory_block(dev); 413 unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); 414 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; 415 unsigned long valid_start_pfn, valid_end_pfn; 416 struct zone *default_zone; 417 int nid; 418 419 /* 420 * Check the existing zone. Make sure that we do that only on the 421 * online nodes otherwise the page_zone is not reliable 422 */ 423 if (mem->state == MEM_ONLINE) { 424 /* 425 * The block contains more than one zone can not be offlined. 426 * This can happen e.g. for ZONE_DMA and ZONE_DMA32 427 */ 428 if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages, 429 &valid_start_pfn, &valid_end_pfn)) 430 return sprintf(buf, "none\n"); 431 start_pfn = valid_start_pfn; 432 strcat(buf, page_zone(pfn_to_page(start_pfn))->name); 433 goto out; 434 } 435 436 nid = mem->nid; 437 default_zone = zone_for_pfn_range(MMOP_ONLINE_KEEP, nid, start_pfn, nr_pages); 438 strcat(buf, default_zone->name); 439 440 print_allowed_zone(buf, nid, start_pfn, nr_pages, MMOP_ONLINE_KERNEL, 441 default_zone); 442 print_allowed_zone(buf, nid, start_pfn, nr_pages, MMOP_ONLINE_MOVABLE, 443 default_zone); 444out: 445 strcat(buf, "\n"); 446 447 return strlen(buf); 448} 449static DEVICE_ATTR(valid_zones, 0444, show_valid_zones, NULL); 450#endif 451 452static DEVICE_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); 453static DEVICE_ATTR(state, 0644, show_mem_state, store_mem_state); 454static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL); 455static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL); 456 457/* 458 * Block size attribute stuff 459 */ 460static ssize_t 461print_block_size(struct device *dev, struct device_attribute *attr, 462 char *buf) 463{ 464 return sprintf(buf, "%lx\n", get_memory_block_size()); 465} 466 467static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL); 468 469/* 470 * Memory auto online policy. 471 */ 472 473static ssize_t 474show_auto_online_blocks(struct device *dev, struct device_attribute *attr, 475 char *buf) 476{ 477 if (memhp_auto_online) 478 return sprintf(buf, "online\n"); 479 else 480 return sprintf(buf, "offline\n"); 481} 482 483static ssize_t 484store_auto_online_blocks(struct device *dev, struct device_attribute *attr, 485 const char *buf, size_t count) 486{ 487 if (sysfs_streq(buf, "online")) 488 memhp_auto_online = true; 489 else if (sysfs_streq(buf, "offline")) 490 memhp_auto_online = false; 491 else 492 return -EINVAL; 493 494 return count; 495} 496 497static DEVICE_ATTR(auto_online_blocks, 0644, show_auto_online_blocks, 498 store_auto_online_blocks); 499 500/* 501 * Some architectures will have custom drivers to do this, and 502 * will not need to do it from userspace. The fake hot-add code 503 * as well as ppc64 will do all of their discovery in userspace 504 * and will require this interface. 505 */ 506#ifdef CONFIG_ARCH_MEMORY_PROBE 507static ssize_t 508memory_probe_store(struct device *dev, struct device_attribute *attr, 509 const char *buf, size_t count) 510{ 511 u64 phys_addr; 512 int nid, ret; 513 unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block; 514 515 ret = kstrtoull(buf, 0, &phys_addr); 516 if (ret) 517 return ret; 518 519 if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1)) 520 return -EINVAL; 521 522 nid = memory_add_physaddr_to_nid(phys_addr); 523 ret = add_memory(nid, phys_addr, 524 MIN_MEMORY_BLOCK_SIZE * sections_per_block); 525 526 if (ret) 527 goto out; 528 529 ret = count; 530out: 531 return ret; 532} 533 534static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store); 535#endif 536 537#ifdef CONFIG_MEMORY_FAILURE 538/* 539 * Support for offlining pages of memory 540 */ 541 542/* Soft offline a page */ 543static ssize_t 544store_soft_offline_page(struct device *dev, 545 struct device_attribute *attr, 546 const char *buf, size_t count) 547{ 548 int ret; 549 u64 pfn; 550 if (!capable(CAP_SYS_ADMIN)) 551 return -EPERM; 552 if (kstrtoull(buf, 0, &pfn) < 0) 553 return -EINVAL; 554 pfn >>= PAGE_SHIFT; 555 if (!pfn_valid(pfn)) 556 return -ENXIO; 557 ret = soft_offline_page(pfn_to_page(pfn), 0); 558 return ret == 0 ? count : ret; 559} 560 561/* Forcibly offline a page, including killing processes. */ 562static ssize_t 563store_hard_offline_page(struct device *dev, 564 struct device_attribute *attr, 565 const char *buf, size_t count) 566{ 567 int ret; 568 u64 pfn; 569 if (!capable(CAP_SYS_ADMIN)) 570 return -EPERM; 571 if (kstrtoull(buf, 0, &pfn) < 0) 572 return -EINVAL; 573 pfn >>= PAGE_SHIFT; 574 ret = memory_failure(pfn, 0); 575 return ret ? ret : count; 576} 577 578static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page); 579static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page); 580#endif 581 582/* 583 * Note that phys_device is optional. It is here to allow for 584 * differentiation between which *physical* devices each 585 * section belongs to... 586 */ 587int __weak arch_get_memory_phys_device(unsigned long start_pfn) 588{ 589 return 0; 590} 591 592/* 593 * A reference for the returned object is held and the reference for the 594 * hinted object is released. 595 */ 596struct memory_block *find_memory_block_hinted(struct mem_section *section, 597 struct memory_block *hint) 598{ 599 int block_id = base_memory_block_id(__section_nr(section)); 600 struct device *hintdev = hint ? &hint->dev : NULL; 601 struct device *dev; 602 603 dev = subsys_find_device_by_id(&memory_subsys, block_id, hintdev); 604 if (hint) 605 put_device(&hint->dev); 606 if (!dev) 607 return NULL; 608 return to_memory_block(dev); 609} 610 611/* 612 * For now, we have a linear search to go find the appropriate 613 * memory_block corresponding to a particular phys_index. If 614 * this gets to be a real problem, we can always use a radix 615 * tree or something here. 616 * 617 * This could be made generic for all device subsystems. 618 */ 619struct memory_block *find_memory_block(struct mem_section *section) 620{ 621 return find_memory_block_hinted(section, NULL); 622} 623 624static struct attribute *memory_memblk_attrs[] = { 625 &dev_attr_phys_index.attr, 626 &dev_attr_state.attr, 627 &dev_attr_phys_device.attr, 628 &dev_attr_removable.attr, 629#ifdef CONFIG_MEMORY_HOTREMOVE 630 &dev_attr_valid_zones.attr, 631#endif 632 NULL 633}; 634 635static struct attribute_group memory_memblk_attr_group = { 636 .attrs = memory_memblk_attrs, 637}; 638 639static const struct attribute_group *memory_memblk_attr_groups[] = { 640 &memory_memblk_attr_group, 641 NULL, 642}; 643 644/* 645 * register_memory - Setup a sysfs device for a memory block 646 */ 647static 648int register_memory(struct memory_block *memory) 649{ 650 int ret; 651 652 memory->dev.bus = &memory_subsys; 653 memory->dev.id = memory->start_section_nr / sections_per_block; 654 memory->dev.release = memory_block_release; 655 memory->dev.groups = memory_memblk_attr_groups; 656 memory->dev.offline = memory->state == MEM_OFFLINE; 657 658 ret = device_register(&memory->dev); 659 if (ret) 660 put_device(&memory->dev); 661 662 return ret; 663} 664 665static int init_memory_block(struct memory_block **memory, 666 struct mem_section *section, unsigned long state) 667{ 668 struct memory_block *mem; 669 unsigned long start_pfn; 670 int scn_nr; 671 int ret = 0; 672 673 mem = kzalloc(sizeof(*mem), GFP_KERNEL); 674 if (!mem) 675 return -ENOMEM; 676 677 scn_nr = __section_nr(section); 678 mem->start_section_nr = 679 base_memory_block_id(scn_nr) * sections_per_block; 680 mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; 681 mem->state = state; 682 start_pfn = section_nr_to_pfn(mem->start_section_nr); 683 mem->phys_device = arch_get_memory_phys_device(start_pfn); 684 685 ret = register_memory(mem); 686 687 *memory = mem; 688 return ret; 689} 690 691static int add_memory_block(int base_section_nr) 692{ 693 struct memory_block *mem; 694 int i, ret, section_count = 0, section_nr; 695 696 for (i = base_section_nr; 697 (i < base_section_nr + sections_per_block) && i < NR_MEM_SECTIONS; 698 i++) { 699 if (!present_section_nr(i)) 700 continue; 701 if (section_count == 0) 702 section_nr = i; 703 section_count++; 704 } 705 706 if (section_count == 0) 707 return 0; 708 ret = init_memory_block(&mem, __nr_to_section(section_nr), MEM_ONLINE); 709 if (ret) 710 return ret; 711 mem->section_count = section_count; 712 return 0; 713} 714 715/* 716 * need an interface for the VM to add new memory regions, 717 * but without onlining it. 718 */ 719int hotplug_memory_register(int nid, struct mem_section *section) 720{ 721 int ret = 0; 722 struct memory_block *mem; 723 724 mutex_lock(&mem_sysfs_mutex); 725 726 mem = find_memory_block(section); 727 if (mem) { 728 mem->section_count++; 729 put_device(&mem->dev); 730 } else { 731 ret = init_memory_block(&mem, section, MEM_OFFLINE); 732 if (ret) 733 goto out; 734 mem->section_count++; 735 } 736 737out: 738 mutex_unlock(&mem_sysfs_mutex); 739 return ret; 740} 741 742#ifdef CONFIG_MEMORY_HOTREMOVE 743static void 744unregister_memory(struct memory_block *memory) 745{ 746 BUG_ON(memory->dev.bus != &memory_subsys); 747 748 /* drop the ref. we got in remove_memory_block() */ 749 put_device(&memory->dev); 750 device_unregister(&memory->dev); 751} 752 753static int remove_memory_section(unsigned long node_id, 754 struct mem_section *section, int phys_device) 755{ 756 struct memory_block *mem; 757 758 mutex_lock(&mem_sysfs_mutex); 759 760 /* 761 * Some users of the memory hotplug do not want/need memblock to 762 * track all sections. Skip over those. 763 */ 764 mem = find_memory_block(section); 765 if (!mem) 766 goto out_unlock; 767 768 unregister_mem_sect_under_nodes(mem, __section_nr(section)); 769 770 mem->section_count--; 771 if (mem->section_count == 0) 772 unregister_memory(mem); 773 else 774 put_device(&mem->dev); 775 776out_unlock: 777 mutex_unlock(&mem_sysfs_mutex); 778 return 0; 779} 780 781int unregister_memory_section(struct mem_section *section) 782{ 783 if (!present_section(section)) 784 return -EINVAL; 785 786 return remove_memory_section(0, section, 0); 787} 788#endif /* CONFIG_MEMORY_HOTREMOVE */ 789 790/* return true if the memory block is offlined, otherwise, return false */ 791bool is_memblock_offlined(struct memory_block *mem) 792{ 793 return mem->state == MEM_OFFLINE; 794} 795 796static struct attribute *memory_root_attrs[] = { 797#ifdef CONFIG_ARCH_MEMORY_PROBE 798 &dev_attr_probe.attr, 799#endif 800 801#ifdef CONFIG_MEMORY_FAILURE 802 &dev_attr_soft_offline_page.attr, 803 &dev_attr_hard_offline_page.attr, 804#endif 805 806 &dev_attr_block_size_bytes.attr, 807 &dev_attr_auto_online_blocks.attr, 808 NULL 809}; 810 811static struct attribute_group memory_root_attr_group = { 812 .attrs = memory_root_attrs, 813}; 814 815static const struct attribute_group *memory_root_attr_groups[] = { 816 &memory_root_attr_group, 817 NULL, 818}; 819 820/* 821 * Initialize the sysfs support for memory devices... 822 */ 823int __init memory_dev_init(void) 824{ 825 unsigned int i; 826 int ret; 827 int err; 828 unsigned long block_sz; 829 830 ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); 831 if (ret) 832 goto out; 833 834 block_sz = get_memory_block_size(); 835 sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; 836 837 /* 838 * Create entries for memory sections that were found 839 * during boot and have been initialized 840 */ 841 mutex_lock(&mem_sysfs_mutex); 842 for (i = 0; i <= __highest_present_section_nr; 843 i += sections_per_block) { 844 err = add_memory_block(i); 845 if (!ret) 846 ret = err; 847 } 848 mutex_unlock(&mem_sysfs_mutex); 849 850out: 851 if (ret) 852 printk(KERN_ERR "%s() failed: %d\n", __func__, ret); 853 return ret; 854}