lkml.org 
[lkml]   [2011]   [Jun]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[04/85] [CPUFREQ] Fix memory leak in cpufreq_stat
    2.6.33-longterm review patch.  If anyone has any objections, please let us know.

    ------------------

    From: steven finney <Steven.Finney@palm.com>

    commit 98586ed8b8878e10691203687e89a42fa3355300 upstream.

    When a CPU is taken offline in an SMP system, cpufreq_remove_dev()
    nulls out the per-cpu policy before cpufreq_stats_free_table() can
    make use of it. cpufreq_stats_free_table() then skips the
    call to sysfs_remove_group(), leaving about 100 bytes of sysfs-related
    memory unclaimed each time a CPU-removal occurs. Break up
    cpu_stats_free_table into sysfs and table portions, and
    call the sysfs portion early.

    Signed-off-by: Steven Finney <steven.finney@palm.com>
    Signed-off-by: Dave Jones <davej@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/cpufreq/cpufreq_stats.c | 21 ++++++++++++++++++---
    1 file changed, 18 insertions(+), 3 deletions(-)

    --- a/drivers/cpufreq/cpufreq_stats.c
    +++ b/drivers/cpufreq/cpufreq_stats.c
    @@ -164,17 +164,27 @@ static int freq_table_get_index(struct c
    return -1;
    }

    +/* should be called late in the CPU removal sequence so that the stats
    + * memory is still available in case someone tries to use it.
    + */
    static void cpufreq_stats_free_table(unsigned int cpu)
    {
    struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu);
    - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
    - if (policy && policy->cpu == cpu)
    - sysfs_remove_group(&policy->kobj, &stats_attr_group);
    if (stat) {
    kfree(stat->time_in_state);
    kfree(stat);
    }
    per_cpu(cpufreq_stats_table, cpu) = NULL;
    +}
    +
    +/* must be called early in the CPU removal sequence (before
    + * cpufreq_remove_dev) so that policy is still valid.
    + */
    +static void cpufreq_stats_free_sysfs(unsigned int cpu)
    +{
    + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
    + if (policy && policy->cpu == cpu)
    + sysfs_remove_group(&policy->kobj, &stats_attr_group);
    if (policy)
    cpufreq_cpu_put(policy);
    }
    @@ -315,6 +325,9 @@ static int __cpuinit cpufreq_stat_cpu_ca
    case CPU_ONLINE_FROZEN:
    cpufreq_update_policy(cpu);
    break;
    + case CPU_DOWN_PREPARE:
    + cpufreq_stats_free_sysfs(cpu);
    + break;
    case CPU_DEAD:
    case CPU_DEAD_FROZEN:
    cpufreq_stats_free_table(cpu);
    @@ -323,9 +336,11 @@ static int __cpuinit cpufreq_stat_cpu_ca
    return NOTIFY_OK;
    }

    +/* priority=1 so this will get called before cpufreq_remove_dev */
    static struct notifier_block cpufreq_stat_cpu_notifier __refdata =
    {
    .notifier_call = cpufreq_stat_cpu_callback,
    + .priority = 1,
    };

    static struct notifier_block notifier_policy_block = {



    \
     
     \ /
      Last update: 2011-06-16 09:27    [W:2.224 / U:0.404 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site