aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBrent Casavant <bcasavan@sgi.com>2005-01-03 04:17:25 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-03 04:17:25 -0800
commite330572fb04d1901d917f8a8c32941bac5cded8b (patch)
tree12df3320f5e32798e8c1d6eaaa3053d94ff92b9b /fs
parentdcee73c4378e99a401a661773b2361da9c448afb (diff)
downloadhistory-e330572fb04d1901d917f8a8c32941bac5cded8b.tar.gz
[PATCH] filesystem hashes: NUMA interleaving
The following patch modifies the dentry cache and inode cache to enable the use of vmalloc to alleviate boottime memory allocation imbalances on NUMA systems, utilizing flags to the alloc_large_system_hash routine in order to centralize the enabling of this behavior. In general, for each hash, we check at the early allocation point whether hash distribution is enabled, and if so we defer allocation. At the late allocation point we perform the allocation if it was not earlier deferred. These late allocation points are the same points utilized prior to the addition of alloc_large_system_hash to the kernel. Signed-off-by: Brent Casavant <bcasavan@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/dcache.c25
-rw-r--r--fs/inode.c25
2 files changed, 50 insertions, 0 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 13f0cce0550d54..500c4c4d02f49d 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1574,6 +1574,12 @@ static void __init dcache_init_early(void)
{
int loop;
+ /* If hashes are distributed across NUMA nodes, defer
+ * hash allocation until vmalloc space is available.
+ */
+ if (hashdist)
+ return;
+
dentry_hashtable =
alloc_large_system_hash("Dentry cache",
sizeof(struct hlist_head),
@@ -1590,6 +1596,8 @@ static void __init dcache_init_early(void)
static void __init dcache_init(unsigned long mempages)
{
+ int loop;
+
/*
* A constructor could be added for stable state like the lists,
* but it is probably not worth it because of the cache nature
@@ -1602,6 +1610,23 @@ static void __init dcache_init(unsigned long mempages)
NULL, NULL);
set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory);
+
+ /* Hash may have been set up in dcache_init_early */
+ if (!hashdist)
+ return;
+
+ dentry_hashtable =
+ alloc_large_system_hash("Dentry cache",
+ sizeof(struct hlist_head),
+ dhash_entries,
+ 13,
+ 0,
+ &d_hash_shift,
+ &d_hash_mask,
+ 0);
+
+ for (loop = 0; loop < (1 << d_hash_shift); loop++)
+ INIT_HLIST_HEAD(&dentry_hashtable[loop]);
}
/* SLAB cache for __getname() consumers */
diff --git a/fs/inode.c b/fs/inode.c
index 2126c475def0ff..77173753e39712 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1328,6 +1328,12 @@ void __init inode_init_early(void)
{
int loop;
+ /* If hashes are distributed across NUMA nodes, defer
+ * hash allocation until vmalloc space is available.
+ */
+ if (hashdist)
+ return;
+
inode_hashtable =
alloc_large_system_hash("Inode-cache",
sizeof(struct hlist_head),
@@ -1344,10 +1350,29 @@ void __init inode_init_early(void)
void __init inode_init(unsigned long mempages)
{
+ int loop;
+
/* inode slab cache */
inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode),
0, SLAB_PANIC, init_once, NULL);
set_shrinker(DEFAULT_SEEKS, shrink_icache_memory);
+
+ /* Hash may have been set up in inode_init_early */
+ if (!hashdist)
+ return;
+
+ inode_hashtable =
+ alloc_large_system_hash("Inode-cache",
+ sizeof(struct hlist_head),
+ ihash_entries,
+ 14,
+ 0,
+ &i_hash_shift,
+ &i_hash_mask,
+ 0);
+
+ for (loop = 0; loop < (1 << i_hash_shift); loop++)
+ INIT_HLIST_HEAD(&inode_hashtable[loop]);
}
void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)