lkml.org 
[lkml]   [2004]   [Mar]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] [4/6] HUGETLB memory commitment
    [070-mem_acctdom_hugetlb]

    Convert hugetlb to accounting domains (core)

    ---
    fs/hugetlbfs/inode.c | 45 ++++++++++++++++++++++++++++++++++++++-------
    include/linux/hugetlb.h | 5 +++++
    security/commoncap.c | 9 +++++++++
    security/dummy.c | 9 +++++++++
    security/selinux/hooks.c | 9 +++++++++
    5 files changed, 70 insertions(+), 7 deletions(-)

    diff -upN reference/fs/hugetlbfs/inode.c current/fs/hugetlbfs/inode.c
    --- reference/fs/hugetlbfs/inode.c 2004-03-25 02:43:00.000000000 +0000
    +++ current/fs/hugetlbfs/inode.c 2004-03-25 15:03:33.000000000 +0000
    @@ -26,12 +26,15 @@
    #include <linux/dnotify.h>
    #include <linux/statfs.h>
    #include <linux/security.h>
    +#include <linux/mman.h>

    #include <asm/uaccess.h>

    /* some random number */
    #define HUGETLBFS_MAGIC 0x958458f6

    +#define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT)
    +
    static struct super_operations hugetlbfs_ops;
    static struct address_space_operations hugetlbfs_aops;
    struct file_operations hugetlbfs_file_operations;
    @@ -191,6 +194,7 @@ void truncate_hugepages(struct address_s
    static void hugetlbfs_delete_inode(struct inode *inode)
    {
    struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
    + long change;

    hlist_del_init(&inode->i_hash);
    list_del_init(&inode->i_list);
    @@ -198,6 +202,9 @@ static void hugetlbfs_delete_inode(struc
    inodes_stat.nr_inodes--;
    spin_unlock(&inode_lock);

    + change = VM_ACCT(inode->i_size) - VM_ACCT(0);
    + if (change)
    + vm_unacct_memory(VM_AD_HUGETLB, change);
    if (inode->i_data.nrpages)
    truncate_hugepages(&inode->i_data, 0);

    @@ -217,6 +224,7 @@ static void hugetlbfs_forget_inode(struc
    {
    struct super_block *super_block = inode->i_sb;
    struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
    + long change;

    if (hlist_unhashed(&inode->i_hash))
    goto out_truncate;
    @@ -239,6 +247,9 @@ out_truncate:
    inode->i_state |= I_FREEING;
    inodes_stat.nr_inodes--;
    spin_unlock(&inode_lock);
    + change = VM_ACCT(inode->i_size) - VM_ACCT(0);
    + if (change)
    + vm_unacct_memory(VM_AD_HUGETLB, change);
    if (inode->i_data.nrpages)
    truncate_hugepages(&inode->i_data, 0);

    @@ -312,8 +323,10 @@ static int hugetlb_vmtruncate(struct ino
    unsigned long pgoff;
    struct address_space *mapping = inode->i_mapping;

    + /*
    if (offset > inode->i_size)
    return -EINVAL;
    + */

    BUG_ON(offset & ~HPAGE_MASK);
    pgoff = offset >> HPAGE_SHIFT;
    @@ -334,6 +347,8 @@ static int hugetlbfs_setattr(struct dent
    struct inode *inode = dentry->d_inode;
    int error;
    unsigned int ia_valid = attr->ia_valid;
    + long change = 0;
    + loff_t csize;

    BUG_ON(!inode);

    @@ -345,15 +360,27 @@ static int hugetlbfs_setattr(struct dent
    if (error)
    goto out;
    if (ia_valid & ATTR_SIZE) {
    + csize = i_size_read(inode);
    error = -EINVAL;
    - if (!(attr->ia_size & ~HPAGE_MASK))
    - error = hugetlb_vmtruncate(inode, attr->ia_size);
    - if (error)
    + if (!(attr->ia_size & ~HPAGE_MASK))
    + goto out;
    + if (attr->ia_size > csize)
    goto out;
    + change = VM_ACCT(csize) - VM_ACCT(attr->ia_size);
    + if (change)
    + vm_unacct_memory(VM_AD_HUGETLB, change);
    + /* XXX: here we commit to removing the mappings, should we do
    + * this before we attmempt to write the inode or after. What
    + * should we do if it fails?
    + */
    + hugetlb_vmtruncate(inode, attr->ia_size);
    attr->ia_valid &= ~ATTR_SIZE;
    }
    error = inode_setattr(inode, attr);
    out:
    + if (error && change)
    + vm_acct_memory(VM_AD_HUGETLB, change);
    +
    return error;
    }

    @@ -710,17 +737,19 @@ struct file *hugetlb_zero_setup(size_t s
    if (!capable(CAP_IPC_LOCK))
    return ERR_PTR(-EPERM);

    - if (!is_hugepage_mem_enough(size))
    + if (security_vm_enough_memory(VM_AD_HUGETLB, VM_ACCT(size)))
    return ERR_PTR(-ENOMEM);
    -
    +
    root = hugetlbfs_vfsmount->mnt_root;
    snprintf(buf, 16, "%lu", hugetlbfs_counter());
    quick_string.name = buf;
    quick_string.len = strlen(quick_string.name);
    quick_string.hash = 0;
    dentry = d_alloc(root, &quick_string);
    - if (!dentry)
    - return ERR_PTR(-ENOMEM);
    + if (!dentry) {
    + error = -ENOMEM;
    + goto out_committed;
    + }

    error = -ENFILE;
    file = get_empty_filp();
    @@ -747,6 +776,8 @@ out_file:
    put_filp(file);
    out_dentry:
    dput(dentry);
    +out_committed:
    + vm_unacct_memory(VM_AD_HUGETLB, VM_ACCT(size));
    return ERR_PTR(error);
    }

    diff -upN reference/include/linux/hugetlb.h current/include/linux/hugetlb.h
    --- reference/include/linux/hugetlb.h 2004-02-23 18:15:09.000000000 +0000
    +++ current/include/linux/hugetlb.h 2004-03-25 15:03:33.000000000 +0000
    @@ -19,6 +19,7 @@ int hugetlb_prefault(struct address_spac
    void huge_page_release(struct page *);
    int hugetlb_report_meminfo(char *);
    int is_hugepage_mem_enough(size_t);
    +unsigned long hugetlb_total_pages(void);
    struct page *follow_huge_addr(struct mm_struct *mm, struct vm_area_struct *vma,
    unsigned long address, int write);
    struct vm_area_struct *hugepage_vma(struct mm_struct *mm,
    @@ -48,6 +49,10 @@ static inline int is_vm_hugetlb_page(str
    {
    return 0;
    }
    +static inline unsigned long hugetlb_total_pages(void)
    +{
    + return 0;
    +}

    #define follow_hugetlb_page(m,v,p,vs,a,b,i) ({ BUG(); 0; })
    #define follow_huge_addr(mm, vma, addr, write) 0
    diff -upN reference/security/commoncap.c current/security/commoncap.c
    --- reference/security/commoncap.c 2004-03-25 15:03:32.000000000 +0000
    +++ current/security/commoncap.c 2004-03-25 15:03:33.000000000 +0000
    @@ -22,6 +22,7 @@
    #include <linux/netlink.h>
    #include <linux/ptrace.h>
    #include <linux/xattr.h>
    +#include <linux/hugetlb.h>

    int cap_capable (struct task_struct *tsk, int cap)
    {
    @@ -314,6 +315,13 @@ int cap_vm_enough_memory(int domain, lon

    vm_acct_memory(domain, pages);

    + /* Check against the full compliment of hugepages, no reserve. */
    + if (domain == VM_AD_HUGETLB) {
    + allowed = hugetlb_total_pages();
    +
    + goto check;
    + }
    +
    /* We only account for the default memory domain, assume overcommit
    * for all others.
    */
    @@ -367,6 +375,7 @@ int cap_vm_enough_memory(int domain, lon
    allowed = totalram_pages * sysctl_overcommit_ratio / 100;
    allowed += total_swap_pages;

    +check:
    if (atomic_read(&vm_committed_space[domain]) < allowed)
    return 0;

    diff -upN reference/security/dummy.c current/security/dummy.c
    --- reference/security/dummy.c 2004-03-25 15:03:32.000000000 +0000
    +++ current/security/dummy.c 2004-03-25 15:03:33.000000000 +0000
    @@ -25,6 +25,7 @@
    #include <linux/netlink.h>
    #include <net/sock.h>
    #include <linux/xattr.h>
    +#include <linux/hugetlb.h>

    static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
    {
    @@ -115,6 +116,13 @@ static int dummy_vm_enough_memory(int do

    vm_acct_memory(domain, pages);

    + /* Check against the full compliment of hugepages, no reserve. */
    + if (domain == VM_AD_HUGETLB) {
    + allowed = hugetlb_total_pages();
    +
    + goto check;
    + }
    +
    /* We only account for the default memory domain, assume overcommit
    * for all others.
    */
    @@ -155,6 +163,7 @@ static int dummy_vm_enough_memory(int do
    allowed = totalram_pages * sysctl_overcommit_ratio / 100;
    allowed += total_swap_pages;

    +check:
    if (atomic_read(&vm_committed_space[domain]) < allowed)
    return 0;

    diff -upN reference/security/selinux/hooks.c current/security/selinux/hooks.c
    --- reference/security/selinux/hooks.c 2004-03-25 15:03:32.000000000 +0000
    +++ current/security/selinux/hooks.c 2004-03-25 15:03:33.000000000 +0000
    @@ -59,6 +59,7 @@
    #include <net/af_unix.h> /* for Unix socket types */
    #include <linux/parser.h>
    #include <linux/nfs_mount.h>
    +#include <linux/hugetlb.h>

    #include "avc.h"
    #include "objsec.h"
    @@ -1504,6 +1505,13 @@ static int selinux_vm_enough_memory(int

    vm_acct_memory(domain, pages);

    + /* Check against the full compliment of hugepages, no reserve. */
    + if (domain == VM_AD_HUGETLB) {
    + allowed = hugetlb_total_pages();
    +
    + goto check;
    + }
    +
    /* We only account for the default memory domain, assume overcommit
    * for all others.
    */
    @@ -1553,6 +1561,7 @@ static int selinux_vm_enough_memory(int
    allowed = totalram_pages * sysctl_overcommit_ratio / 100;
    allowed += total_swap_pages;

    +check:
    if (atomic_read(&vm_committed_space[domain]) < allowed)
    return 0;

    -
    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 14:01    [W:4.825 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site