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