lkml.org 
[lkml]   [2003]   [Sep]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] reduce NFS stack usage
    struct nfs_entry, nfs_readdir_descriptor_t, struct nfs_fh, and struct
    nfs_fattr are all not-small and shouldn't be placed on the stack
    if we can help it. This was noticed in a "do_IRQ stack overflow"
    oops trace, by examining the stack pointer deltas.

    This patch does the obvious -- uses kmalloc.

    Patch against 2.4.23-preXX, but should apply to 2.6.0-test as well.

    Untested, unreviewed... enjoy.



    ===== fs/nfs/dir.c 1.12 vs edited =====
    --- 1.12/fs/nfs/dir.c Tue Oct 15 00:59:27 2002
    +++ edited/fs/nfs/dir.c Mon Sep 22 15:08:27 2003
    @@ -349,14 +349,25 @@
    {
    struct dentry *dentry = filp->f_dentry;
    struct inode *inode = dentry->d_inode;
    - nfs_readdir_descriptor_t my_desc,
    - *desc = &my_desc;
    - struct nfs_entry my_entry;
    + nfs_readdir_descriptor_t *desc;
    + struct nfs_entry *my_entry;
    long res;
    + int rc = -EINVAL;
    + void *mem;
    +
    + mem = kmalloc(sizeof(struct nfs_entry) +
    + sizeof(nfs_readdir_descriptor_t), GFP_KERNEL);
    + if (!mem)
    + return -ENOMEM;
    +
    + my_entry = mem;
    + desc = mem + sizeof(struct nfs_entry);

    res = nfs_revalidate(dentry);
    - if (res < 0)
    - return res;
    + if (res < 0) {
    + rc = (int) res;
    + goto out;
    + }

    /*
    * filp->f_pos points to the file offset in the page cache.
    @@ -365,11 +376,11 @@
    * itself.
    */
    memset(desc, 0, sizeof(*desc));
    - memset(&my_entry, 0, sizeof(my_entry));
    + memset(my_entry, 0, sizeof(my_entry));

    desc->file = filp;
    desc->target = filp->f_pos;
    - desc->entry = &my_entry;
    + desc->entry = my_entry;
    desc->decode = NFS_PROTO(inode)->decode_dirent;

    while(!desc->entry->eof) {
    @@ -393,11 +404,16 @@
    break;
    }
    }
    +
    if (desc->error < 0)
    - return desc->error;
    - if (res < 0)
    - return res;
    - return 0;
    + rc = desc->error;
    + else if (res < 0)
    + rc = res;
    + /* fall through */
    +
    +out:
    + kfree(mem);
    + return rc;
    }

    /*
    @@ -476,13 +492,22 @@
    struct inode *dir;
    struct inode *inode;
    int error;
    - struct nfs_fh fhandle;
    - struct nfs_fattr fattr;
    + struct nfs_fh *fhandle;
    + struct nfs_fattr *fattr;
    + void *mem;
    + int rc = 0;

    lock_kernel();
    dir = dentry->d_parent->d_inode;
    inode = dentry->d_inode;

    + mem = kmalloc(sizeof(struct nfs_fh) + sizeof(struct nfs_fattr),
    + GFP_KERNEL);
    + if (!mem)
    + goto out_bad;
    + fhandle = mem;
    + fattr = mem + sizeof(struct nfs_fh);
    +
    if (!inode) {
    if (nfs_neg_need_reval(dir, dentry))
    goto out_bad;
    @@ -505,18 +530,19 @@
    if (NFS_STALE(inode))
    goto out_bad;

    - error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
    + error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
    if (error)
    goto out_bad;
    - if (memcmp(NFS_FH(inode), &fhandle, sizeof(struct nfs_fh))!= 0)
    + if (memcmp(NFS_FH(inode), fhandle, sizeof(struct nfs_fh))!= 0)
    goto out_bad;
    - if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
    + if ((error = nfs_refresh_inode(inode, fattr)) != 0)
    goto out_bad;

    nfs_renew_times(dentry);
    out_valid:
    - unlock_kernel();
    - return 1;
    + rc = 1;
    + goto out;
    +
    out_bad:
    NFS_CACHEINV(dir);
    if (inode && S_ISDIR(inode->i_mode)) {
    @@ -528,8 +554,14 @@
    shrink_dcache_parent(dentry);
    }
    d_drop(dentry);
    + rc = 0;
    + /* fall through */
    +
    +out:
    unlock_kernel();
    - return 0;
    + if (mem)
    + kfree(mem);
    + return rc;
    }

    /*
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 13:48    [W:0.025 / U:0.176 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site