lkml.org 
[lkml]   [2010]   [May]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V2] x86/pat: fix memory leak in free_memtype
    Date
    reserve_memtype will allocate memory for new memtype, but
    in free_memtype, after the memtype erased from rbtree, the
    memory is not freed.

    Changes since V1:
    make rbt_memtype_erase return erased memtype so that
    it can be freed in free_memtype.

    Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
    Cc: Jack Steiner <steiner@sgi.com>
    Cc: Suresh Siddha <suresh.b.siddha@intel.com>
    ---
    arch/x86/mm/pat.c | 10 +++++++---
    arch/x86/mm/pat_internal.h | 6 +++---
    arch/x86/mm/pat_rbtree.c | 7 ++++---
    3 files changed, 14 insertions(+), 9 deletions(-)

    diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
    index bbe5502..bf2b5fa 100644
    --- a/arch/x86/mm/pat.c
    +++ b/arch/x86/mm/pat.c
    @@ -336,6 +336,7 @@ int free_memtype(u64 start, u64 end)
    {
    int err = -EINVAL;
    int is_range_ram;
    + struct memtype *entry;

    if (!pat_enabled)
    return 0;
    @@ -355,17 +356,20 @@ int free_memtype(u64 start, u64 end)
    }

    spin_lock(&memtype_lock);
    - err = rbt_memtype_erase(start, end);
    + entry = rbt_memtype_erase(start, end);
    spin_unlock(&memtype_lock);

    - if (err) {
    + if (!entry) {
    printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
    current->comm, current->pid, start, end);
    + return -EINVAL;
    }
    +
    + kfree(entry);

    dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end);

    - return err;
    + return 0;
    }


    diff --git a/arch/x86/mm/pat_internal.h b/arch/x86/mm/pat_internal.h
    index 4f39eef..77e5ba1 100644
    --- a/arch/x86/mm/pat_internal.h
    +++ b/arch/x86/mm/pat_internal.h
    @@ -28,15 +28,15 @@ static inline char *cattr_name(unsigned long flags)
    #ifdef CONFIG_X86_PAT
    extern int rbt_memtype_check_insert(struct memtype *new,
    unsigned long *new_type);
    -extern int rbt_memtype_erase(u64 start, u64 end);
    +extern struct memtype *rbt_memtype_erase(u64 start, u64 end);
    extern struct memtype *rbt_memtype_lookup(u64 addr);
    extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos);
    #else
    static inline int rbt_memtype_check_insert(struct memtype *new,
    unsigned long *new_type)
    { return 0; }
    -static inline int rbt_memtype_erase(u64 start, u64 end)
    -{ return 0; }
    +static inline struct memtype *rbt_memtype_erase(u64 start, u64 end)
    +{ return NULL; }
    static inline struct memtype *rbt_memtype_lookup(u64 addr)
    { return NULL; }
    static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos)
    diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
    index 07de4cb..f537087 100644
    --- a/arch/x86/mm/pat_rbtree.c
    +++ b/arch/x86/mm/pat_rbtree.c
    @@ -231,16 +231,17 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
    return err;
    }

    -int rbt_memtype_erase(u64 start, u64 end)
    +struct memtype *rbt_memtype_erase(u64 start, u64 end)
    {
    struct memtype *data;

    data = memtype_rb_exact_match(&memtype_rbroot, start, end);
    if (!data)
    - return -EINVAL;
    + goto out;

    rb_erase(&data->rb, &memtype_rbroot);
    - return 0;
    +out:
    + return data;
    }

    struct memtype *rbt_memtype_lookup(u64 addr)
    --
    1.6.6.1


    \
     
     \ /
      Last update: 2010-05-26 03:53    [W:0.024 / U:7.512 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site