aboutsummaryrefslogtreecommitdiffstats
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
authorSasha Levin <sasha.levin@oracle.com>2013-02-22 19:32:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:10 -0500
commit43b5fbbd28294e095653d3c1ba9c399b2168e8df (patch)
tree509f1bfe3c16a85ed561067aa56ea66853b1f726 /mm/huge_memory.c
parenta9aacbccf3145355190d87f0df1731fb84fdd8c8 (diff)
mm/huge_memory.c: use new hashtable implementation
Switch hugemem to use the new hashtable implementation. This reduces the amount of generic unrelated code in the hugemem. This also removes the dymanic allocation of the hash table. The upside is that we save a pointer dereference when accessing the hashtable, but we lose 8KB if CONFIG_TRANSPARENT_HUGEPAGE is enabled but the processor doesn't support hugepages. Signed-off-by: Sasha Levin <sasha.levin@oracle.com> Cc: David Rientjes <rientjes@google.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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 /*