Skip to content

Commit

Permalink
nohz: Convert a few places to use local per cpu accesses
Browse files Browse the repository at this point in the history
A few functions use remote per CPU access APIs when they
deal with local values.

Just do the right conversion to improve performance, code
readability and debug checks.

While at it, lets extend some of these function names with *_this_cpu()
suffix in order to display their purpose more clearly.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Frederic Weisbecker committed Dec 2, 2013
1 parent dc1ccc4 commit e8fcaa5
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 34 deletions.
6 changes: 3 additions & 3 deletions include/linux/tick.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ extern struct cpumask *tick_get_broadcast_oneshot_mask(void);
extern void tick_clock_notify(void);
extern int tick_check_oneshot_change(int allow_nohz);
extern struct tick_sched *tick_get_tick_sched(int cpu);
extern void tick_check_idle(int cpu);
extern void tick_check_idle(void);
extern int tick_oneshot_mode_active(void);
# ifndef arch_needs_cpu
# define arch_needs_cpu(cpu) (0)
# endif
# else
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
static inline void tick_check_idle(int cpu) { }
static inline void tick_check_idle(void) { }
static inline int tick_oneshot_mode_active(void) { return 0; }
# endif

Expand All @@ -121,7 +121,7 @@ static inline void tick_init(void) { }
static inline void tick_cancel_sched_timer(int cpu) { }
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
static inline void tick_check_idle(int cpu) { }
static inline void tick_check_idle(void) { }
static inline int tick_oneshot_mode_active(void) { return 0; }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */

Expand Down
4 changes: 1 addition & 3 deletions kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,16 +311,14 @@ asmlinkage void do_softirq(void)
*/
void irq_enter(void)
{
int cpu = smp_processor_id();

rcu_irq_enter();
if (is_idle_task(current) && !in_interrupt()) {
/*
* Prevent raise_softirq from needlessly waking up ksoftirqd
* here, as softirq will be serviced on return from interrupt.
*/
local_bh_disable();
tick_check_idle(cpu);
tick_check_idle();
_local_bh_enable();
}

Expand Down
6 changes: 3 additions & 3 deletions kernel/time/tick-broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,10 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
* Called from irq_enter() when idle was interrupted to reenable the
* per cpu device.
*/
void tick_check_oneshot_broadcast(int cpu)
void tick_check_oneshot_broadcast_this_cpu(void)
{
if (cpumask_test_cpu(cpu, tick_broadcast_oneshot_mask)) {
struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
if (cpumask_test_cpu(smp_processor_id(), tick_broadcast_oneshot_mask)) {
struct tick_device *td = &__get_cpu_var(tick_cpu_device);

/*
* We might be in the middle of switching over from
Expand Down
4 changes: 2 additions & 2 deletions kernel/time/tick-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ extern void tick_broadcast_switch_to_oneshot(void);
extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
extern int tick_broadcast_oneshot_active(void);
extern void tick_check_oneshot_broadcast(int cpu);
extern void tick_check_oneshot_broadcast_this_cpu(void);
bool tick_broadcast_oneshot_available(void);
# else /* BROADCAST */
static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
Expand All @@ -62,7 +62,7 @@ static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
static inline void tick_broadcast_switch_to_oneshot(void) { }
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
static inline int tick_broadcast_oneshot_active(void) { return 0; }
static inline void tick_check_oneshot_broadcast(int cpu) { }
static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
static inline bool tick_broadcast_oneshot_available(void) { return true; }
# endif /* !BROADCAST */

Expand Down
39 changes: 16 additions & 23 deletions kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,9 @@ __setup("nohz=", setup_tick_nohz);
*/
static void tick_nohz_update_jiffies(ktime_t now)
{
int cpu = smp_processor_id();
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
unsigned long flags;

ts->idle_waketime = now;
__this_cpu_write(tick_cpu_sched.idle_waketime, now);

local_irq_save(flags);
tick_do_update_jiffies64(now);
Expand Down Expand Up @@ -426,17 +424,15 @@ update_ts_time_stats(int cpu, struct tick_sched *ts, ktime_t now, u64 *last_upda

}

static void tick_nohz_stop_idle(int cpu, ktime_t now)
static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)
{
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);

update_ts_time_stats(cpu, ts, now, NULL);
update_ts_time_stats(smp_processor_id(), ts, now, NULL);
ts->idle_active = 0;

sched_clock_idle_wakeup_event(0);
}

static ktime_t tick_nohz_start_idle(int cpu, struct tick_sched *ts)
static ktime_t tick_nohz_start_idle(struct tick_sched *ts)
{
ktime_t now = ktime_get();

Expand Down Expand Up @@ -752,7 +748,7 @@ static void __tick_nohz_idle_enter(struct tick_sched *ts)
ktime_t now, expires;
int cpu = smp_processor_id();

now = tick_nohz_start_idle(cpu, ts);
now = tick_nohz_start_idle(ts);

if (can_stop_idle_tick(cpu, ts)) {
int was_stopped = ts->tick_stopped;
Expand Down Expand Up @@ -914,8 +910,7 @@ static void tick_nohz_account_idle_ticks(struct tick_sched *ts)
*/
void tick_nohz_idle_exit(void)
{
int cpu = smp_processor_id();
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
ktime_t now;

local_irq_disable();
Expand All @@ -928,7 +923,7 @@ void tick_nohz_idle_exit(void)
now = ktime_get();

if (ts->idle_active)
tick_nohz_stop_idle(cpu, now);
tick_nohz_stop_idle(ts, now);

if (ts->tick_stopped) {
tick_nohz_restart_sched_tick(ts, now);
Expand Down Expand Up @@ -1012,12 +1007,10 @@ static void tick_nohz_switch_to_nohz(void)
* timer and do not touch the other magic bits which need to be done
* when idle is left.
*/
static void tick_nohz_kick_tick(int cpu, ktime_t now)
static void tick_nohz_kick_tick(struct tick_sched *ts, ktime_t now)
{
#if 0
/* Switch back to 2.6.27 behaviour */

struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
ktime_t delta;

/*
Expand All @@ -1032,36 +1025,36 @@ static void tick_nohz_kick_tick(int cpu, ktime_t now)
#endif
}

static inline void tick_check_nohz(int cpu)
static inline void tick_check_nohz_this_cpu(void)
{
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
ktime_t now;

if (!ts->idle_active && !ts->tick_stopped)
return;
now = ktime_get();
if (ts->idle_active)
tick_nohz_stop_idle(cpu, now);
tick_nohz_stop_idle(ts, now);
if (ts->tick_stopped) {
tick_nohz_update_jiffies(now);
tick_nohz_kick_tick(cpu, now);
tick_nohz_kick_tick(ts, now);
}
}

#else

static inline void tick_nohz_switch_to_nohz(void) { }
static inline void tick_check_nohz(int cpu) { }
static inline void tick_check_nohz_this_cpu(void) { }

#endif /* CONFIG_NO_HZ_COMMON */

/*
* Called from irq_enter to notify about the possible interruption of idle()
*/
void tick_check_idle(int cpu)
void tick_check_idle(void)
{
tick_check_oneshot_broadcast(cpu);
tick_check_nohz(cpu);
tick_check_oneshot_broadcast_this_cpu();
tick_check_nohz_this_cpu();
}

/*
Expand Down

0 comments on commit e8fcaa5

Please sign in to comment.