diff options
author | Chris Wright <chrisw@osdl.org> | 2004-12-16 23:12:52 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2004-12-16 23:12:52 -0800 |
commit | 7edb095c1831c3c361beafbcff8e6ef3e5b094f9 (patch) | |
tree | 5ca70a44ae335e1368f27d5a34dc61922da8a841 /fs | |
parent | 41a96b10c549f8323514f1a2482660a4ae4eb73f (diff) | |
download | history-7edb095c1831c3c361beafbcff8e6ef3e5b094f9.tar.gz |
[PATCH] sysfs: Allocate sysfs_dirent structures from their own slab.
* Andrew Morton (akpm@osdl.org) wrote:
> That's all well and good, but sysfs_new_dirent() should be using a
> standalone slab cache for allocating sysfs_dirent instances. That way, we
> use 36 bytes for each one rather than 64.
Reasonable, here's a patch (lightly tested). Without, size-64 looks
like so:
size-64 4064 4108 76 52 1 : tunables 32 16 8 : slabdata 79 79 0 : globalstat 4263 4079 79 0 0 0 84 0 : cpustat 15986 337 12286 3
And with:
size-64 1196 1196 76 52 1 : tunables 32 16 8 : slabdata 23 23 0 : globalstat 1297 1196 23 0 0 0 84 0 : cpustat 12418 108 11349 1
sysfs_dir_cache 2862 2916 48 81 1 : tunables 32 16 8 : slabdata 36 36 0 : globalstat 2931 2874 36 0 0 0 113 0 : cpustat 2756 216 110 0
Allocate sysfs_dirent structures from their own slab.
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/dir.c | 2 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 17 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 3 |
3 files changed, 18 insertions, 4 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index b0a7905431b126..fe198210bc2d53 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -36,7 +36,7 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd, { struct sysfs_dirent * sd; - sd = kmalloc(sizeof(*sd), GFP_KERNEL); + sd = kmem_cache_alloc(sysfs_dir_cachep, GFP_KERNEL); if (!sd) return NULL; diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 57b69917610518..5c30a6eaf6da5a 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c @@ -16,6 +16,7 @@ struct vfsmount *sysfs_mount; struct super_block * sysfs_sb = NULL; +kmem_cache_t *sysfs_dir_cachep; static struct super_operations sysfs_ops = { .statfs = simple_statfs, @@ -76,7 +77,13 @@ static struct file_system_type sysfs_fs_type = { int __init sysfs_init(void) { - int err; + int err = -ENOMEM; + + sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache", + sizeof(struct sysfs_dirent), + 0, 0, NULL, NULL); + if (!sysfs_dir_cachep) + goto out; err = register_filesystem(&sysfs_fs_type); if (!err) { @@ -85,7 +92,13 @@ int __init sysfs_init(void) printk(KERN_ERR "sysfs: could not mount!\n"); err = PTR_ERR(sysfs_mount); sysfs_mount = NULL; + goto out_err; } - } + } else + goto out_err; +out: return err; +out_err: + kmem_cache_destroy(sysfs_dir_cachep); + goto out; } diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index f1075824d9a050..a8a24a0c0b3bd4 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -1,5 +1,6 @@ extern struct vfsmount * sysfs_mount; +extern kmem_cache_t *sysfs_dir_cachep; extern struct inode * sysfs_new_inode(mode_t mode); extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); @@ -74,7 +75,7 @@ static inline void release_sysfs_dirent(struct sysfs_dirent * sd) kobject_put(sl->target_kobj); kfree(sl); } - kfree(sd); + kmem_cache_free(sysfs_dir_cachep, sd); } static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd) |