Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ksm: cleanup for mm_slots_hash

Use compile-allocated memory instead of dynamic allocated memory for
mm_slots_hash.

Use hash_ptr() instead divisions for bucket calculation.

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Izik Eidus <ieidus@redhat.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Lai Jiangshan and committed by
Linus Torvalds
d9f8984c e31f3698

+9 -29
+9 -29
mm/ksm.c
··· 33 33 #include <linux/mmu_notifier.h> 34 34 #include <linux/swap.h> 35 35 #include <linux/ksm.h> 36 + #include <linux/hash.h> 36 37 37 38 #include <asm/tlbflush.h> 38 39 #include "internal.h" ··· 154 153 static struct rb_root root_stable_tree = RB_ROOT; 155 154 static struct rb_root root_unstable_tree = RB_ROOT; 156 155 157 - #define MM_SLOTS_HASH_HEADS 1024 158 - static struct hlist_head *mm_slots_hash; 156 + #define MM_SLOTS_HASH_SHIFT 10 157 + #define MM_SLOTS_HASH_HEADS (1 << MM_SLOTS_HASH_SHIFT) 158 + static struct hlist_head mm_slots_hash[MM_SLOTS_HASH_HEADS]; 159 159 160 160 static struct mm_slot ksm_mm_head = { 161 161 .mm_list = LIST_HEAD_INIT(ksm_mm_head.mm_list), ··· 271 269 kmem_cache_free(mm_slot_cache, mm_slot); 272 270 } 273 271 274 - static int __init mm_slots_hash_init(void) 275 - { 276 - mm_slots_hash = kzalloc(MM_SLOTS_HASH_HEADS * sizeof(struct hlist_head), 277 - GFP_KERNEL); 278 - if (!mm_slots_hash) 279 - return -ENOMEM; 280 - return 0; 281 - } 282 - 283 - static void __init mm_slots_hash_free(void) 284 - { 285 - kfree(mm_slots_hash); 286 - } 287 - 288 272 static struct mm_slot *get_mm_slot(struct mm_struct *mm) 289 273 { 290 274 struct mm_slot *mm_slot; 291 275 struct hlist_head *bucket; 292 276 struct hlist_node *node; 293 277 294 - bucket = &mm_slots_hash[((unsigned long)mm / sizeof(struct mm_struct)) 295 - % MM_SLOTS_HASH_HEADS]; 278 + bucket = &mm_slots_hash[hash_ptr(mm, MM_SLOTS_HASH_SHIFT)]; 296 279 hlist_for_each_entry(mm_slot, node, bucket, link) { 297 280 if (mm == mm_slot->mm) 298 281 return mm_slot; ··· 290 303 { 291 304 struct hlist_head *bucket; 292 305 293 - bucket = &mm_slots_hash[((unsigned long)mm / sizeof(struct mm_struct)) 294 - % MM_SLOTS_HASH_HEADS]; 306 + bucket = &mm_slots_hash[hash_ptr(mm, MM_SLOTS_HASH_SHIFT)]; 295 307 mm_slot->mm = mm; 296 308 hlist_add_head(&mm_slot->link, bucket); 297 309 } ··· 1924 1938 if (err) 1925 1939 goto out; 1926 1940 1927 - err = mm_slots_hash_init(); 1928 - if (err) 1929 - goto out_free1; 1930 - 1931 1941 ksm_thread = kthread_run(ksm_scan_thread, NULL, "ksmd"); 1932 1942 if (IS_ERR(ksm_thread)) { 1933 1943 printk(KERN_ERR "ksm: creating kthread failed\n"); 1934 1944 err = PTR_ERR(ksm_thread); 1935 - goto out_free2; 1945 + goto out_free; 1936 1946 } 1937 1947 1938 1948 #ifdef CONFIG_SYSFS ··· 1936 1954 if (err) { 1937 1955 printk(KERN_ERR "ksm: register sysfs failed\n"); 1938 1956 kthread_stop(ksm_thread); 1939 - goto out_free2; 1957 + goto out_free; 1940 1958 } 1941 1959 #else 1942 1960 ksm_run = KSM_RUN_MERGE; /* no way for user to start it */ ··· 1952 1970 #endif 1953 1971 return 0; 1954 1972 1955 - out_free2: 1956 - mm_slots_hash_free(); 1957 - out_free1: 1973 + out_free: 1958 1974 ksm_slab_free(); 1959 1975 out: 1960 1976 return err;