提交 438cc81a 编写于 作者: D David Gibson 提交者: Michael Ellerman

powerpc/pseries: Automatically resize HPT for memory hot add/remove

We've now implemented code in the pseries platform to use the new PAPR
interface to allow resizing the hash page table (HPT) at runtime.

This patch uses that interface to automatically attempt to resize the HPT
when memory is hot added or removed.  This tries to always keep the HPT at
a reasonable size for our current memory size.
Signed-off-by: NDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: NPaul Mackerras <paulus@samba.org>
Signed-off-by: NMichael Ellerman <mpe@ellerman.id.au>
上级 0de0fb09
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#endif /* CONFIG_SPARSEMEM */ #endif /* CONFIG_SPARSEMEM */
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
extern void resize_hpt_for_hotplug(unsigned long new_mem_size);
extern int create_section_mapping(unsigned long start, unsigned long end); extern int create_section_mapping(unsigned long start, unsigned long end);
extern int remove_section_mapping(unsigned long start, unsigned long end); extern int remove_section_mapping(unsigned long start, unsigned long end);
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
......
...@@ -749,6 +749,35 @@ static unsigned long __init htab_get_table_size(void) ...@@ -749,6 +749,35 @@ static unsigned long __init htab_get_table_size(void)
} }
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
void resize_hpt_for_hotplug(unsigned long new_mem_size)
{
unsigned target_hpt_shift;
if (!mmu_hash_ops.resize_hpt)
return;
target_hpt_shift = htab_shift_for_mem_size(new_mem_size);
/*
* To avoid lots of HPT resizes if memory size is fluctuating
* across a boundary, we deliberately have some hysterisis
* here: we immediately increase the HPT size if the target
* shift exceeds the current shift, but we won't attempt to
* reduce unless the target shift is at least 2 below the
* current shift
*/
if ((target_hpt_shift > ppc64_pft_size)
|| (target_hpt_shift < (ppc64_pft_size - 1))) {
int rc;
rc = mmu_hash_ops.resize_hpt(target_hpt_shift);
if (rc)
printk(KERN_WARNING
"Unable to resize hash page table to target order %d: %d\n",
target_hpt_shift, rc);
}
}
int hash__create_section_mapping(unsigned long start, unsigned long end) int hash__create_section_mapping(unsigned long start, unsigned long end)
{ {
int rc = htab_bolt_mapping(start, end, __pa(start), int rc = htab_bolt_mapping(start, end, __pa(start),
......
...@@ -134,6 +134,8 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device) ...@@ -134,6 +134,8 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
unsigned long nr_pages = size >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT;
int rc; int rc;
resize_hpt_for_hotplug(memblock_phys_mem_size());
pgdata = NODE_DATA(nid); pgdata = NODE_DATA(nid);
start = (unsigned long)__va(start); start = (unsigned long)__va(start);
...@@ -174,6 +176,8 @@ int arch_remove_memory(u64 start, u64 size) ...@@ -174,6 +176,8 @@ int arch_remove_memory(u64 start, u64 size)
*/ */
vm_unmap_aliases(); vm_unmap_aliases();
resize_hpt_for_hotplug(memblock_phys_mem_size());
return ret; return ret;
} }
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册