On Sat, Nov 30, 2013 at 1:43 AM, Simon Kirby <s...@hostway.ca> wrote:
>
> I turned on kmalloc-192 tracing to find what else is using it: struct
> nfs_fh, struct bio, and struct cred. Poking around those, struct bio has
> bi_cnt, but it is way down in the struct. struct cred has "usage", but it
> comes first.

You could also try to avoid the whole aliasing by using a separate
slab for just the pipe_inode_info.

Something like the attached patch (which also enables debugging just
for that slab).

I still don't see what could be wrong with the pipe_inode_info thing,
but the fact that it's been so consistent in your traces does make me
suspect it really is *that* particular slab. But I dunno, and this
would just confirm it.

                Linus
 fs/pipe.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index d2c45e14e6d8..7cfd6cdf0147 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -729,7 +729,7 @@ pipe_poll(struct file *filp, poll_table *wait)
 static int
 pipe_release(struct inode *inode, struct file *file)
 {
-       struct pipe_inode_info *pipe = inode->i_pipe;
+       struct pipe_inode_info *pipe = file->private_data;
        int kill = 0;
 
        __pipe_lock(pipe);
@@ -776,11 +776,13 @@ pipe_fasync(int fd, struct file *filp, int on)
        return retval;
 }
 
+static struct kmem_cache *pipe_info_slab;
+
 struct pipe_inode_info *alloc_pipe_info(void)
 {
        struct pipe_inode_info *pipe;
 
-       pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
+       pipe = kmem_cache_zalloc(pipe_info_slab, GFP_KERNEL);
        if (pipe) {
                pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * 
PIPE_DEF_BUFFERS, GFP_KERNEL);
                if (pipe->bufs) {
@@ -790,7 +792,7 @@ struct pipe_inode_info *alloc_pipe_info(void)
                        mutex_init(&pipe->mutex);
                        return pipe;
                }
-               kfree(pipe);
+               kmem_cache_free(pipe_info_slab, pipe);
        }
 
        return NULL;
@@ -808,7 +810,7 @@ void free_pipe_info(struct pipe_inode_info *pipe)
        if (pipe->tmp_page)
                __free_page(pipe->tmp_page);
        kfree(pipe->bufs);
-       kfree(pipe);
+       kmem_cache_free(pipe_info_slab, pipe);
 }
 
 static struct vfsmount *pipe_mnt __read_mostly;
@@ -1311,8 +1313,17 @@ static struct file_system_type pipe_fs_type = {
 
 static int __init init_pipe_fs(void)
 {
-       int err = register_filesystem(&pipe_fs_type);
+       int err;
+
+       pipe_info_slab = kmem_cache_create("pipe-inode-info",
+               sizeof(struct pipe_inode_info),
+               0,
+               SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | SLAB_DEBUG_FREE,
+               NULL);
+       if (!pipe_info_slab)
+               return -ENOMEM;
 
+       err = register_filesystem(&pipe_fs_type);
        if (!err) {
                pipe_mnt = kern_mount(&pipe_fs_type);
                if (IS_ERR(pipe_mnt)) {

Reply via email to