lkml.org 
[lkml]   [2013]   [Nov]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
SubjectRe: [3.10] Oopses in kmem_cache_allocate() via prepare_creds()
From
On Sat, Nov 30, 2013 at 1:43 AM, Simon Kirby <sim@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)) {
\
 
 \ /
  Last update: 2013-11-30 22:21    [W:0.053 / U:1.208 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site