From: Luka Bai We added a kmem slab cached called collapse_hint_cache for khugepaged collapse hint, to improve the performance in allocation and freeing for the hint structs. Signed-off-by: Luka Bai --- mm/khugepaged.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 5090ffae73f3..04cf85ea5557 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -98,6 +98,7 @@ static unsigned int khugepaged_max_ptes_shared __read_mostly; static DEFINE_READ_MOSTLY_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS); static struct kmem_cache *mm_slot_cache __ro_after_init; +static struct kmem_cache *collapse_hint_cache __ro_after_init; #define KHUGEPAGED_PRIORITY_QUEUE_MAX_FAIL 10 @@ -555,6 +556,13 @@ int __init khugepaged_init(void) if (!mm_slot_cache) return -ENOMEM; + collapse_hint_cache = KMEM_CACHE(khugepaged_collapse_hint, 0); + if (!collapse_hint_cache) { + kmem_cache_destroy(mm_slot_cache); + mm_slot_cache = NULL; + return -ENOMEM; + } + for (i = 0; i < NR_KHUGEPAGED_PRIORITY_LEVEL; i++) INIT_LIST_HEAD(&khugepaged_priority_queue[i]); @@ -569,6 +577,7 @@ int __init khugepaged_init(void) void __init khugepaged_destroy(void) { kmem_cache_destroy(mm_slot_cache); + kmem_cache_destroy(collapse_hint_cache); } static inline int collapse_test_exit(struct mm_struct *mm) @@ -686,7 +695,7 @@ static void khugepaged_release_collapse_hints( list_for_each_entry_safe(hint, tmp, &req->hints, node) { list_del(&hint->node); - kfree(hint); + kmem_cache_free(collapse_hint_cache, hint); } } @@ -3013,7 +3022,7 @@ void khugepaged_add_collapse_hint(struct mm_struct *mm, if (!mm_flags_test(MMF_VM_HUGEPAGE, mm)) return; - hint = kmalloc_obj(struct khugepaged_collapse_hint); + hint = kmem_cache_alloc(collapse_hint_cache, GFP_KERNEL); if (!hint) return; @@ -3025,14 +3034,14 @@ void khugepaged_add_collapse_hint(struct mm_struct *mm, * just "best-effort" optimization. */ if (!spin_trylock(&khugepaged_mm_lock)) { - kfree(hint); + kmem_cache_free(collapse_hint_cache, hint); return; } slot = mm_slot_lookup(mm_slots_hash, mm); if (!slot) { spin_unlock(&khugepaged_mm_lock); - kfree(hint); + kmem_cache_free(collapse_hint_cache, hint); return; } khp_mm_slot = mm_slot_entry(slot, struct khugepaged_mm_slot, slot); @@ -3125,7 +3134,7 @@ static int collapse_scan_one_priority_entry(unsigned int progress_max, addr = hint->address; if (unlikely(collapse_test_exit_or_disable(mm))) { - kfree(hint); + kmem_cache_free(collapse_hint_cache, hint); break; } @@ -3149,7 +3158,7 @@ static int collapse_scan_one_priority_entry(unsigned int progress_max, if (*result != SCAN_SUCCEED) (*fail_count)++; skip_hint: - kfree(hint); + kmem_cache_free(collapse_hint_cache, hint); } if (!lock_dropped) -- 2.52.0