1. 21 Oct, 2021 2 commits
  2. 19 Oct, 2021 1 commit
    • Daniel Lezcano's avatar
      Merge branch 'timers/drivers/armv8.6_arch_timer' into timers/drivers/next · 32cf6d0a
      Daniel Lezcano authored
      The branch is a stable branch shared with ARM maintainers for the
      first 13th patches of the series:
      
      It is based on v5.14-rc3.
      
      As stated by the changelog:
      
      " [... ] enabling ARMv8.6 support for timer subsystem, and was prompted by a
      discussion with Oliver around the fact that an ARMv8.6 implementation
      must have a 1GHz counter, which leads to a number of things to break
      in the timer code:
      
      - the counter rollover can come pretty quickly as we only advertise a
        56bit counter,
      - the maximum timer delta can be remarkably small, as we use the
        countdown interface which is limited to 32bit...
      
      Thankfully, there is a way out: we can compute the minimal width of
      the counter based on the guarantees that the architecture gives us,
      and we can use the 64bit comparator interface instead of the countdown
      to program the timer.
      
      Finally, we start making use of the ARMv8.6 ECV features by switching
      accesses to the counters to a self-synchronising register, removing
      the need for an ISB. Hopefully, implementations will *not* just stick
      an invisible ISB there...
      
      A side effect of the switch to CVAL is that XGene-1 breaks. I have
      added a workaround to keep it alive.
      
      I have added Oliver's original patch[0] to the series and tweaked a
      couple of things. Blame me if I broke anything.
      
      The whole things has been tested on Juno (sysreg + MMIO timers),
      XGene-1 (broken sysreg timers), FVP (FEAT_ECV, CNT*CTSS_EL0).
      "
      
      Link: https://lore.kernel.org/r/20211017124225.3018098-1-maz@kernel.orgSigned-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
      32cf6d0a
  3. 18 Oct, 2021 2 commits
  4. 17 Oct, 2021 11 commits
  5. 16 Oct, 2021 1 commit
    • Randy Dunlap's avatar
      clocksource/drivers/arc_timer: Eliminate redefined macro error · 58100c34
      Randy Dunlap authored
      In drivers/clocksource/, 3 drivers use "TIMER_CTRL_IE" with 3 different
      values.  Two of them (mps2-timer.c and timer-sp804.c/timer-sp.h) are
      localized and left unmodifed.
      
      One of them uses a shared header file (<soc/arc/timers.h>), which is
      what is causing the "redefined" warnings, so change the macro name in
      that driver only. Also change the TIMER_CTRL_NH macro name.
      Both macro names are prefixed with "ARC_" to reduce the likelihood
      of future name collisions.
      
      In file included from ../drivers/clocksource/timer-sp804.c:24:
      ../drivers/clocksource/timer-sp.h:25: error: "TIMER_CTRL_IE" redefined [-Werror]
         25 | #define TIMER_CTRL_IE           (1 << 5)        /*   VR */
      ../include/soc/arc/timers.h:20: note: this is the location of the previous definition
         20 | #define TIMER_CTRL_IE           (1 << 0) /* Interrupt when Count reaches limit */
      
      Fixes: b26c2e38 ("ARC: breakout timer include code into separate header")
      Signed-off-by: default avatarRandy Dunlap <rdunlap@infradead.org>
      Cc: Vineet Gupta <vgupta@kernel.org>
      Cc: linux-snps-arc@lists.infradead.org
      Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Shahab Vahedi <Shahab.Vahedi@synopsys.com>
      Acked-by: default avatarVineet Gupta <vgupta@kernel.org>
      Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
      Link: https://lore.kernel.org/r/20210924020825.20317-1-rdunlap@infradead.org
      58100c34
  6. 28 Aug, 2021 1 commit
  7. 26 Aug, 2021 1 commit
  8. 21 Aug, 2021 1 commit
  9. 14 Aug, 2021 3 commits
  10. 13 Aug, 2021 4 commits
  11. 12 Aug, 2021 2 commits
  12. 10 Aug, 2021 11 commits
    • Thomas Gleixner's avatar
      hrtimer: Avoid more SMP function calls in clock_was_set() · 1e7f7fbc
      Thomas Gleixner authored
      By unconditionally updating the offsets there are more indicators
      whether the SMP function calls on clock_was_set() can be avoided:
      
        - When the offset update already happened on the remote CPU then the
          remote update attempt will yield the same seqeuence number and no
          IPI is required.
      
        - When the remote CPU is currently handling hrtimer_interrupt(). In
          that case the remote CPU will reevaluate the timer bases before
          reprogramming anyway, so nothing to do.
      
        - After updating it can be checked whether the first expiring timer in
          the affected clock bases moves before the first expiring (softirq)
          timer of the CPU. If that's not the case then sending the IPI is not
          required.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.887322464@linutronix.de
      1e7f7fbc
    • Marcelo Tosatti's avatar
      hrtimer: Avoid unnecessary SMP function calls in clock_was_set() · 81d741d3
      Marcelo Tosatti authored
      Setting of clocks triggers an unconditional SMP function call on all online
      CPUs to reprogram the clock event device.
      
      However, only some clocks have their offsets updated and therefore
      potentially require a reprogram. That's CLOCK_REALTIME and CLOCK_TAI and in
      the case of resume (delayed sleep time injection) also CLOCK_BOOTTIME.
      
      Instead of sending an IPI unconditionally, check each per CPU hrtimer base
      whether it has active timers in the affected clock bases which are
      indicated by the caller in the @bases argument of clock_was_set().
      
      If that's not the case, skip the IPI and update the offsets remotely which
      ensures that any subsequently armed timers on the affected clocks are
      evaluated with the correct offsets.
      
      [ tglx: Adopted to the new bases argument, removed the softirq_active
        	check, added comment, fixed up stale comment ]
      Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.787536542@linutronix.de
      81d741d3
    • Thomas Gleixner's avatar
      hrtimer: Add bases argument to clock_was_set() · 17a1b882
      Thomas Gleixner authored
      clock_was_set() unconditionaly invokes retrigger_next_event() on all online
      CPUs. This was necessary because that mechanism was also used for resume
      from suspend to idle which is not longer the case.
      
      The bases arguments allows the callers of clock_was_set() to hand in a mask
      which tells clock_was_set() which of the hrtimer clock bases are affected
      by the clock setting. This mask will be used in the next step to check
      whether a CPU base has timers queued on a clock base affected by the event
      and avoid the SMP function call if there are none.
      
      Add a @bases argument, provide defines for the active bases masking and
      fixup all callsites.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.691083465@linutronix.de
      17a1b882
    • Thomas Gleixner's avatar
      time/timekeeping: Avoid invoking clock_was_set() twice · 1b267793
      Thomas Gleixner authored
      do_adjtimex() might end up scheduling a delayed clock_was_set() via
      timekeeping_advance() and then invoke clock_was_set() directly which is
      pointless.
      
      Make timekeeping_advance() return whether an invocation of clock_was_set()
      is required and handle it at the call sites which allows do_adjtimex() to
      issue a single direct call if required.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.580966888@linutronix.de
      1b267793
    • Thomas Gleixner's avatar
      timekeeping: Distangle resume and clock-was-set events · a761a67f
      Thomas Gleixner authored
      Resuming timekeeping is a clock-was-set event and uses the clock-was-set
      notification mechanism. This is in the way of making the clock-was-set
      update for hrtimers selective so unnecessary IPIs are avoided when a CPU
      base does not have timers queued which are affected by the clock setting.
      
      Distangle it by invoking hrtimer_resume() on each unfreezing CPU and invoke
      the new timerfd_resume() function from timekeeping_resume() which is the
      only place where this is needed.
      
      Rename hrtimer_resume() to hrtimer_resume_local() to reflect the change.
      
      With this the clock_was_set*() functions are not longer required to IPI all
      CPUs unconditionally and can get some smarts to avoid them.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.488853478@linutronix.de
      a761a67f
    • Thomas Gleixner's avatar
      timerfd: Provide timerfd_resume() · 66f7b0c8
      Thomas Gleixner authored
      Resuming timekeeping is a clock-was-set event and uses the clock-was-set
      notification mechanism. This is in the way of making the clock-was-set
      update for hrtimers selective so unnecessary IPIs are avoided when a CPU
      base does not have timers queued which are affected by the clock setting.
      
      Provide a seperate timerfd_resume() interface so the resume logic and the
      clock-was-set mechanism can be distangled in the core code.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.395287410@linutronix.de
      66f7b0c8
    • Thomas Gleixner's avatar
      hrtimer: Force clock_was_set() handling for the HIGHRES=n, NOHZ=y case · e71a4153
      Thomas Gleixner authored
      When CONFIG_HIGH_RES_TIMERS is disabled, but NOHZ is enabled then
      clock_was_set() is not doing anything. With HIGHRES=n the kernel relies on
      the periodic tick to update the clock offsets, but when NOHZ is enabled and
      active then CPUs which are in a deep idle sleep do not have a periodic tick
      which means the expiry of timers affected by clock_was_set() can be
      arbitrarily delayed up to the point where the CPUs are brought out of idle
      again.
      
      Make the clock_was_set() logic unconditionaly available so that idle CPUs
      are kicked out of idle to handle the update.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.288697903@linutronix.de
      e71a4153
    • Thomas Gleixner's avatar
      hrtimer: Ensure timerfd notification for HIGHRES=n · 8c3b5e6e
      Thomas Gleixner authored
      If high resolution timers are disabled the timerfd notification about a
      clock was set event is not happening for all cases which use
      clock_was_set_delayed() because that's a NOP for HIGHRES=n, which is wrong.
      
      Make clock_was_set_delayed() unconditially available to fix that.
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.196661266@linutronix.de
      8c3b5e6e
    • Peter Zijlstra's avatar
      hrtimer: Consolidate reprogramming code · b14bca97
      Peter Zijlstra authored
      This code is mostly duplicated. The redudant store in the force reprogram
      case does no harm and the in hrtimer interrupt condition cannot be true for
      the force reprogram invocations.
      Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135158.054424875@linutronix.de
      b14bca97
    • Thomas Gleixner's avatar
      hrtimer: Avoid double reprogramming in __hrtimer_start_range_ns() · 627ef5ae
      Thomas Gleixner authored
      If __hrtimer_start_range_ns() is invoked with an already armed hrtimer then
      the timer has to be canceled first and then added back. If the timer is the
      first expiring timer then on removal the clockevent device is reprogrammed
      to the next expiring timer to avoid that the pending expiry fires needlessly.
      
      If the new expiry time ends up to be the first expiry again then the clock
      event device has to reprogrammed again.
      
      Avoid this by checking whether the timer is the first to expire and in that
      case, keep the timer on the current CPU and delay the reprogramming up to
      the point where the timer has been enqueued again.
      Reported-by: default avatarLorenzo Colitti <lorenzo@google.com>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Link: https://lore.kernel.org/r/20210713135157.873137732@linutronix.de
      
      627ef5ae
    • Frederic Weisbecker's avatar
      posix-cpu-timers: Recalc next expiration when timer_settime() ends up not queueing · ee375328
      Frederic Weisbecker authored
      There are several scenarios that can result in posix_cpu_timer_set()
      not queueing the timer but still leaving the threadgroup cputime counter
      running or keeping the tick dependency around for a random amount of time.
      
      1) If timer_settime() is called with a 0 expiration on a timer that is
         already disabled, the process wide cputime counter will be started
         and won't ever get a chance to be stopped by stop_process_timer()
         since no timer is actually armed to be processed.
      
         The following snippet is enough to trigger the issue.
      
      	void trigger_process_counter(void)
      	{
      		timer_t id;
      		struct itimerspec val = { };
      
      		timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
      		timer_settime(id, TIMER_ABSTIME, &val, NULL);
      		timer_delete(id);
      	}
      
      2) If timer_settime() is called with a 0 expiration on a timer that is
         already armed, the timer is dequeued but not really disarmed. So the
         process wide cputime counter and the tick dependency may still remain
         a while around.
      
         The following code snippet keeps this overhead around for one week after
         the timer deletion:
      
      	void trigger_process_counter(void)
      	{
      		timer_t id;
      		struct itimerspec val = { };
      
      		val.it_value.tv_sec = 604800;
      		timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
      		timer_settime(id, 0, &val, NULL);
      		timer_delete(id);
      	}
      
      3) If the timer was initially deactivated, this call to timer_settime()
         with an early expiration may have started the process wide cputime
         counter even though the timer hasn't been queued and armed because it
         has fired early and inline within posix_cpu_timer_set() itself. As a
         result the process wide cputime counter may never stop until a new
         timer is ever armed in the future.
      
         The following code snippet can reproduce this:
      
      	void trigger_process_counter(void)
      	{
      		timer_t id;
      		struct itimerspec val = { };
      
      		signal(SIGALRM, SIG_IGN);
      		timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
      		val.it_value.tv_nsec = 1;
      		timer_settime(id, TIMER_ABSTIME, &val, NULL);
      	}
      
      4) If the timer was initially armed with a former expiration value
         before this call to timer_settime() and the current call sets an
         early deadline that has already expired, the timer fires inline
         within posix_cpu_timer_set(). In this case it must have been dequeued
         before firing inline with its new expiration value, yet it hasn't
         been disarmed in this case. So the process wide cputime counter and
         the tick dependency may still be around for a while even after the
         timer fired.
      
         The following code snippet can reproduce this:
      
      	void trigger_process_counter(void)
      	{
      		timer_t id;
      		struct itimerspec val = { };
      
      		signal(SIGALRM, SIG_IGN);
      		timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &id);
      		val.it_value.tv_sec = 100;
      		timer_settime(id, TIMER_ABSTIME, &val, NULL);
      		val.it_value.tv_sec = 0;
      		val.it_value.tv_nsec = 1;
      		timer_settime(id, TIMER_ABSTIME, &val, NULL);
      	}
      
      Fix all these issues with triggering the related base next expiration
      recalculation on the next tick. This also implies to re-evaluate the need
      to keep around the process wide cputime counter and the tick dependency, in
      a similar fashion to disarm_timer().
      Suggested-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Signed-off-by: default avatarFrederic Weisbecker <frederic@kernel.org>
      Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
      Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
      Link: https://lore.kernel.org/r/20210726125513.271824-7-frederic@kernel.org
      ee375328