aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-06-24 01:03:01 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 03:06:29 -0400
commite60d4398a7c20fbe9c4a6cc39d7188ef9f65d2f1 (patch)
treed634acd73c61b04e873349eee638251fc433cd2c
parentc815afc73eeef089922449857ca4ed4d2e8950cb (diff)
[PATCH] nfsd4: slabify nfs4_files
The structures the server uses to keep track of various pieces of nfsv4 state (open files, outstanding delegations, etc.) are likely to be allocated and deallocated frequently and seem reasonable candidates for slab caches. While we're at it, the slab code keeps statistics that help catch leaks and such, so we may as well take this chance to eliminate some debugging counters that we've been keeping ourselves. Start with the struct nfs4_file. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/nfsd/nfs4state.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 8ac0c9abe941..260c1cbe25c4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -70,8 +70,6 @@ u32 list_add_perfile = 0;
70u32 list_del_perfile = 0; 70u32 list_del_perfile = 0;
71u32 add_perclient = 0; 71u32 add_perclient = 0;
72u32 del_perclient = 0; 72u32 del_perclient = 0;
73u32 alloc_file = 0;
74u32 free_file = 0;
75u32 vfsopen = 0; 73u32 vfsopen = 0;
76u32 vfsclose = 0; 74u32 vfsclose = 0;
77u32 alloc_delegation= 0; 75u32 alloc_delegation= 0;
@@ -90,6 +88,9 @@ static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
90 */ 88 */
91static DECLARE_MUTEX(client_sema); 89static DECLARE_MUTEX(client_sema);
92 90
91kmem_cache_t *stateowner_slab = NULL;
92kmem_cache_t *file_slab = NULL;
93
93void 94void
94nfs4_lock_state(void) 95nfs4_lock_state(void)
95{ 96{
@@ -961,14 +962,14 @@ alloc_init_file(struct inode *ino)
961 struct nfs4_file *fp; 962 struct nfs4_file *fp;
962 unsigned int hashval = file_hashval(ino); 963 unsigned int hashval = file_hashval(ino);
963 964
964 if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) { 965 fp = kmem_cache_alloc(file_slab, GFP_KERNEL);
966 if (fp) {
965 INIT_LIST_HEAD(&fp->fi_hash); 967 INIT_LIST_HEAD(&fp->fi_hash);
966 INIT_LIST_HEAD(&fp->fi_perfile); 968 INIT_LIST_HEAD(&fp->fi_perfile);
967 INIT_LIST_HEAD(&fp->fi_del_perfile); 969 INIT_LIST_HEAD(&fp->fi_del_perfile);
968 list_add(&fp->fi_hash, &file_hashtbl[hashval]); 970 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
969 fp->fi_inode = igrab(ino); 971 fp->fi_inode = igrab(ino);
970 fp->fi_id = current_fileid++; 972 fp->fi_id = current_fileid++;
971 alloc_file++;
972 return fp; 973 return fp;
973 } 974 }
974 return NULL; 975 return NULL;
@@ -992,29 +993,41 @@ release_all_files(void)
992 } 993 }
993} 994}
994 995
995kmem_cache_t *stateowner_slab = NULL; 996static void
996 997nfsd4_free_slab(kmem_cache_t **slab)
997static int
998nfsd4_init_slabs(void)
999{ 998{
1000 stateowner_slab = kmem_cache_create("nfsd4_stateowners", 999 int status;
1001 sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL); 1000
1002 if (stateowner_slab == NULL) { 1001 if (*slab == NULL)
1003 dprintk("nfsd4: out of memory while initializing nfsv4\n"); 1002 return;
1004 return -ENOMEM; 1003 status = kmem_cache_destroy(*slab);
1005 } 1004 *slab = NULL;
1006 return 0; 1005 WARN_ON(status);
1007} 1006}
1008 1007
1009static void 1008static void
1010nfsd4_free_slabs(void) 1009nfsd4_free_slabs(void)
1011{ 1010{
1012 int status = 0; 1011 nfsd4_free_slab(&stateowner_slab);
1012 nfsd4_free_slab(&file_slab);
1013}
1013 1014
1014 if (stateowner_slab) 1015static int
1015 status = kmem_cache_destroy(stateowner_slab); 1016nfsd4_init_slabs(void)
1016 stateowner_slab = NULL; 1017{
1017 BUG_ON(status); 1018 stateowner_slab = kmem_cache_create("nfsd4_stateowners",
1019 sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL);
1020 if (stateowner_slab == NULL)
1021 goto out_nomem;
1022 file_slab = kmem_cache_create("nfsd4_files",
1023 sizeof(struct nfs4_file), 0, 0, NULL, NULL);
1024 if (file_slab == NULL)
1025 goto out_nomem;
1026 return 0;
1027out_nomem:
1028 nfsd4_free_slabs();
1029 dprintk("nfsd4: out of memory while initializing nfsv4\n");
1030 return -ENOMEM;
1018} 1031}
1019 1032
1020void 1033void
@@ -1167,10 +1180,9 @@ release_stateid(struct nfs4_stateid *stp, int flags)
1167static void 1180static void
1168release_file(struct nfs4_file *fp) 1181release_file(struct nfs4_file *fp)
1169{ 1182{
1170 free_file++;
1171 list_del(&fp->fi_hash); 1183 list_del(&fp->fi_hash);
1172 iput(fp->fi_inode); 1184 iput(fp->fi_inode);
1173 kfree(fp); 1185 kmem_cache_free(file_slab, fp);
1174} 1186}
1175 1187
1176void 1188void
@@ -3286,8 +3298,6 @@ __nfs4_state_shutdown(void)
3286 list_add_perfile, list_del_perfile); 3298 list_add_perfile, list_del_perfile);
3287 dprintk("NFSD: add_perclient %d del_perclient %d\n", 3299 dprintk("NFSD: add_perclient %d del_perclient %d\n",
3288 add_perclient, del_perclient); 3300 add_perclient, del_perclient);
3289 dprintk("NFSD: alloc_file %d free_file %d\n",
3290 alloc_file, free_file);
3291 dprintk("NFSD: vfsopen %d vfsclose %d\n", 3301 dprintk("NFSD: vfsopen %d vfsclose %d\n",
3292 vfsopen, vfsclose); 3302 vfsopen, vfsclose);
3293 dprintk("NFSD: alloc_delegation %d free_delegation %d\n", 3303 dprintk("NFSD: alloc_delegation %d free_delegation %d\n",