aboutsummaryrefslogtreecommitdiffstats
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r--mm/huge_memory.c54
1 files changed, 9 insertions, 45 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index b5783d81eda9..9db521fa8e8a 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -20,6 +20,7 @@
20#include <linux/mman.h> 20#include <linux/mman.h>
21#include <linux/pagemap.h> 21#include <linux/pagemap.h>
22#include <linux/migrate.h> 22#include <linux/migrate.h>
23#include <linux/hashtable.h>
23 24
24#include <asm/tlb.h> 25#include <asm/tlb.h>
25#include <asm/pgalloc.h> 26#include <asm/pgalloc.h>
@@ -62,12 +63,11 @@ static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait);
62static unsigned int khugepaged_max_ptes_none __read_mostly = HPAGE_PMD_NR-1; 63static unsigned int khugepaged_max_ptes_none __read_mostly = HPAGE_PMD_NR-1;
63 64
64static int khugepaged(void *none); 65static int khugepaged(void *none);
65static int mm_slots_hash_init(void);
66static int khugepaged_slab_init(void); 66static int khugepaged_slab_init(void);
67static void khugepaged_slab_free(void);
68 67
69#define MM_SLOTS_HASH_HEADS 1024 68#define MM_SLOTS_HASH_BITS 10
70static struct hlist_head *mm_slots_hash __read_mostly; 69static __read_mostly DEFINE_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
70
71static struct kmem_cache *mm_slot_cache __read_mostly; 71static struct kmem_cache *mm_slot_cache __read_mostly;
72 72
73/** 73/**
@@ -634,12 +634,6 @@ static int __init hugepage_init(void)
634 if (err) 634 if (err)
635 goto out; 635 goto out;
636 636
637 err = mm_slots_hash_init();
638 if (err) {
639 khugepaged_slab_free();
640 goto out;
641 }
642
643 register_shrinker(&huge_zero_page_shrinker); 637 register_shrinker(&huge_zero_page_shrinker);
644 638
645 /* 639 /*
@@ -1908,12 +1902,6 @@ static int __init khugepaged_slab_init(void)
1908 return 0; 1902 return 0;
1909} 1903}
1910 1904
1911static void __init khugepaged_slab_free(void)
1912{
1913 kmem_cache_destroy(mm_slot_cache);
1914 mm_slot_cache = NULL;
1915}
1916
1917static inline struct mm_slot *alloc_mm_slot(void) 1905static inline struct mm_slot *alloc_mm_slot(void)
1918{ 1906{
1919 if (!mm_slot_cache) /* initialization failed */ 1907 if (!mm_slot_cache) /* initialization failed */
@@ -1926,47 +1914,23 @@ static inline void free_mm_slot(struct mm_slot *mm_slot)
1926 kmem_cache_free(mm_slot_cache, mm_slot); 1914 kmem_cache_free(mm_slot_cache, mm_slot);
1927} 1915}
1928 1916
1929static int __init mm_slots_hash_init(void)
1930{
1931 mm_slots_hash = kzalloc(MM_SLOTS_HASH_HEADS * sizeof(struct hlist_head),
1932 GFP_KERNEL);
1933 if (!mm_slots_hash)
1934 return -ENOMEM;
1935 return 0;
1936}
1937
1938#if 0
1939static void __init mm_slots_hash_free(void)
1940{
1941 kfree(mm_slots_hash);
1942 mm_slots_hash = NULL;
1943}
1944#endif
1945
1946static struct mm_slot *get_mm_slot(struct mm_struct *mm) 1917static struct mm_slot *get_mm_slot(struct mm_struct *mm)
1947{ 1918{
1948 struct mm_slot *mm_slot; 1919 struct mm_slot *mm_slot;
1949 struct hlist_head *bucket;
1950 struct hlist_node *node; 1920 struct hlist_node *node;
1951 1921
1952 bucket = &mm_slots_hash[((unsigned long)mm / sizeof(struct mm_struct)) 1922 hash_for_each_possible(mm_slots_hash, mm_slot, node, hash, (unsigned long)mm)
1953 % MM_SLOTS_HASH_HEADS];
1954 hlist_for_each_entry(mm_slot, node, bucket, hash) {
1955 if (mm == mm_slot->mm) 1923 if (mm == mm_slot->mm)
1956 return mm_slot; 1924 return mm_slot;
1957 } 1925
1958 return NULL; 1926 return NULL;
1959} 1927}
1960 1928
1961static void insert_to_mm_slots_hash(struct mm_struct *mm, 1929static void insert_to_mm_slots_hash(struct mm_struct *mm,
1962 struct mm_slot *mm_slot) 1930 struct mm_slot *mm_slot)
1963{ 1931{
1964 struct hlist_head *bucket;
1965
1966 bucket = &mm_slots_hash[((unsigned long)mm / sizeof(struct mm_struct))
1967 % MM_SLOTS_HASH_HEADS];
1968 mm_slot->mm = mm; 1932 mm_slot->mm = mm;
1969 hlist_add_head(&mm_slot->hash, bucket); 1933 hash_add(mm_slots_hash, &mm_slot->hash, (long)mm);
1970} 1934}
1971 1935
1972static inline int khugepaged_test_exit(struct mm_struct *mm) 1936static inline int khugepaged_test_exit(struct mm_struct *mm)
@@ -2035,7 +1999,7 @@ void __khugepaged_exit(struct mm_struct *mm)
2035 spin_lock(&khugepaged_mm_lock); 1999 spin_lock(&khugepaged_mm_lock);
2036 mm_slot = get_mm_slot(mm); 2000 mm_slot = get_mm_slot(mm);
2037 if (mm_slot && khugepaged_scan.mm_slot != mm_slot) { 2001 if (mm_slot && khugepaged_scan.mm_slot != mm_slot) {
2038 hlist_del(&mm_slot->hash); 2002 hash_del(&mm_slot->hash);
2039 list_del(&mm_slot->mm_node); 2003 list_del(&mm_slot->mm_node);
2040 free = 1; 2004 free = 1;
2041 } 2005 }
@@ -2484,7 +2448,7 @@ static void collect_mm_slot(struct mm_slot *mm_slot)
2484 2448
2485 if (khugepaged_test_exit(mm)) { 2449 if (khugepaged_test_exit(mm)) {
2486 /* free mm_slot */ 2450 /* free mm_slot */
2487 hlist_del(&mm_slot->hash); 2451 hash_del(&mm_slot->hash);
2488 list_del(&mm_slot->mm_node); 2452 list_del(&mm_slot->mm_node);
2489 2453
2490 /* 2454 /*