sched_clock: Squashed revert of the latest updates

Revert "sched_clock: Avoid corrupting hrtimer tree during suspend"

This reverts commit 8aad725c70.

Revert "sched_clock: Add support for >32 bit sched_clock"

This reverts commit 657eb100e4.

Revert "sched_clock: Use an hrtimer instead of timer"

This reverts commit b2ee62ec51.

Revert "sched_clock: Use seqcount instead of rolling our own"

This reverts commit 538b187b6e.

Revert "ARM: sched_clock: Load cycle count after epoch stabilizes"

This reverts commit 8c7175ba39.

Revert "sched_clock: Make ARM's sched_clock generic for all architectures"

This reverts commit ebb97da74a.

Revert "ARM: 7699/1: sched_clock: Add more notrace to prevent recursion"

This reverts commit 086da6a6c4.

Revert "ARM: make sched_clock just call a function pointer"

This reverts commit 0dd4fad6c9.

Revert "ARM: sched_clock: allow changing to higher frequency counter"

This reverts commit 4a3cf85432.

Change-Id: I98aaec7b554a2e11be4c551a864d952e0d8c3e22
This commit is contained in:
Artem Borisov 2018-02-17 17:47:01 +03:00
parent 84655b5f70
commit e2c600a1f3
25 changed files with 80 additions and 111 deletions

View File

@ -37,7 +37,6 @@ config ARM
select GENERIC_IRQ_SHOW
select CPU_PM if (SUSPEND || CPU_IDLE)
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select HAVE_BPF_JIT if NET
select GENERIC_SMP_IDLE_THREAD
help

View File

@ -25,8 +25,8 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
#include <asm/hardware/arm_timer.h>
static long __init sp804_get_clock_rate(const char *name)

View File

@ -5,19 +5,10 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef LINUX_SCHED_CLOCK
#define LINUX_SCHED_CLOCK
#ifndef ASM_SCHED_CLOCK
#define ASM_SCHED_CLOCK
#ifdef CONFIG_GENERIC_SCHED_CLOCK
extern void sched_clock_postinit(void);
#else
static inline void sched_clock_postinit(void) { }
#endif
extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
extern void sched_clock_register(u64 (*read)(void), int bits,
unsigned long rate);
extern unsigned long long (*sched_clock_func)(void);
#endif

View File

@ -16,7 +16,7 @@ CFLAGS_REMOVE_return_address.o = -pg
# Object file lists.
obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
process.o ptrace.o return_address.o \
process.o ptrace.o return_address.o sched_clock.o \
setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o

View File

@ -23,11 +23,11 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/export.h>
#include <linux/sched_clock.h>
#include <asm/cputype.h>
#include <asm/localtimer.h>
#include <asm/arch_timer.h>
#include <asm/sched_clock.h>
#include <asm/hardware/gic.h>
#include <asm/system_info.h>

View File

