[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>
This commit is contained in:
committed by
Linus Torvalds
parent
c815afc73e
commit
e60d4398a7
@@ -70,8 +70,6 @@ u32 list_add_perfile = 0;
|
|||||||
u32 list_del_perfile = 0;
|
u32 list_del_perfile = 0;
|
||||||
u32 add_perclient = 0;
|
u32 add_perclient = 0;
|
||||||
u32 del_perclient = 0;
|
u32 del_perclient = 0;
|
||||||
u32 alloc_file = 0;
|
|
||||||
u32 free_file = 0;
|
|
||||||
u32 vfsopen = 0;
|
u32 vfsopen = 0;
|
||||||
u32 vfsclose = 0;
|
u32 vfsclose = 0;
|
||||||
u32 alloc_delegation= 0;
|
u32 alloc_delegation= 0;
|
||||||
@@ -90,6 +88,9 @@ static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
|
|||||||
*/
|
*/
|
||||||
static DECLARE_MUTEX(client_sema);
|
static DECLARE_MUTEX(client_sema);
|
||||||
|
|
||||||
|
kmem_cache_t *stateowner_slab = NULL;
|
||||||
|
kmem_cache_t *file_slab = NULL;
|
||||||
|
|
||||||
void
|
void
|
||||||
nfs4_lock_state(void)
|
nfs4_lock_state(void)
|
||||||
{
|
{
|
||||||
@@ -961,14 +962,14 @@ alloc_init_file(struct inode *ino)
|
|||||||
struct nfs4_file *fp;
|
struct nfs4_file *fp;
|
||||||
unsigned int hashval = file_hashval(ino);
|
unsigned int hashval = file_hashval(ino);
|
||||||
|
|
||||||
if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
|
fp = kmem_cache_alloc(file_slab, GFP_KERNEL);
|
||||||
|
if (fp) {
|
||||||
INIT_LIST_HEAD(&fp->fi_hash);
|
INIT_LIST_HEAD(&fp->fi_hash);
|
||||||
INIT_LIST_HEAD(&fp->fi_perfile);
|
INIT_LIST_HEAD(&fp->fi_perfile);
|
||||||
INIT_LIST_HEAD(&fp->fi_del_perfile);
|
INIT_LIST_HEAD(&fp->fi_del_perfile);
|
||||||
list_add(&fp->fi_hash, &file_hashtbl[hashval]);
|
list_add(&fp->fi_hash, &file_hashtbl[hashval]);
|
||||||
fp->fi_inode = igrab(ino);
|
fp->fi_inode = igrab(ino);
|
||||||
fp->fi_id = current_fileid++;
|
fp->fi_id = current_fileid++;
|
||||||
alloc_file++;
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -992,29 +993,41 @@ release_all_files(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kmem_cache_t *stateowner_slab = NULL;
|
static void
|
||||||
|
nfsd4_free_slab(kmem_cache_t **slab)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (*slab == NULL)
|
||||||
|
return;
|
||||||
|
status = kmem_cache_destroy(*slab);
|
||||||
|
*slab = NULL;
|
||||||
|
WARN_ON(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nfsd4_free_slabs(void)
|
||||||
|
{
|
||||||
|
nfsd4_free_slab(&stateowner_slab);
|
||||||
|
nfsd4_free_slab(&file_slab);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nfsd4_init_slabs(void)
|
nfsd4_init_slabs(void)
|
||||||
{
|
{
|
||||||
stateowner_slab = kmem_cache_create("nfsd4_stateowners",
|
stateowner_slab = kmem_cache_create("nfsd4_stateowners",
|
||||||
sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL);
|
sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL);
|
||||||
if (stateowner_slab == NULL) {
|
if (stateowner_slab == NULL)
|
||||||
dprintk("nfsd4: out of memory while initializing nfsv4\n");
|
goto out_nomem;
|
||||||
return -ENOMEM;
|
file_slab = kmem_cache_create("nfsd4_files",
|
||||||
}
|
sizeof(struct nfs4_file), 0, 0, NULL, NULL);
|
||||||
|
if (file_slab == NULL)
|
||||||
|
goto out_nomem;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
out_nomem:
|
||||||
|
nfsd4_free_slabs();
|
||||||
static void
|
dprintk("nfsd4: out of memory while initializing nfsv4\n");
|
||||||
nfsd4_free_slabs(void)
|
return -ENOMEM;
|
||||||
{
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
if (stateowner_slab)
|
|
||||||
status = kmem_cache_destroy(stateowner_slab);
|
|
||||||
stateowner_slab = NULL;
|
|
||||||
BUG_ON(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1167,10 +1180,9 @@ release_stateid(struct nfs4_stateid *stp, int flags)
|
|||||||
static void
|
static void
|
||||||
release_file(struct nfs4_file *fp)
|
release_file(struct nfs4_file *fp)
|
||||||
{
|
{
|
||||||
free_file++;
|
|
||||||
list_del(&fp->fi_hash);
|
list_del(&fp->fi_hash);
|
||||||
iput(fp->fi_inode);
|
iput(fp->fi_inode);
|
||||||
kfree(fp);
|
kmem_cache_free(file_slab, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -3286,8 +3298,6 @@ __nfs4_state_shutdown(void)
|
|||||||
list_add_perfile, list_del_perfile);
|
list_add_perfile, list_del_perfile);
|
||||||
dprintk("NFSD: add_perclient %d del_perclient %d\n",
|
dprintk("NFSD: add_perclient %d del_perclient %d\n",
|
||||||
add_perclient, del_perclient);
|
add_perclient, del_perclient);
|
||||||
dprintk("NFSD: alloc_file %d free_file %d\n",
|
|
||||||
alloc_file, free_file);
|
|
||||||
dprintk("NFSD: vfsopen %d vfsclose %d\n",
|
dprintk("NFSD: vfsopen %d vfsclose %d\n",
|
||||||
vfsopen, vfsclose);
|
vfsopen, vfsclose);
|
||||||
dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
|
dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
|
||||||
|
Reference in New Issue
Block a user