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)) {