diff options
author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-03-11 10:55:49 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-03-11 10:55:49 +0100 |
commit | c897df0e2dbc81bcc09c11425658d69830825364 (patch) | |
tree | 04c268e4951f2b75acb6873307673e45d05a635e /kernel/time/sched_clock.c | |
parent | [media] omap3isp: Fix kerneldoc for _module_sync_is_stopping and isp_isr() (diff) | |
parent | Linux 3.14-rc5 (diff) | |
download | linux-c897df0e2dbc81bcc09c11425658d69830825364.tar.xz linux-c897df0e2dbc81bcc09c11425658d69830825364.zip |
Merge tag 'v3.14-rc5' into patchwork
Linux 3.14-rc5
* tag 'v3.14-rc5': (1117 commits)
Linux 3.14-rc5
drm/vmwgfx: avoid null pointer dereference at failure paths
drm/vmwgfx: Make sure backing mobs are cleared when allocated. Update driver date.
drm/vmwgfx: Remove some unused surface formats
MAINTAINERS: add maintainer entry for Armada DRM driver
arm64: Fix !CONFIG_SMP kernel build
arm64: mm: Add double logical invert to pte accessors
dm cache: fix truncation bug when mapping I/O to >2TB fast device
perf tools: Fix strict alias issue for find_first_bit
powerpc/powernv: Fix indirect XSCOM unmangling
powerpc/powernv: Fix opal_xscom_{read,write} prototype
powerpc/powernv: Refactor PHB diag-data dump
powerpc/powernv: Dump PHB diag-data immediately
powerpc: Increase stack redzone for 64-bit userspace to 512 bytes
powerpc/ftrace: bugfix for test_24bit_addr
powerpc/crashdump : Fix page frame number check in copy_oldmem_page
powerpc/le: Ensure that the 'stop-self' RTAS token is handled correctly
kvm, vmx: Really fix lazy FPU on nested guest
perf tools: fix BFD detection on opensuse
drm/radeon: enable speaker allocation setup on dce3.2
...
Diffstat (limited to 'kernel/time/sched_clock.c')
-rw-r--r-- | kernel/time/sched_clock.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c index 0abb36464281..4d23dc4d8139 100644 --- a/kernel/time/sched_clock.c +++ b/kernel/time/sched_clock.c @@ -116,20 +116,42 @@ static enum hrtimer_restart sched_clock_poll(struct hrtimer *hrt) void __init sched_clock_register(u64 (*read)(void), int bits, unsigned long rate) { + u64 res, wrap, new_mask, new_epoch, cyc, ns; + u32 new_mult, new_shift; + ktime_t new_wrap_kt; unsigned long r; - u64 res, wrap; char r_unit; if (cd.rate > rate) return; WARN_ON(!irqs_disabled()); - read_sched_clock = read; - sched_clock_mask = CLOCKSOURCE_MASK(bits); - cd.rate = rate; /* 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(&new_mult, &new_shift, rate, NSEC_PER_SEC, 3600); + + new_mask = CLOCKSOURCE_MASK(bits); + + /* calculate how many ns until we wrap */ + wrap = clocks_calc_max_nsecs(new_mult, new_shift, 0, new_mask); + new_wrap_kt = ns_to_ktime(wrap - (wrap >> 3)); + + /* update epoch for new counter and update epoch_ns from old counter*/ + new_epoch = read(); + cyc = read_sched_clock(); + ns = cd.epoch_ns + cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask, + cd.mult, cd.shift); + + raw_write_seqcount_begin(&cd.seq); + read_sched_clock = read; + sched_clock_mask = new_mask; + cd.rate = rate; + cd.wrap_kt = new_wrap_kt; + cd.mult = new_mult; + cd.shift = new_shift; + cd.epoch_cyc = new_epoch; + cd.epoch_ns = ns; + raw_write_seqcount_end(&cd.seq); r = rate; if (r >= 4000000) { @@ -141,22 +163,12 @@ void __init sched_clock_register(u64 (*read)(void), int bits, } else 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)); - /* calculate the ns resolution of this counter */ - res = cyc_to_ns(1ULL, cd.mult, cd.shift); + res = cyc_to_ns(1ULL, new_mult, new_shift); + pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lluns\n", bits, r, r_unit, res, wrap); - update_sched_clock(); - - /* - * Ensure that sched_clock() starts off at 0ns - */ - cd.epoch_ns = 0; - /* Enable IRQ time accounting if we have a fast enough sched_clock */ if (irqtime > 0 || (irqtime == -1 && rate >= 1000000)) enable_sched_clock_irqtime(); |