Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e19e7af authored by Wei Wang's avatar Wei Wang Committed by TARKZiM
Browse files

kernel: initialize and free cpufreq stats properly



Initialize task's cpufreq to NULL including for idle
Make sure free task's cpufreq when free task struct

[backported to 3.10: Corinna Vinschen <xda@vinschen.de>]

Bug: 110044919
Change-Id: Ie4629d0ebe3ef4b72dffea3ee613b15f40a57142
Signed-off-by: default avatarWei Wang <wvw@google.com>
parent 22fc5259
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -234,14 +234,18 @@ static int cpufreq_stats_update(unsigned int cpu)

void cpufreq_task_stats_init(struct task_struct *p)
{
	size_t alloc_size;
	void *temp;
	unsigned long flags;

	spin_lock_irqsave(&task_time_in_state_lock, flags);
	p->time_in_state = NULL;
	spin_unlock_irqrestore(&task_time_in_state_lock, flags);
	WRITE_ONCE(p->max_states, 0);
}

void cpufreq_task_stats_alloc(struct task_struct *p)
{
	size_t alloc_size;
	void *temp;
	unsigned long flags;

	if (!all_freq_table || !cpufreq_all_freq_init)
		return;
@@ -1007,6 +1011,11 @@ static int process_notifier(struct notifier_block *self,
	return NOTIFY_OK;
}

void cpufreq_task_stats_free(struct task_struct *p)
{
	kfree(p->time_in_state);
}

static int uid_time_in_state_open(struct inode *inode, struct file *file)
{
	return single_open(file, uid_time_in_state_show, PDE_DATA(inode));
+2 −0
Original line number Diff line number Diff line
@@ -491,6 +491,8 @@ static inline int cpufreq_generic_exit(struct cpufreq_policy *policy)

void acct_update_power(struct task_struct *p, cputime_t cputime);
void cpufreq_task_stats_init(struct task_struct *p);
void cpufreq_task_stats_alloc(struct task_struct *p);
void cpufreq_task_stats_free(struct task_struct *p);
void cpufreq_task_stats_remove_uids(uid_t uid_start, uid_t uid_end);
int  proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
	struct pid *pid, struct task_struct *p);
+4 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@
#include <linux/signalfd.h>
#include <linux/uprobes.h>
#include <linux/aio.h>
#include <linux/cpufreq.h>

#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -210,6 +211,9 @@ static void account_kernel_stack(struct thread_info *ti, int account)

void free_task(struct task_struct *tsk)
{
#ifdef CONFIG_CPU_FREQ_STAT
	cpufreq_task_stats_free(tsk);
#endif
	account_kernel_stack(tsk->stack, -1);
	arch_release_thread_info(tsk->stack);
	free_thread_info(tsk->stack);
+7 −2
Original line number Diff line number Diff line
@@ -3498,6 +3498,10 @@ static void __sched_fork(struct task_struct *p)
	memset(&p->se.statistics, 0, sizeof(p->se.statistics));
#endif

#ifdef CONFIG_CPU_FREQ_STAT
	cpufreq_task_stats_init(p);
#endif

	INIT_LIST_HEAD(&p->rt.run_list);

#ifdef CONFIG_PREEMPT_NOTIFIERS
@@ -3546,11 +3550,12 @@ void sched_fork(struct task_struct *p)
	unsigned long flags;
	int cpu = get_cpu();

	__sched_fork(p);

#ifdef CONFIG_CPU_FREQ_STAT
	cpufreq_task_stats_init(p);
	cpufreq_task_stats_alloc(p);
#endif

	__sched_fork(p);
	/*
	 * We mark the process as running here. This guarantees that
	 * nobody will actually run it, and a signal or other external