@ -8,73 +8,65 @@
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/syscore_ops.h>
#include <linux/hrtimer.h>
#include <linux/sched_clock.h>
#include <linux/seqlock.h>
#include <linux/bitops.h>
#include <linux/timer.h>
#include <asm/sched_clock.h>
struct clock_data {
ktime_t wrap_kt;
u64 epoch_ns;
u64 epoch_cyc;
seqcount_t seq;
unsigned long rate;
u32 epoch_cyc;
u32 epoch_cyc_copy;
u32 mult;
u32 shift;
bool suspended;
bool needs_suspend;
};
static struct hrtimer sched_clock_timer;
static void sched_clock_poll(unsigned long wrap_ticks);
static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
static struct clock_data cd = {
.mult = NSEC_PER_SEC / HZ,
};
static u64 __read_mostly sched_clock_mask;
static u32 __read_mostly sched_clock_mask = 0xffffffff;
static u64 notrace jiffy_sched_clock_read(void)
static u32 notrace jiffy_sched_clock_read(void)
{
/*
* We don't need to use get_jiffies_64 on 32-bit arches here
* because we register with BITS_PER_LONG
*/
return (u64)(jiffies - INITIAL_JIFFIES);
return (u32)(jiffies - INITIAL_JIFFIES);
}
static u32 __read_mostly (*read_sched_clock_32)(void);
static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
static u64 notrace read_sched_clock_32_wrapper(void)
{
return read_sched_clock_32();
}
static u64 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift)
static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
{
return (cyc * mult) >> shift;
}
static unsigned long long notrace sched_clock_32(void)
static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask)
{
u64 epoch_ns;
u64 epoch_cyc;
u64 cyc;
unsigned long seq;
u32 epoch_cyc;
if (cd.suspended)
return cd.epoch_ns;
/*
* Load the epoch_cyc and epoch_ns atomically. We do this by
* ensuring that we always write epoch_cyc, epoch_ns and
* epoch_cyc_copy in strict order, and read them in strict order.
* If epoch_cyc and epoch_cyc_copy are not equal, then we're in
* the middle of an update, and we should repeat the load.
*/
do {
seq = read_seqcount_begin(&cd.seq);
epoch_cyc = cd.epoch_cyc;
smp_rmb();
epoch_ns = cd.epoch_ns;
} while (read_seqcount_retry(&cd.seq, seq));
smp_rmb();
} while (epoch_cyc != cd.epoch_cyc_copy);
cyc = read_sched_clock();
cyc = (cyc - epoch_cyc) & sched_clock_mask;
@ -87,46 +79,46 @@ static unsigned long long notrace sched_clock_32(void)
static void notrace update_sched_clock(void)
{
unsigned long flags;
u64 cyc;
u32 cyc;
u64 ns;
cyc = read_sched_clock();
ns = cd.epoch_ns +
cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
cd.mult, cd.shift);
/*
* Write epoch_cyc and epoch_ns in a way that the update is
* detectable in cyc_to_fixed_sched_clock().
*/
raw_local_irq_save(flags);
write_seqcount_begin(&cd.seq);
cd.epoch_cyc_copy = cyc;
smp_wmb();
cd.epoch_ns = ns;
smp_wmb();
cd.epoch_cyc = cyc;
write_seqcount_end(&cd.seq);
raw_local_irq_restore(flags);
}
static enum hrtimer_restart sched_clock_poll(struct hrtimer *hrt)
static void sched_clock_poll(unsigned long wrap_ticks)
{
mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
update_sched_clock();
hrtimer_forward_now(hrt, cd.wrap_kt);
return HRTIMER_RESTART;
}
void __init sched_clock_register(u64 (*read)(void), int bits,
unsigned long rate)
void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
{
unsigned long r;
unsigned long r, w;
u64 res, wrap;
char r_unit;
if (cd.rate > rate)
return;
BUG_ON(bits > 32);
WARN_ON(!irqs_disabled());
WARN_ON(read_sched_clock != jiffy_sched_clock_read);
read_sched_clock = read;
sched_clock_mask = CLOCKSOURCE_MASK(bits);
cd.rate = rate;
sched_clock_mask = (1 << bits) - 1;
/* calculate the mult/shift to convert counter ticks to ns. */
clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 3600);
clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0);
r = rate;
if (r >= 4000000) {
@ -139,14 +131,20 @@ void __init sched_clock_register(u64 (*read)(void), int bits,
r_unit = ' ';
/* calculate how many ns until we wrap */
wrap = clocks_calc_max_nsecs(cd.mult, cd.shift, 0, sched_clock_mask);
cd.wrap_kt = ns_to_ktime(wrap - (wrap >> 3));
wrap = cyc_to_ns((1ULL << bits) - 1, cd.mult, cd.shift);
do_div(wrap, NSEC_PER_MSEC);
w = wrap;
/* calculate the ns resolution of this counter */
res = cyc_to_ns(1ULL, cd.mult, cd.shift);
pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lluns\n",
bits, r, r_unit, res, wrap);
pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
bits, r, r_unit, res, w);
/*
* Start the timer to keep sched_clock() properly updated and
* sets the initial epoch.
*/
sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
update_sched_clock();
/*
@ -157,17 +155,10 @@ void __init sched_clock_register(u64 (*read)(void), int bits,
pr_debug("Registered %pF as sched_clock source\n", read);
}
void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
{
read_sched_clock_32 = read;
sched_clock_register(read_sched_clock_32_wrapper, bits, rate);
}
unsigned long long __read_mostly (*sched_clock_func)(void) = sched_clock_32;
unsigned long long notrace sched_clock(void)
{
return sched_clock_func();
u32 cyc = read_sched_clock();
return cyc_to_sched_clock(cyc, sched_clock_mask);
}
void __init sched_clock_postinit(void)
@ -177,23 +168,14 @@ void __init sched_clock_postinit(void)
* make it the final one one.
*/
if (read_sched_clock == jiffy_sched_clock_read)
sched_clock_register(jiffy_sched_clock_read, BITS_PER_LONG, HZ);
setup_sched_clock(jiffy_sched_clock_read, 32, HZ);
update_sched_clock();
/*
* Start the timer to keep sched_clock() properly updated and
* sets the initial epoch.
*/
hrtimer_init(&sched_clock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
sched_clock_timer.function = sched_clock_poll;
hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
sched_clock_poll(sched_clock_timer.data);
}
static int sched_clock_suspend(void)
{
update_sched_clock();
hrtimer_cancel(&sched_clock_timer);
sched_clock_poll(sched_clock_timer.data);
cd.suspended = true;
return 0;
}
@ -201,7 +183,7 @@ static int sched_clock_suspend(void)
static void sched_clock_resume(void)
{
cd.epoch_cyc = read_sched_clock();
hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
cd.epoch_cyc_copy = cd.epoch_cyc;
cd.suspended = false;
}

