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

Commit 3421f6b3 authored by Kyle Yan's avatar Kyle Yan Committed by Prasad Sodagudi
Browse files

timer: Add a global deferrable timer



Add a global deferrable timer in addition to the per-cpu deferrable timer
to allow deferrable timers without the TIMER_PINNED flag to run
on any active CPU.

Change-Id: I8e6b77cef972589912ad18f324c46c936fbbb96f
Signed-off-by: default avatarKyle Yan <kyan@codeaurora.org>
Signed-off-by: default avatarPrasad Sodagudi <psodagud@codeaurora.org>
parent 58cc082c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -198,6 +198,8 @@ extern void add_timer(struct timer_list *timer);

extern int try_to_del_timer_sync(struct timer_list *timer);

extern struct timer_base timer_base_deferrable;

#ifdef CONFIG_SMP
  extern int del_timer_sync(struct timer_list *timer);
#else
+15 −4
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ struct timer_base {
} ____cacheline_aligned;

static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]);
struct timer_base timer_base_deferrable;

#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
unsigned int sysctl_timer_migration = 1;
@@ -231,6 +232,9 @@ void timers_update_migration(bool update_nohz)
		per_cpu(timer_bases[BASE_DEF].nohz_active, cpu) = true;
		per_cpu(hrtimer_bases.nohz_active, cpu) = true;
	}

	timer_base_deferrable.migration_enabled = on;
	timer_base_deferrable.nohz_active = true;
}

int timer_migration_handler(struct ctl_table *table, int write,
@@ -817,8 +821,11 @@ static inline struct timer_base *get_timer_cpu_base(u32 tflags, u32 cpu)
	 * the deferrable base.
	 */
	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active &&
	    (tflags & TIMER_DEFERRABLE))
	    (tflags & TIMER_DEFERRABLE)) {
		base = &timer_base_deferrable;
		if (tflags & TIMER_PINNED)
			base = per_cpu_ptr(&timer_bases[BASE_DEF], cpu);
	}
	return base;
}

@@ -832,6 +839,8 @@ static inline struct timer_base *get_timer_this_cpu_base(u32 tflags)
	 */
	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active &&
	    (tflags & TIMER_DEFERRABLE))
		base = &timer_base_deferrable;
		if (tflags & TIMER_PINNED)
			base = this_cpu_ptr(&timer_bases[BASE_DEF]);
	return base;
}
@@ -1612,9 +1621,11 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h)
	struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);

	__run_timers(base);
	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active)
	if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) {
		__run_timers(&timer_base_deferrable);
		__run_timers(this_cpu_ptr(&timer_bases[BASE_DEF]));
	}
}

/*
 * Called by the local, per-CPU timer interrupt on SMP.