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

Commit ae1bcff1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cpuidle: lpm-levels: Free the allocated resource to avoid memory leak"

parents 5148a8f2 68aed363
Loading
Loading
Loading
Loading
+43 −23
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ module_param_named(
static int msm_pm_sleep_time_override;
module_param_named(sleep_time_override,
	msm_pm_sleep_time_override, int, S_IRUGO | S_IWUSR | S_IWGRP);
static uint64_t suspend_wake_time;

static bool print_parsed_dt;
module_param_named(
@@ -123,6 +124,21 @@ s32 msm_cpuidle_get_deep_idle_latency(void)
	return 10;
}

void lpm_suspend_wake_time(uint64_t wakeup_time)
{
	if (wakeup_time <= 0) {
		suspend_wake_time = msm_pm_sleep_time_override;
		return;
	}

	if (msm_pm_sleep_time_override &&
		(msm_pm_sleep_time_override < wakeup_time))
		suspend_wake_time = msm_pm_sleep_time_override;
	else
		suspend_wake_time = wakeup_time;
}
EXPORT_SYMBOL(lpm_suspend_wake_time);

static void update_debug_pc_event(enum debug_event event, uint32_t arg1,
		uint32_t arg2, uint32_t arg3, uint32_t arg4)
{
@@ -377,18 +393,19 @@ static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster,
	struct cpumask online_cpus_in_cluster;

	next_event.tv64 = KTIME_MAX;

	if (!suspend_wake_time)
		suspend_wake_time =  msm_pm_sleep_time_override;
	if (!from_idle) {
		if (mask)
			cpumask_copy(mask, cpumask_of(raw_smp_processor_id()));
		if (!msm_pm_sleep_time_override)
		if (!suspend_wake_time)
			return ~0ULL;
		else
			return USEC_PER_SEC * msm_pm_sleep_time_override;
			return USEC_PER_SEC * suspend_wake_time;
	}

	BUG_ON(!cpumask_and(&online_cpus_in_cluster,
			&cluster->num_childs_in_sync, cpu_online_mask));
	cpumask_and(&online_cpus_in_cluster,
			&cluster->num_children_in_sync, cpu_online_mask);

	for_each_cpu(cpu, &online_cpus_in_cluster) {
		td = &per_cpu(tick_cpu_device, cpu);
@@ -449,7 +466,7 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle)
			cpumask_weight(cpu_online_mask) > 1)
			continue;

		if (!cpumask_equal(&cluster->num_childs_in_sync,
		if (!cpumask_equal(&cluster->num_children_in_sync,
					&level->num_cpu_votes))
			continue;

@@ -491,18 +508,18 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,

	spin_lock(&cluster->sync_lock);

	if (!cpumask_equal(&cluster->num_childs_in_sync, &cluster->child_cpus)
			|| is_IPI_pending(&cluster->num_childs_in_sync)) {
	if (!cpumask_equal(&cluster->num_children_in_sync, &cluster->child_cpus)
			|| is_IPI_pending(&cluster->num_children_in_sync)) {
		spin_unlock(&cluster->sync_lock);
		return -EPERM;
	}

	if (idx != cluster->default_level) {
		update_debug_pc_event(CLUSTER_ENTER, idx,
			cluster->num_childs_in_sync.bits[0],
			cluster->num_children_in_sync.bits[0],
			cluster->child_cpus.bits[0], from_idle);
		trace_cluster_enter(cluster->cluster_name, idx,
			cluster->num_childs_in_sync.bits[0],
			cluster->num_children_in_sync.bits[0],
			cluster->child_cpus.bits[0], from_idle);
		lpm_stats_cluster_enter(cluster->stats, idx);
	}
@@ -568,8 +585,8 @@ static void cluster_prepare(struct lpm_cluster *cluster,
		return;

	spin_lock(&cluster->sync_lock);
	cpumask_or(&cluster->num_childs_in_sync, cpu,
			&cluster->num_childs_in_sync);
	cpumask_or(&cluster->num_children_in_sync, cpu,
			&cluster->num_children_in_sync);

	for (i = 0; i < cluster->nlevels; i++) {
		struct lpm_cluster_level *lvl = &cluster->levels[i];
@@ -586,7 +603,7 @@ static void cluster_prepare(struct lpm_cluster *cluster,
	 * configuration process
	 */

	if (!cpumask_equal(&cluster->num_childs_in_sync,
	if (!cpumask_equal(&cluster->num_children_in_sync,
				&cluster->child_cpus)) {
		spin_unlock(&cluster->sync_lock);
		return;
@@ -601,7 +618,7 @@ static void cluster_prepare(struct lpm_cluster *cluster,
	if (cluster_configure(cluster, i, from_idle))
		return;

	cluster_prepare(cluster->parent, &cluster->num_childs_in_sync, i,
	cluster_prepare(cluster->parent, &cluster->num_children_in_sync, i,
			from_idle);
}

@@ -620,10 +637,10 @@ static void cluster_unprepare(struct lpm_cluster *cluster,

	spin_lock(&cluster->sync_lock);
	last_level = cluster->default_level;
	first_cpu = cpumask_equal(&cluster->num_childs_in_sync,
	first_cpu = cpumask_equal(&cluster->num_children_in_sync,
				&cluster->child_cpus);
	cpumask_andnot(&cluster->num_childs_in_sync,
			&cluster->num_childs_in_sync, cpu);
	cpumask_andnot(&cluster->num_children_in_sync,
			&cluster->num_children_in_sync, cpu);

	for (i = 0; i < cluster->nlevels; i++) {
		struct lpm_cluster_level *lvl = &cluster->levels[i];
@@ -652,10 +669,10 @@ static void cluster_unprepare(struct lpm_cluster *cluster,
	}

	update_debug_pc_event(CLUSTER_EXIT, cluster->last_level,
			cluster->num_childs_in_sync.bits[0],
			cluster->num_children_in_sync.bits[0],
			cluster->child_cpus.bits[0], from_idle);
	trace_cluster_exit(cluster->cluster_name, cluster->last_level,
			cluster->num_childs_in_sync.bits[0],
			cluster->num_children_in_sync.bits[0],
			cluster->child_cpus.bits[0], from_idle);

	last_level = cluster->last_level;
@@ -750,7 +767,7 @@ int get_cluster_id(struct lpm_cluster *cluster, int *aff_lvl)

	spin_lock(&cluster->sync_lock);

	if (!cpumask_equal(&cluster->num_childs_in_sync,
	if (!cpumask_equal(&cluster->num_children_in_sync,
				&cluster->child_cpus))
		goto unlock_and_return;

@@ -952,10 +969,10 @@ static int cluster_cpuidle_register(struct lpm_cluster *cl)
		while (p) {
			int j;
			spin_lock(&p->sync_lock);
			cpumask_set_cpu(cpu, &p->num_childs_in_sync);
			cpumask_set_cpu(cpu, &p->num_children_in_sync);
			for (j = 0; j < p->nlevels; j++)
				cpumask_copy(&p->levels[j].num_cpu_votes,
						&p->num_childs_in_sync);
						&p->num_children_in_sync);
			spin_unlock(&p->sync_lock);
			p = p->parent;
		}
@@ -986,6 +1003,8 @@ static void register_cpu_lpm_stats(struct lpm_cpu *cpu,

	lpm_stats_config_level("cpu", level_name, cpu->nlevels,
			parent->stats, &parent->child_cpus);

	kfree(level_name);
}

static void register_cluster_lpm_stats(struct lpm_cluster *cl,
@@ -1212,7 +1231,8 @@ enum msm_pm_l2_scm_flag lpm_cpu_pre_pc_cb(unsigned int cpu)
		goto unlock_and_return;
	}

	if (!cpumask_equal(&cluster->num_childs_in_sync, &cluster->child_cpus))
	if (!cpumask_equal(&cluster->num_children_in_sync,
						&cluster->child_cpus))
		goto unlock_and_return;

	if (cluster->lpm_dev)
+2 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ struct lpm_cluster {
	struct cpuidle_driver *drv;
	spinlock_t sync_lock;
	struct cpumask child_cpus;
	struct cpumask num_childs_in_sync;
	struct cpumask num_children_in_sync;
	struct lpm_cluster *parent;
	struct lpm_stats *stats;
	unsigned int psci_mode_shift;
@@ -105,6 +105,7 @@ struct lpm_cluster {
int set_l2_mode(struct low_power_ops *ops, int mode, bool notify_rpm);
int set_system_mode(struct low_power_ops *ops, int mode, bool notify_rpm);
int set_l3_mode(struct low_power_ops *ops, int mode, bool notify_rpm);
void lpm_suspend_wake_time(uint64_t wakeup_time);

struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev);
void free_cluster_node(struct lpm_cluster *cluster);