View File

@ -24,10 +24,10 @@
#include <linux/syscore_ops.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/sched_clock.h>
#include <asm/leds.h>
#include <asm/thread_info.h>
#include <asm/sched_clock.h>
#include <asm/stacktrace.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
@ -147,5 +147,6 @@ void __init time_init(void)
{
system_timer = machine_desc->timer;
system_timer->init();
sched_clock_postinit();
}

View File

@ -18,8 +18,8 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>

View File

@ -33,7 +33,6 @@
#include <linux/io.h>
#include <linux/mtd/physmap.h>
#include <linux/clk.h>
#include <linux/sched_clock.h>
#include <video/vga.h>
#include <mach/hardware.h>
@ -42,6 +41,7 @@
#include <asm/setup.h>
#include <asm/param.h> /* HZ */
#include <asm/mach-types.h>
#include <asm/sched_clock.h>
#include <mach/lm.h>
#include <mach/irqs.h>

View File

@ -29,7 +29,6 @@
#include <linux/io.h>
#include <linux/export.h>
#include <linux/gpio.h>
#include <linux/sched_clock.h>
#include <mach/udc.h>
#include <mach/hardware.h>
@ -38,6 +37,7 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <asm/sched_clock.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>

View File

@ -25,8 +25,8 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
#include <mach/addr-map.h>
#include <mach/regs-timers.h>
#include <mach/regs-apbc.h>

View File

@ -23,11 +23,11 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/percpu.h>
#include <linux/sched_clock.h>
#include <asm/localtimer.h>
#include <asm/mach/time.h>
#include <asm/hardware/gic.h>
#include <asm/sched_clock.h>
#include <asm/smp_plat.h>
#include <mach/msm_iomap.h>
#include <mach/irqs.h>

View File

@ -43,10 +43,10 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/io.h>
#include <linux/sched_clock.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/sched_clock.h>
#include <mach/hardware.h>
#include <asm/mach/irq.h>

View File

@ -36,11 +36,11 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/slab.h>
#include <linux/sched_clock.h>
#include <asm/mach/time.h>
#include <plat/dmtimer.h>
#include <asm/smp_twd.h>
#include <asm/sched_clock.h>
#include "common.h"
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>

View File

@ -16,11 +16,11 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/clockchips.h>
#include <linux/sched_clock.h>
#include <asm/div64.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/sched_clock.h>
#include <mach/regs-ost.h>
#include <mach/irqs.h>

View File

@ -14,9 +14,9 @@
#include <linux/irq.h>
#include <linux/timex.h>
#include <linux/clockchips.h>
#include <linux/sched_clock.h>
#include <asm/mach/time.h>
#include <asm/sched_clock.h>
#include <mach/hardware.h>
#include <mach/irqs.h>

View File

@ -17,11 +17,11 @@
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/sched_clock.h>
#include <mach/hardware.h>
/* Generic stuff */
#include <asm/sched_clock.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>

View File

@ -22,9 +22,9 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/export.h>
#include <linux/sched_clock.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/sched_clock.h>
#include <asm/uaccess.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>

View File

@ -18,7 +18,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clocksource.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
#include <plat/hardware.h>
#include <plat/common.h>

View File

@ -16,7 +16,7 @@
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
/*
* MBus bridge block registers.

View File

@ -20,8 +20,8 @@
*/
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
#include <plat/sched_clock.h>
static void __iomem *ctr;

View File

@ -14,7 +14,8 @@
*/
#include <linux/clockchips.h>
#include <linux/clksrc-dbx500-prcmu.h>
#include <linux/sched_clock.h>
#include <asm/sched_clock.h>
#include <mach/setup.h>
#include <mach/hardware.h>

View File

@ -577,9 +577,6 @@ config LOG_BUF_SHIFT
config HAVE_UNSTABLE_SCHED_CLOCK
bool
config GENERIC_SCHED_CLOCK
bool
menuconfig CGROUPS
boolean "Control Group support"
depends on EVENTFD

View File

@ -69,7 +69,6 @@
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <linux/random.h>
#include <linux/sched_clock.h>
#include <asm/io.h>
#include <asm/bugs.h>
@ -557,7 +556,6 @@ asmlinkage void __init start_kernel(void)
softirq_init();
timekeeping_init();
time_init();
sched_clock_postinit();
profile_init();
call_function_init();
if (!irqs_disabled())

View File

@ -4,6 +4,5 @@ obj-y += timeconv.o posix-clock.o alarmtimer.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o
obj-$(CONFIG_GENERIC_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o
obj-$(CONFIG_TICK_ONESHOT) += tick-sched.o