diff options
| -rw-r--r-- | mm/page_alloc.c | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 4bc66f6b771..62564e27b44 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1727,6 +1727,7 @@ void __init build_all_zonelists(void) | |||
| 1727 | */ | 1727 | */ |
| 1728 | #define PAGES_PER_WAITQUEUE 256 | 1728 | #define PAGES_PER_WAITQUEUE 256 |
| 1729 | 1729 | ||
| 1730 | #ifndef CONFIG_MEMORY_HOTPLUG | ||
| 1730 | static inline unsigned long wait_table_hash_nr_entries(unsigned long pages) | 1731 | static inline unsigned long wait_table_hash_nr_entries(unsigned long pages) |
| 1731 | { | 1732 | { |
| 1732 | unsigned long size = 1; | 1733 | unsigned long size = 1; |
| @@ -1745,6 +1746,29 @@ static inline unsigned long wait_table_hash_nr_entries(unsigned long pages) | |||
| 1745 | 1746 | ||
| 1746 | return max(size, 4UL); | 1747 | return max(size, 4UL); |
| 1747 | } | 1748 | } |
| 1749 | #else | ||
| 1750 | /* | ||
| 1751 | * A zone's size might be changed by hot-add, so it is not possible to determine | ||
| 1752 | * a suitable size for its wait_table. So we use the maximum size now. | ||
| 1753 | * | ||
| 1754 | * The max wait table size = 4096 x sizeof(wait_queue_head_t). ie: | ||
| 1755 | * | ||
| 1756 | * i386 (preemption config) : 4096 x 16 = 64Kbyte. | ||
| 1757 | * ia64, x86-64 (no preemption): 4096 x 20 = 80Kbyte. | ||
| 1758 | * ia64, x86-64 (preemption) : 4096 x 24 = 96Kbyte. | ||
| 1759 | * | ||
| 1760 | * The maximum entries are prepared when a zone's memory is (512K + 256) pages | ||
| 1761 | * or more by the traditional way. (See above). It equals: | ||
| 1762 | * | ||
| 1763 | * i386, x86-64, powerpc(4K page size) : = ( 2G + 1M)byte. | ||
| 1764 | * ia64(16K page size) : = ( 8G + 4M)byte. | ||
| 1765 | * powerpc (64K page size) : = (32G +16M)byte. | ||
| 1766 | */ | ||
| 1767 | static inline unsigned long wait_table_hash_nr_entries(unsigned long pages) | ||
| 1768 | { | ||
| 1769 | return 4096UL; | ||
| 1770 | } | ||
| 1771 | #endif | ||
| 1748 | 1772 | ||
| 1749 | /* | 1773 | /* |
| 1750 | * This is an integer logarithm so that shifts can be used later | 1774 | * This is an integer logarithm so that shifts can be used later |
| @@ -2010,10 +2034,11 @@ void __init setup_per_cpu_pageset(void) | |||
| 2010 | #endif | 2034 | #endif |
| 2011 | 2035 | ||
| 2012 | static __meminit | 2036 | static __meminit |
| 2013 | void zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) | 2037 | int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) |
| 2014 | { | 2038 | { |
| 2015 | int i; | 2039 | int i; |
| 2016 | struct pglist_data *pgdat = zone->zone_pgdat; | 2040 | struct pglist_data *pgdat = zone->zone_pgdat; |
| 2041 | size_t alloc_size; | ||
| 2017 | 2042 | ||
| 2018 | /* | 2043 | /* |
| 2019 | * The per-page waitqueue mechanism uses hashed waitqueues | 2044 | * The per-page waitqueue mechanism uses hashed waitqueues |
| @@ -2023,12 +2048,32 @@ void zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages) | |||
| 2023 | wait_table_hash_nr_entries(zone_size_pages); | 2048 | wait_table_hash_nr_entries(zone_size_pages); |
| 2024 | zone->wait_table_bits = | 2049 | zone->wait_table_bits = |
| 2025 | wait_table_bits(zone->wait_table_hash_nr_entries); | 2050 | wait_table_bits(zone->wait_table_hash_nr_entries); |
| 2026 | zone->wait_table = (wait_queue_head_t *) | 2051 | alloc_size = zone->wait_table_hash_nr_entries |
| 2027 | alloc_bootmem_node(pgdat, zone->wait_table_hash_nr_entries | 2052 | * sizeof(wait_queue_head_t); |
| 2028 | * sizeof(wait_queue_head_t)); | 2053 | |
| 2054 | if (system_state == SYSTEM_BOOTING) { | ||
| 2055 | zone->wait_table = (wait_queue_head_t *) | ||
| 2056 | alloc_bootmem_node(pgdat, alloc_size); | ||
| 2057 | } else { | ||
| 2058 | /* | ||
| 2059 | * This case means that a zone whose size was 0 gets new memory | ||
| 2060 | * via memory hot-add. | ||
| 2061 | * But it may be the case that a new node was hot-added. In | ||
| 2062 | * this case vmalloc() will not be able to use this new node's | ||
| 2063 | * memory - this wait_table must be initialized to use this new | ||
| 2064 | * node itself as well. | ||
| 2065 | * To use this new node's memory, further consideration will be | ||
| 2066 | * necessary. | ||
| 2067 | */ | ||
| 2068 | zone->wait_table = (wait_queue_head_t *)vmalloc(alloc_size); | ||
| 2069 | } | ||
| 2070 | if (!zone->wait_table) | ||
| 2071 | return -ENOMEM; | ||
| 2029 | 2072 | ||
| 2030 | for(i = 0; i < zone->wait_table_hash_nr_entries; ++i) | 2073 | for(i = 0; i < zone->wait_table_hash_nr_entries; ++i) |
| 2031 | init_waitqueue_head(zone->wait_table + i); | 2074 | init_waitqueue_head(zone->wait_table + i); |
| 2075 | |||
| 2076 | return 0; | ||
| 2032 | } | 2077 | } |
| 2033 | 2078 | ||
| 2034 | static __meminit void zone_pcp_init(struct zone *zone) | 2079 | static __meminit void zone_pcp_init(struct zone *zone) |
| @@ -2055,8 +2100,10 @@ __meminit int init_currently_empty_zone(struct zone *zone, | |||
| 2055 | unsigned long size) | 2100 | unsigned long size) |
| 2056 | { | 2101 | { |
| 2057 | struct pglist_data *pgdat = zone->zone_pgdat; | 2102 | struct pglist_data *pgdat = zone->zone_pgdat; |
| 2058 | 2103 | int ret; | |
| 2059 | zone_wait_table_init(zone, size); | 2104 | ret = zone_wait_table_init(zone, size); |
| 2105 | if (ret) | ||
| 2106 | return ret; | ||
| 2060 | pgdat->nr_zones = zone_idx(zone) + 1; | 2107 | pgdat->nr_zones = zone_idx(zone) + 1; |
| 2061 | 2108 | ||
| 2062 | zone->zone_start_pfn = zone_start_pfn; | 2109 | zone->zone_start_pfn = zone_start_pfn; |
