X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=linux-2.6-590-GC-dcookies.patch;h=fee1c31eebfce0dc5e2b9601b0236547e385256a;hb=69829d1f43b2952b176fe645191e0f320fd3dcc9;hp=bf9c6f2ebd3a74b69c8f5ac1047064d42220b6a1;hpb=8d2a46e745f588e95d1a3972576266666ec3a92b;p=linux-2.6.git diff --git a/linux-2.6-590-GC-dcookies.patch b/linux-2.6-590-GC-dcookies.patch index bf9c6f2eb..fee1c31ee 100644 --- a/linux-2.6-590-GC-dcookies.patch +++ b/linux-2.6-590-GC-dcookies.patch @@ -1,139 +1,190 @@ ---- linux-2.6.22.19-chopstix/fs/dcookies.c 2009-02-28 03:10:05.000000000 -0500 -+++ linux-2.6.22.19-chopstix/fs/dcookies.c.orig 2008-02-25 18:59:40.000000000 -0500 -@@ -38,19 +38,14 @@ +diff -Nurb linux-2.6.22.19/fs/dcookies.c linux-2.6.22.19-dcookies/fs/dcookies.c +--- linux-2.6.22.19/fs/dcookies.c 2008-02-25 18:59:40.000000000 -0500 ++++ linux-2.6.22.19-dcookies/fs/dcookies.c 2009-03-16 14:44:24.000000000 -0400 +@@ -38,14 +38,19 @@ static LIST_HEAD(dcookie_users); static DEFINE_MUTEX(dcookie_mutex); static struct kmem_cache *dcookie_cache __read_mostly; --static struct list_head *dcookie_hashtable[2] __read_mostly; -+static struct list_head *dcookie_hashtable __read_mostly; +-static struct list_head *dcookie_hashtable __read_mostly; ++static struct list_head *dcookie_hashtable[3] __read_mostly; static size_t hash_size __read_mostly; --unsigned int current_hash = 0; ++unsigned int current_hash = 0, old_hash = -1; static inline int is_live(void) { return !(list_empty(&dcookie_users)); } --static inline int is_shared(void) --{ -- return !(list_empty(&dcookie_users)) && !(list_empty(dcookie_users.next)); --} ++static inline int is_shared(void) ++{ ++ return !(list_empty(&dcookie_users)) && !(list_empty(dcookie_users.next)); ++} /* The dentry is locked, its address will do for the cookie */ static inline unsigned long dcookie_value(struct dcookie_struct * dcs) -@@ -72,7 +67,7 @@ +@@ -67,7 +72,7 @@ struct list_head * pos; struct list_head * list; -- list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie); -+ list = dcookie_hashtable + dcookie_hash(dcookie); +- list = dcookie_hashtable + dcookie_hash(dcookie); ++ list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie); list_for_each(pos, list) { dcs = list_entry(pos, struct dcookie_struct, hash_list); -@@ -88,7 +83,7 @@ +@@ -77,13 +82,26 @@ + } + } + ++ if (!found && (old_hash!=-1)) { ++ list = dcookie_hashtable[old_hash] + dcookie_hash(dcookie); ++ ++ list_for_each(pos, list) { ++ dcs = list_entry(pos, struct dcookie_struct, hash_list); ++ if (dcookie_value(dcs) == dcookie) { ++ found = dcs; ++ break; ++ } ++ } ++ ++ } ++ + return found; + } + static void hash_dcookie(struct dcookie_struct * dcs) { -- struct list_head * list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie_value(dcs)); -+ struct list_head * list = dcookie_hashtable + dcookie_hash(dcookie_value(dcs)); +- struct list_head * list = dcookie_hashtable + dcookie_hash(dcookie_value(dcs)); ++ struct list_head * list = dcookie_hashtable[current_hash] + dcookie_hash(dcookie_value(dcs)); list_add(&dcs->hash_list, list); } -@@ -96,7 +91,7 @@ +@@ -91,7 +109,7 @@ static struct dcookie_struct * alloc_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt) { -- struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_ATOMIC); -+ struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL); +- struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL); ++ struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_ATOMIC); if (!dcs) return NULL; -@@ -215,12 +210,8 @@ +@@ -210,10 +228,19 @@ if (!dcookie_cache) goto out; -- dcookie_hashtable[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); -- if (!dcookie_hashtable[0]) -- goto out_kmem; -- -- dcookie_hashtable[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); -- if (!dcookie_hashtable[1]) -+ dcookie_hashtable = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if (!dcookie_hashtable) +- dcookie_hashtable = kmalloc(PAGE_SIZE, GFP_KERNEL); +- if (!dcookie_hashtable) ++ dcookie_hashtable[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); ++ if (!dcookie_hashtable[0]) ++ goto out_kmem; ++ ++ dcookie_hashtable[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); ++ if (!dcookie_hashtable[1]) goto out_kmem; ++ dcookie_hashtable[2] = kmalloc(PAGE_SIZE, GFP_KERNEL); ++ if (!dcookie_hashtable[0]) ++ goto out_kmem; ++ ++ err = 0; -@@ -244,15 +235,7 @@ + + /* +@@ -235,7 +262,24 @@ hash_size = 1UL << hash_bits; /* And initialize the newly allocated array */ -- d = dcookie_hashtable[0]; -- i = hash_size; -- do { -- INIT_LIST_HEAD(d); -- d++; -- i--; -- } while (i); -- -- d = dcookie_hashtable[1]; -+ d = dcookie_hashtable; +- d = dcookie_hashtable; ++ ++ d = dcookie_hashtable[0]; ++ i = hash_size; ++ do { ++ INIT_LIST_HEAD(d); ++ d++; ++ i--; ++ } while (i); ++ ++ d = dcookie_hashtable[1]; ++ i = hash_size; ++ do { ++ INIT_LIST_HEAD(d); ++ d++; ++ i--; ++ } while (i); ++ ++ d = dcookie_hashtable[2]; i = hash_size; do { INIT_LIST_HEAD(d); -@@ -276,30 +259,6 @@ +@@ -259,6 +303,39 @@ kmem_cache_free(dcookie_cache, dcs); } --/* Switch to the second hash */ --int garbage_collect(void) { -- struct list_head * list; -- struct list_head * pos; -- struct list_head * pos2; -- struct dcookie_struct * dcs; -- size_t i; -- -- if (is_shared()) -- return -EAGAIN; -- -- for (i = 0; i < hash_size; ++i) { -- list = dcookie_hashtable[current_hash] + i; -- list_for_each_safe(pos, pos2, list) { -- dcs = list_entry(pos, struct dcookie_struct, hash_list); -- list_del(&dcs->hash_list); -- free_dcookie(dcs); -- } -- } -- -- current_hash = (current_hash & 1) ^ 1; -- -- return 0; --} ++int dcookie_swap(void) { ++ if (is_shared()) ++ return -EAGAIN; ++ ++ old_hash=current_hash; ++ current_hash = (current_hash + 1) % 3; ++ return 0; ++} ++ ++/* Switch to the second hash */ ++int dcookie_garbage_collect(void) { ++ struct list_head * list; ++ struct list_head * pos; ++ struct list_head * pos2; ++ struct dcookie_struct * dcs; ++ size_t i; ++ int next_hash=(current_hash + 1) % 3; ++ ++ if (is_shared()) ++ return -EAGAIN; ++ ++ /* XXX consider the consequence of dcookie allocation concurring with this cleanup */ ++ for (i = 0; i < hash_size; ++i) { ++ list = dcookie_hashtable[next_hash] + i; ++ list_for_each_safe(pos, pos2, list) { ++ dcs = list_entry(pos, struct dcookie_struct, hash_list); ++ list_del(&dcs->hash_list); ++ free_dcookie(dcs); ++ } ++ } ++ ++ return 0; ++} static void dcookie_exit(void) { -@@ -310,14 +269,7 @@ +@@ -269,7 +346,14 @@ size_t i; for (i = 0; i < hash_size; ++i) { -- list = dcookie_hashtable[0] + i; -- list_for_each_safe(pos, pos2, list) { -- dcs = list_entry(pos, struct dcookie_struct, hash_list); -- list_del(&dcs->hash_list); -- free_dcookie(dcs); -- } -- -- list = dcookie_hashtable[1] + i; -+ list = dcookie_hashtable + i; +- list = dcookie_hashtable + i; ++ list = dcookie_hashtable[0] + i; ++ list_for_each_safe(pos, pos2, list) { ++ dcs = list_entry(pos, struct dcookie_struct, hash_list); ++ list_del(&dcs->hash_list); ++ free_dcookie(dcs); ++ } ++ ++ list = dcookie_hashtable[1] + i; list_for_each_safe(pos, pos2, list) { dcs = list_entry(pos, struct dcookie_struct, hash_list); list_del(&dcs->hash_list); -@@ -325,8 +277,7 @@ +@@ -277,7 +361,8 @@ } } -- kfree(dcookie_hashtable[0]); -- kfree(dcookie_hashtable[1]); -+ kfree(dcookie_hashtable); +- kfree(dcookie_hashtable); ++ kfree(dcookie_hashtable[0]); ++ kfree(dcookie_hashtable[1]); kmem_cache_destroy(dcookie_cache); } +@@ -327,3 +412,5 @@ + EXPORT_SYMBOL_GPL(dcookie_register); + EXPORT_SYMBOL_GPL(dcookie_unregister); + EXPORT_SYMBOL_GPL(get_dcookie); ++EXPORT_SYMBOL_GPL(dcookie_garbage_collect); ++EXPORT_SYMBOL_GPL(dcookie_swap);