diff options
Diffstat (limited to 'drivers/base/node.c')
-rw-r--r-- | drivers/base/node.c | 55 |
1 files changed, 26 insertions, 29 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c index 75b7e6f6535b..296546ffed6c 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -427,6 +427,8 @@ static ssize_t node_read_meminfo(struct device *dev, | |||
427 | "Node %d AnonHugePages: %8lu kB\n" | 427 | "Node %d AnonHugePages: %8lu kB\n" |
428 | "Node %d ShmemHugePages: %8lu kB\n" | 428 | "Node %d ShmemHugePages: %8lu kB\n" |
429 | "Node %d ShmemPmdMapped: %8lu kB\n" | 429 | "Node %d ShmemPmdMapped: %8lu kB\n" |
430 | "Node %d FileHugePages: %8lu kB\n" | ||
431 | "Node %d FilePmdMapped: %8lu kB\n" | ||
430 | #endif | 432 | #endif |
431 | , | 433 | , |
432 | nid, K(node_page_state(pgdat, NR_FILE_DIRTY)), | 434 | nid, K(node_page_state(pgdat, NR_FILE_DIRTY)), |
@@ -452,6 +454,10 @@ static ssize_t node_read_meminfo(struct device *dev, | |||
452 | nid, K(node_page_state(pgdat, NR_SHMEM_THPS) * | 454 | nid, K(node_page_state(pgdat, NR_SHMEM_THPS) * |
453 | HPAGE_PMD_NR), | 455 | HPAGE_PMD_NR), |
454 | nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) * | 456 | nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) * |
457 | HPAGE_PMD_NR), | ||
458 | nid, K(node_page_state(pgdat, NR_FILE_THPS) * | ||
459 | HPAGE_PMD_NR), | ||
460 | nid, K(node_page_state(pgdat, NR_FILE_PMDMAPPED) * | ||
455 | HPAGE_PMD_NR) | 461 | HPAGE_PMD_NR) |
456 | #endif | 462 | #endif |
457 | ); | 463 | ); |
@@ -756,15 +762,13 @@ static int __ref get_nid_for_pfn(unsigned long pfn) | |||
756 | static int register_mem_sect_under_node(struct memory_block *mem_blk, | 762 | static int register_mem_sect_under_node(struct memory_block *mem_blk, |
757 | void *arg) | 763 | void *arg) |
758 | { | 764 | { |
765 | unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE; | ||
766 | unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); | ||
767 | unsigned long end_pfn = start_pfn + memory_block_pfns - 1; | ||
759 | int ret, nid = *(int *)arg; | 768 | int ret, nid = *(int *)arg; |
760 | unsigned long pfn, sect_start_pfn, sect_end_pfn; | 769 | unsigned long pfn; |
761 | 770 | ||
762 | mem_blk->nid = nid; | 771 | for (pfn = start_pfn; pfn <= end_pfn; pfn++) { |
763 | |||
764 | sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); | ||
765 | sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); | ||
766 | sect_end_pfn += PAGES_PER_SECTION - 1; | ||
767 | for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { | ||
768 | int page_nid; | 772 | int page_nid; |
769 | 773 | ||
770 | /* | 774 | /* |
@@ -789,6 +793,13 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk, | |||
789 | if (page_nid != nid) | 793 | if (page_nid != nid) |
790 | continue; | 794 | continue; |
791 | } | 795 | } |
796 | |||
797 | /* | ||
798 | * If this memory block spans multiple nodes, we only indicate | ||
799 | * the last processed node. | ||
800 | */ | ||
801 | mem_blk->nid = nid; | ||
802 | |||
792 | ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, | 803 | ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, |
793 | &mem_blk->dev.kobj, | 804 | &mem_blk->dev.kobj, |
794 | kobject_name(&mem_blk->dev.kobj)); | 805 | kobject_name(&mem_blk->dev.kobj)); |
@@ -804,32 +815,18 @@ static int register_mem_sect_under_node(struct memory_block *mem_blk, | |||
804 | } | 815 | } |
805 | 816 | ||
806 | /* | 817 | /* |
807 | * Unregister memory block device under all nodes that it spans. | 818 | * Unregister a memory block device under the node it spans. Memory blocks |
808 | * Has to be called with mem_sysfs_mutex held (due to unlinked_nodes). | 819 | * with multiple nodes cannot be offlined and therefore also never be removed. |
809 | */ | 820 | */ |
810 | void unregister_memory_block_under_nodes(struct memory_block *mem_blk) | 821 | void unregister_memory_block_under_nodes(struct memory_block *mem_blk) |
811 | { | 822 | { |
812 | unsigned long pfn, sect_start_pfn, sect_end_pfn; | 823 | if (mem_blk->nid == NUMA_NO_NODE) |
813 | static nodemask_t unlinked_nodes; | 824 | return; |
814 | |||
815 | nodes_clear(unlinked_nodes); | ||
816 | sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); | ||
817 | sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); | ||
818 | for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { | ||
819 | int nid; | ||
820 | 825 | ||
821 | nid = get_nid_for_pfn(pfn); | 826 | sysfs_remove_link(&node_devices[mem_blk->nid]->dev.kobj, |
822 | if (nid < 0) | 827 | kobject_name(&mem_blk->dev.kobj)); |
823 | continue; | 828 | sysfs_remove_link(&mem_blk->dev.kobj, |
824 | if (!node_online(nid)) | 829 | kobject_name(&node_devices[mem_blk->nid]->dev.kobj)); |
825 | continue; | ||
826 | if (node_test_and_set(nid, unlinked_nodes)) | ||
827 | continue; | ||
828 | sysfs_remove_link(&node_devices[nid]->dev.kobj, | ||
829 | kobject_name(&mem_blk->dev.kobj)); | ||
830 | sysfs_remove_link(&mem_blk->dev.kobj, | ||
831 | kobject_name(&node_devices[nid]->dev.kobj)); | ||
832 | } | ||
833 | } | 830 | } |
834 | 831 | ||
835 | int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) | 832 | int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) |