From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754503AbcIIUBD (ORCPT ); Fri, 9 Sep 2016 16:01:03 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:35648 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751064AbcIIUBB (ORCPT ); Fri, 9 Sep 2016 16:01:01 -0400 From: Nicolai Stange To: Thomas Gleixner Cc: John Stultz , linux-kernel@vger.kernel.org, Nicolai Stange Subject: [RFC v6 00/23] adapt clockevents frequencies to mono clock Date: Fri, 9 Sep 2016 22:00:10 +0200 Message-Id: <20160909200033.32103-1-nicstange@gmail.com> X-Mailer: git-send-email 2.9.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Goal: avoid programming ced devices too early for large deltas, for details, c.f. the description of [21/23]. This v6 fixes two issues I realized after sending v5 out. The latter was meant to incorporate your feedback to v4. Previous v4 of this series can be found here: http://lkml.kernel.org/r/20160822233320.4548-1-nicstange@gmail.com and v5 here: http://lkml.kernel.org/r/20160904010200.17200-1-nicstange@gmail.com Concerns raised to v4 were 1.) There should be a flag available which when enabled, should exclude a ced from getting its ->mult adjusted. 2.) The ns2cyc multiplication in clockevents_program_event() can overflow with the adjusted ->mult. The first item is addressed by the new [13/23] ("clockevents: introduce CLOCK_EVT_FEAT_NO_ADJUST flag"), the second by [14/23] ("clockevents: decouple ->max_delta_ns from ->max_delta_ticks") A note regarding the CLOCK_EVT_FEAT_NO_ADJUST flag: we probably want to set it for the ->mult = 1, ->shift = 0 devices. However, since the frequency adjustments are small (and bounded), they actually translate to noops for those ceds. Thus, setting it there would be a matter of style and optimization and I left this out for now. This series can be divided into logical subseries as follows: [1-6/23] Don't modify ced rate after registrations through mechanisms other than clockevents_update_freq(). [7-12/23] Let all ced devices set their ->*_delta_ticks values and let the clockevent core do the rest. [13/23] Introduce the CLOCK_EVT_FEAT_NO_ADJUST flag [14-20/23] Fiddle around with the bound checking code in order to allow for non-atomic frequency updates from a CPU different than where the ced is programmed. [21-23/23] Actually do the frequency adjustments. Tested on x86_64 and next-20160825. Changes to v5: [21/23] ("clockevents: initial support for mono to raw time conversion") Replace the max_t() in adj = max_t(u64, adj, mult_ce_raw / 8); by min_t(): mult_ce_raw / 8 actually sets an upper bound on the mult adjustments. [23/23] ("timekeeping: inform clockevents about freq adjustments") Move the clockevents_adjust_all_freqs() invocation from timekeeping_apply_adjustment() to timekeeping_freqadjust(). Reason is given in the patch description. Changes to v4: [1-12/23] Unchanged [13/23] ("clockevents: introduce CLOCK_EVT_FEAT_NO_ADJUST flag") New. [14/23] ("clockevents: decouple ->max_delta_ns from ->max_delta_ticks") New. Solves the overflow problem the former [13/22] ("clockevents: check a programmed delta's bounds in terms of cycles") from v4 introduced. (Note that the former [14/22] ("clockevents: clockevents_program_event(): turn clc into unsigned long") from v4 has been purged.) [15/23] ("clockevents: do comparison of delta against minimum in terms of cycles") This is the former [13/22] ("clockevents: check a programmed delta's bounds in terms of cycles"), but only for the ->min_delta_* -- the ->max_delta_* are handled by [14/23] now. [16/23] ("clockevents: clockevents_program_min_delta(): don't set ->next_event") Former [15/22] unchanged. [17/23] ("clockevents: use ->min_delta_ticks_adjusted to program minimum delta") Former [16/22]. Trivially fix compilation error with CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=n. [18/22] ("clockevents: min delta increment: calculate min_delta_ns from ticks") Former [17/22] unchanged. [19/23] ("timer_list: print_tickdevice(): calculate ->min_delta_ns dynamically") Corresponds to former [18/22] ("timer_list: print_tickdevice(): calculate ->*_delta_ns dynamically") from v4, but only for ->min_delta_ns. The changes required for the display of ->max_delta_ns are now being made in [14/23] already. [20/23] ("clockevents: purge ->min_delta_ns") Corresponds to former [19/22] ("clockevents: purge ->min_delta_ns and ->max_delta_ns"), but with ->max_delta_ns being kept. [21/23] ("clockevents: initial support for mono to raw time conversion") Former [20/22] with the following changes: - Don't adjust mult for those ced's that have CLOCK_EVT_FEAT_NO_ADJUST set. - Don't meld __clockevents_update_bounds() into __clockevents_adjust_freq() anymore: the bounds for those devices having CLOCK_EVT_FEAT_NO_ADJUST set must have got their bounds set as well. - In __clockevents_calc_adjust_freq(), make sure that the adjusted mult doesn't exceed the original by more than 12.5%. C.f. [14/23]. - In timekeeping, define timekeeping_get_mono_mult() only for CONFIG_GENERIC_CLOCKEVENTS=y. [22/23] ("clockevents: make setting of ->mult and ->mult_adjusted atomic") Former [12/22], but with the description updated: previously, it said that this patch would introduce a new locking dependency. This is not true. [23/23] ("timekeeping: inform clockevents about freq adjustments") Former [22/22] with the following changes: - Don't adjust mult for those ced's that have CLOCK_EVT_FEAT_NO_ADJUST set. - In clockevents_adjust_all_freqs(), reuse the adjusted cached mult only if the associated ->shift also matches. - Introduce noop clockevents_adjust_all_freqs() in order to fix a compilation error with CONFIG_GENERIC_CLOCKEVENTS=n. Nicolai Stange (23): clocksource: sh_cmt: compute rate before registration again clocksource: sh_tmu: compute rate before registration again clocksource: em_sti: split clock prepare and enable steps clocksource: em_sti: compute rate before registration clocksource: h8300_timer8: don't reset rate in ->set_state_oneshot() clockevents: make clockevents_config() static many clockevent drivers: set ->min_delta_ticks and ->max_delta_ticks arch/s390/kernel/time: set ->min_delta_ticks and ->max_delta_ticks arch/x86/platform/uv/uv_time: set ->min_delta_ticks and ->max_delta_ticks arch/tile/kernel/time: set ->min_delta_ticks and ->max_delta_ticks clockevents: always initialize ->min_delta_ns and ->max_delta_ns many clockevent drivers: don't set ->min_delta_ns and ->max_delta_ns clockevents: introduce CLOCK_EVT_FEAT_NO_ADJUST flag clockevents: decouple ->max_delta_ns from ->max_delta_ticks clockevents: do comparison of delta against minimum in terms of cycles clockevents: clockevents_program_min_delta(): don't set ->next_event clockevents: use ->min_delta_ticks_adjusted to program minimum delta clockevents: min delta increment: calculate min_delta_ns from ticks timer_list: print_tickdevice(): calculate ->min_delta_ns dynamically clockevents: purge ->min_delta_ns clockevents: initial support for mono to raw time conversion clockevents: make setting of ->mult and ->mult_adjusted atomic timekeeping: inform clockevents about freq adjustments arch/avr32/kernel/time.c | 4 +- arch/blackfin/kernel/time-ts.c | 8 +- arch/c6x/platforms/timer64.c | 4 +- arch/hexagon/kernel/time.c | 4 +- arch/m68k/coldfire/pit.c | 6 +- arch/microblaze/kernel/timer.c | 6 +- arch/mips/alchemy/common/time.c | 4 +- arch/mips/jz4740/time.c | 4 +- arch/mips/kernel/cevt-bcm1480.c | 4 +- arch/mips/kernel/cevt-ds1287.c | 4 +- arch/mips/kernel/cevt-gt641xx.c | 4 +- arch/mips/kernel/cevt-sb1250.c | 4 +- arch/mips/kernel/cevt-txx9.c | 5 +- arch/mips/loongson32/common/time.c | 4 +- arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c | 4 +- arch/mips/loongson64/loongson-3/hpet.c | 4 +- arch/mips/ralink/cevt-rt3352.c | 4 +- arch/mips/sgi-ip27/ip27-timer.c | 4 +- arch/mn10300/kernel/cevt-mn10300.c | 4 +- arch/powerpc/kernel/time.c | 6 +- arch/s390/kernel/time.c | 4 +- arch/score/kernel/time.c | 6 +- arch/sparc/kernel/time_32.c | 4 +- arch/sparc/kernel/time_64.c | 6 +- arch/tile/kernel/time.c | 4 +- arch/um/kernel/time.c | 4 +- arch/unicore32/kernel/time.c | 6 +- arch/x86/kernel/apic/apic.c | 12 +- arch/x86/lguest/boot.c | 4 +- arch/x86/platform/uv/uv_time.c | 6 +- arch/x86/xen/time.c | 8 +- drivers/clocksource/dw_apb_timer.c | 5 +- drivers/clocksource/em_sti.c | 49 +++-- drivers/clocksource/h8300_timer8.c | 8 - drivers/clocksource/metag_generic.c | 4 +- drivers/clocksource/numachip.c | 4 +- drivers/clocksource/sh_cmt.c | 50 ++--- drivers/clocksource/sh_tmu.c | 26 +-- drivers/clocksource/timer-atlas7.c | 4 +- include/linux/clockchips.h | 21 +- kernel/time/clockevents.c | 221 ++++++++++++++++++---- kernel/time/tick-broadcast-hrtimer.c | 2 - kernel/time/tick-internal.h | 6 + kernel/time/timekeeping.c | 16 ++ kernel/time/timer_list.c | 9 +- 45 files changed, 376 insertions(+), 204 deletions(-) -- 2.9.3