All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To: John Stultz <jstultz@google.com>
Cc: Frederic Weisbecker <frederic@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	Miroslav Lichvar <mlichvar@redhat.com>,
	Richard Cochran <richardcochran@gmail.com>,
	Christopher S Hall <christopher.s.hall@intel.com>
Subject: Re: [PATCH v2 06/25] timekeeping: Reorder struct timekeeper
Date: Mon, 14 Oct 2024 11:30:22 +0200	[thread overview]
Message-ID: <87msj7f2vl.fsf@somnus> (raw)
In-Reply-To: <CANDhNCpPhS5nebGH_bA3G06Dmt6eFXAw9GyBEYmNZe2Z1WhS_Q@mail.gmail.com>

John Stultz <jstultz@google.com> writes:

> On Wed, Oct 9, 2024 at 1:29 AM Anna-Maria Behnsen
> <anna-maria@linutronix.de> wrote:
>>
>> From: Thomas Gleixner <tglx@linutronix.de>
>>
>> From: Thomas Gleixner <tglx@linutronix.de>
>>
>> struct timekeeper is ordered suboptimal vs. cachelines. The layout,
>> including the preceding seqcount (see struct tk_core in timekeeper.c) is:
>>
>>  cacheline 0:   seqcount, tkr_mono
>>  cacheline 1:   tkr_raw, xtime_sec
>>  cacheline 2:   ktime_sec ... tai_offset, internal variables
>>  cacheline 3:   next_leap_ktime, raw_sec, internal variables
>>  cacheline 4:   internal variables
>>
>> So any access to via ktime_get*() except for access to CLOCK_MONOTONIC_RAW
>> will use either cachelines 0 + 1 or cachelines 0 + 2. Access to
>> CLOCK_MONOTONIC_RAW uses cachelines 0 + 1 + 3.
>>
>> Reorder the members so that the result is more efficient:
>>
>>  cacheline 0:   seqcount, tkr_mono
>>  cacheline 1:   xtime_sec, ktime_sec ... tai_offset
>>  cacheline 2:   tkr_raw, raw_sec
>>  cacheline 3:   internal variables
>>  cacheline 4:   internal variables
>>
>> That means ktime_get*() will access cacheline 0 + 1 and CLOCK_MONOTONIC_RAW
>> access will use cachelines 0 + 2.
>>
>> Update kernel-doc and fix formatting issues while at it. Also fix a typo
>> in struct tk_read_base kernel-doc.
>>
>> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>> Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
>
> Acked-by: John Stultz <jstultz@google.com>
>
>> ---
>>  include/linux/timekeeper_internal.h | 102 +++++++++++++++++++++---------------
>>  1 file changed, 61 insertions(+), 41 deletions(-)
>>
>> diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
>> index 902c20ef495a..430e40549136 100644
>> --- a/include/linux/timekeeper_internal.h
>> +++ b/include/linux/timekeeper_internal.h
>> @@ -26,7 +26,7 @@
>>   * occupies a single 64byte cache line.
>>   *
>>   * The struct is separate from struct timekeeper as it is also used
>> - * for a fast NMI safe accessors.
>> + * for the fast NMI safe accessors.
>>   *
>>   * @base_real is for the fast NMI safe accessor to allow reading clock
>>   * realtime from any context.
>> @@ -44,33 +44,41 @@ struct tk_read_base {
>>
>>  /**
>>   * struct timekeeper - Structure holding internal timekeeping values.
>> - * @tkr_mono:          The readout base structure for CLOCK_MONOTONIC
>> - * @tkr_raw:           The readout base structure for CLOCK_MONOTONIC_RAW
>> - * @xtime_sec:         Current CLOCK_REALTIME time in seconds
>> - * @ktime_sec:         Current CLOCK_MONOTONIC time in seconds
>> - * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
>> - * @offs_real:         Offset clock monotonic -> clock realtime
>> - * @offs_boot:         Offset clock monotonic -> clock boottime
>> - * @offs_tai:          Offset clock monotonic -> clock tai
>> - * @tai_offset:                The current UTC to TAI offset in seconds
>> - * @clock_was_set_seq: The sequence number of clock was set events
>> - * @cs_was_changed_seq:        The sequence number of clocksource change events
>> - * @next_leap_ktime:   CLOCK_MONOTONIC time value of a pending leap-second
>> - * @raw_sec:           CLOCK_MONOTONIC_RAW  time in seconds
>> - * @monotonic_to_boot: CLOCK_MONOTONIC to CLOCK_BOOTTIME offset
>> - * @cycle_interval:    Number of clock cycles in one NTP interval
>> - * @xtime_interval:    Number of clock shifted nano seconds in one NTP
>> - *                     interval.
>> - * @xtime_remainder:   Shifted nano seconds left over when rounding
>> - *                     @cycle_interval
>> - * @raw_interval:      Shifted raw nano seconds accumulated per NTP interval.
>> - * @ntp_error:         Difference between accumulated time and NTP time in ntp
>> - *                     shifted nano seconds.
>> - * @ntp_error_shift:   Shift conversion between clock shifted nano seconds and
>> - *                     ntp shifted nano seconds.
>> - * @last_warning:      Warning ratelimiter (DEBUG_TIMEKEEPING)
>> - * @underflow_seen:    Underflow warning flag (DEBUG_TIMEKEEPING)
>> - * @overflow_seen:     Overflow warning flag (DEBUG_TIMEKEEPING)
>> + * @tkr_mono:                  The readout base structure for CLOCK_MONOTONIC
>> + * @xtime_sec:                 Current CLOCK_REALTIME time in seconds
>> + * @ktime_sec:                 Current CLOCK_MONOTONIC time in seconds
>> + * @wall_to_monotonic:         CLOCK_REALTIME to CLOCK_MONOTONIC offset
>> + * @offs_real:                 Offset clock monotonic -> clock realtime
>> + * @offs_boot:                 Offset clock monotonic -> clock boottime
>> + * @offs_tai:                  Offset clock monotonic -> clock tai
>> + * @tai_offset:                        The current UTC to TAI offset in seconds
>> + * @tkr_raw:                   The readout base structure for CLOCK_MONOTONIC_RAW
>> + * @raw_sec:                   CLOCK_MONOTONIC_RAW  time in seconds
>> + * @clock_was_set_seq:         The sequence number of clock was set events
>> + * @cs_was_changed_seq:                The sequence number of clocksource change events
>> + * @monotonic_to_boot:         CLOCK_MONOTONIC to CLOCK_BOOTTIME offset
>> + * @cycle_interval:            Number of clock cycles in one NTP interval
>> + * @xtime_interval:            Number of clock shifted nano seconds in one NTP
>> + *                             interval.
>> + * @xtime_remainder:           Shifted nano seconds left over when rounding
>> + *                             @cycle_interval
>> + * @raw_interval:              Shifted raw nano seconds accumulated per NTP interval.
>> + * @next_leap_ktime:           CLOCK_MONOTONIC time value of a pending leap-second
>> + * @ntp_tick:                  The ntp_tick_length() value currently being
>> + *                             used. This cached copy ensures we consistently
>> + *                             apply the tick length for an entire tick, as
>> + *                             ntp_tick_length may change mid-tick, and we don't
>> + *                             want to apply that new value to the tick in
>> + *                             progress.
>> + * @ntp_error:                 Difference between accumulated time and NTP time in ntp
>> + *                             shifted nano seconds.
>> + * @ntp_error_shift:           Shift conversion between clock shifted nano seconds and
>> + *                             ntp shifted nano seconds.
>> + * @ntp_err_mult:              Multiplication factor for scaled math conversion
>> + * @skip_second_overflow:      Flag used to avoid updating NTP twice with same second
>> + * @last_warning:              Warning ratelimiter (DEBUG_TIMEKEEPING)
>> + * @underflow_seen:            Underflow warning flag (DEBUG_TIMEKEEPING)
>> + * @overflow_seen:             Overflow warning flag (DEBUG_TIMEKEEPING)
>>   *
>>   * Note: For timespec(64) based interfaces wall_to_monotonic is what
>>   * we need to add to xtime (or xtime corrected for sub jiffy times)
>> @@ -88,10 +96,25 @@ struct tk_read_base {
>>   *
>>   * @monotonic_to_boottime is a timespec64 representation of @offs_boot to
>>   * accelerate the VDSO update for CLOCK_BOOTTIME.
>> + *
>> + * The cacheline ordering of the structure is optimized for in kernel usage
>> + * of the ktime_get() and ktime_get_ts64() family of time accessors. Struct
>> + * timekeeper is prepended in the core timekeeeping code with a sequence
>> + * count, which results in the following cacheline layout:
>> + *
>> + * 0:  seqcount, tkr_mono
>> + * 1:  xtime_sec ... tai_offset
>> + * 2:  tkr_raw, raw_sec
>> + * 3,4: Internal variables
>> + *
>> + * Cacheline 0,1 contain the data which is used for accessing
>> + * CLOCK_MONOTONIC/REALTIME/BOOTTIME/TAI, while cacheline 2 contains the
>> + * data for accessing CLOCK_MONOTONIC_RAW.  Cacheline 3,4 are internal
>> + * variables which are only accessed during timekeeper updates once per
>> + * tick.
>
> Would it make sense to add divider comments or something in the struct
> to make this more visible? I fret in the context of a patch, a + line
> adding a new structure element that breaks the ordered alignment might
> not be obvious.

This is an argument! I'll add simple comments with /* Cachline X: */

Thanks,

	Anna-Maria

  reply	other threads:[~2024-10-14  9:30 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-09  8:28 [PATCH v2 00/25] timekeeping: Rework to prepare support of indenpendent PTP clocks Anna-Maria Behnsen
2024-10-09  8:28 ` [PATCH v2 01/25] timekeeping: Read NTP tick length only once Anna-Maria Behnsen
2024-10-09 17:18   ` John Stultz
2024-10-09  8:28 ` [PATCH v2 02/25] timekeeping: Don't stop time readers across hard_pps() update Anna-Maria Behnsen
2024-10-09  8:28 ` [PATCH v2 03/25] timekeeping: Avoid duplicate leap state update Anna-Maria Behnsen
2024-10-09 17:31   ` John Stultz
2024-10-09  8:28 ` [PATCH v2 04/25] timekeeping: Abort clocksource change in case of failure Anna-Maria Behnsen
2024-10-09 19:58   ` John Stultz
2024-10-09  8:28 ` [PATCH v2 05/25] timekeeping: Simplify code in timekeeping_advance() Anna-Maria Behnsen
2024-10-09 21:00   ` John Stultz
2024-10-09  8:28 ` [PATCH v2 06/25] timekeeping: Reorder struct timekeeper Anna-Maria Behnsen
2024-10-11  3:22   ` John Stultz
2024-10-14  9:30     ` Anna-Maria Behnsen [this message]
2024-10-15 10:08   ` [PATCH v2a] " Anna-Maria Behnsen
2024-10-25 14:53     ` [tip: timers/core] " tip-bot2 for Thomas Gleixner
2024-10-25 18:01     ` tip-bot2 for Thomas Gleixner
2024-10-09  8:29 ` [PATCH v2 07/25] timekeeping: Move shadow_timekeeper into tk_core Anna-Maria Behnsen
2024-10-24 21:11   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 08/25] timekeeping: Encapsulate locking/unlocking of timekeeper_lock Anna-Maria Behnsen
2024-10-24 21:19   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 09/25] timekeeping: Move timekeeper_lock into tk_core Anna-Maria Behnsen
2024-10-24 21:20   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 10/25] timekeeping: Define a struct type for tk_core to make it reusable Anna-Maria Behnsen
2024-10-24 21:21   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 11/25] timekeeping: Introduce tkd_basic_setup() to make lock and seqcount init reusable Anna-Maria Behnsen
2024-10-24 21:25   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 12/25] timekeeping: Add struct tk_data as argument to timekeeping_update() Anna-Maria Behnsen
2024-10-24 21:29   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 13/25] timekeeping: Split out timekeeper update of timekeeping_advanced() Anna-Maria Behnsen
2024-10-24 21:43   ` John Stultz
2024-10-24 21:53   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 14/25] timekeeping: Introduce combined timekeeping action flag Anna-Maria Behnsen
2024-10-24 22:12   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 15/25] timekeeping: Provide timekeeping_restore_shadow() Anna-Maria Behnsen
2024-10-24 21:45   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 16/25] timekeeping: Rework do_settimeofday64() to use shadow_timekeeper Anna-Maria Behnsen
2024-10-24 21:54   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 17/25] timekeeping: Rework timekeeping_inject_offset() " Anna-Maria Behnsen
2024-10-24 21:57   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 18/25] timekeeping: Rework change_clocksource() " Anna-Maria Behnsen
2024-10-24 21:58   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 19/25] timekeeping: Rework timekeeping_init() " Anna-Maria Behnsen
2024-10-24 22:16   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 20/25] timekeeping: Rework timekeeping_inject_sleeptime64() " Anna-Maria Behnsen
2024-10-24 22:16   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 21/25] timekeeping: Rework timekeeping_resume() " Anna-Maria Behnsen
2024-10-24 22:18   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 22/25] timekeeping: Rework timekeeping_suspend() " Anna-Maria Behnsen
2024-10-24 22:21   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 23/25] timekeeping: Rework do_adjtimex() " Anna-Maria Behnsen
2024-10-24 22:26   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 24/25] timekeeping: Remove TK_MIRROR timekeeping_update() action Anna-Maria Behnsen
2024-10-24 22:29   ` John Stultz
2024-10-09  8:29 ` [PATCH v2 25/25] timekeeping: Merge timekeeping_update_staged() and timekeeping_update() Anna-Maria Behnsen
2024-10-24 22:41   ` John Stultz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87msj7f2vl.fsf@somnus \
    --to=anna-maria@linutronix.de \
    --cc=christopher.s.hall@intel.com \
    --cc=frederic@kernel.org \
    --cc=jstultz@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mlichvar@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=richardcochran@gmail.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.