linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Anna-Maria Behnsen <anna-maria@linutronix.de>
To: Frederic Weisbecker <frederic@kernel.org>
Cc: linux-kernel@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>,
	John Stultz <jstultz@google.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Eric Dumazet <edumazet@google.com>,
	"Rafael J . Wysocki" <rafael.j.wysocki@intel.com>,
	Arjan van de Ven <arjan@infradead.org>,
	"Paul E . McKenney" <paulmck@kernel.org>,
	Rik van Riel <riel@surriel.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Sebastian Siewior <bigeasy@linutronix.de>,
	Giovanni Gherdovich <ggherdovich@suse.cz>,
	Lukasz Luba <lukasz.luba@arm.com>,
	"Gautham R . Shenoy" <gautham.shenoy@amd.com>,
	Srinivas Pandruvada <srinivas.pandruvada@intel.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	Boqun Feng <boqun.feng@gmail.com>
Subject: Re: [PATCH v10 18/20] timers: Implement the hierarchical pull model
Date: Mon, 29 Jan 2024 11:50:39 +0100	[thread overview]
Message-ID: <87sf2gqups.fsf@somnus> (raw)
In-Reply-To: <ZbWJtkAj9z0S9xsH@pavilion.home>

Frederic Weisbecker <frederic@kernel.org> writes:

> Le Mon, Jan 15, 2024 at 03:37:41PM +0100, Anna-Maria Behnsen a écrit :
>> +static bool tmigr_inactive_up(struct tmigr_group *group,
>> +			      struct tmigr_group *child,
>> +			      void *ptr)
>> +{
>> +	union tmigr_state curstate, newstate, childstate;
>> +	struct tmigr_walk *data = ptr;
>> +	bool walk_done;
>> +	u8 childmask;
>> +
>> +	childmask = data->childmask;
>> +	curstate.state = atomic_read(&group->migr_state);
>> +	childstate.state = 0;
>> +
>> +	do {
>
> So I got the confirmation from Boqun (+Cc) and Paul that a failing cmpxchg
> may not order the load of the old value against subsequent loads. And
> that may apply to atomic_try_cmpxchg() as well.
>
> Therefore you not only need to turn group->migr_state read into
> an atomic_read_acquire() but you also need to do this on each iteration
> of this loop. For example you can move the read_acquire right here.

I tried to read and understand more about the memory barriers especially
the acquire/release stuff. So please correct me whenever I'm wrong.

We have to make sure that the child/group state values contain the last
updates and prevent reordering to be able to rely on those values.

So I understand, that we need the atomic_read_acquire() here for the
child state, because we change the group state accordingly and need to
make sure, that it contains the last update of it. The cmpxchg which
writes the child state is (on success) a full memory barrier. And the
atomic_read_acquire() makes sure all preceding "critical sections"
(which ends with the full memory barrier) are visible. Is this right?

To make sure the proper states are used, atomic_read_acquire() is then
also required in:
  - tmigr_check_migrator()
  - tmigr_check_migrator_and_lonely()
  - tmigr_check_lonely()
  - tmigr_new_timer_up() (for childstate and groupstate)
  - tmigr_connect_child_parent()
Right?

Regarding the pairing of acquire: What happens when two
atomic_read_acquire() are executed afterwards without pairing 1:1 with a
release or stronger memory barrier?

Now I want to understand the case for the group state here and also in
active_up path. When reading it without acquire, it is possible, that
not all changes are visible due to reordering,... . But then the worst
outcome would be that the cmpxchg fails and the loop has to be done once
more? Is this right?

I know that memory barriers are not for free and redo the loop is also
not for free. But I don't know which of both is worse. At least in
inactive_up() path, we are not in the critical path. In active_up() it
would be good to take the less expensive option.

I want to understand the atomic_try_cmpxchg_acquire() variant: The Read
is an acquire, so even if the compare/write fails, the value which is
handed back is the one which was update last with a succesful cmpxchg
and then we can rely on this value?

Thanks a lot in advance for the help to understand this topic a little
better!

	Anna-Maria

>
> Thanks.
>
>> +		if (child)
>> +			childstate.state = atomic_read(&child->migr_state);
>> +
>> +		newstate = curstate;
>> +		walk_done = true;
>> +
>> +		/* Reset active bit when the child is no longer active */
>> +		if (!childstate.active)
>> +			newstate.active &= ~childmask;
>> +
>> +		if (newstate.migrator == childmask) {
>> +			/*
>> +			 * Find a new migrator for the group, because the child
>> +			 * group is idle!
>> +			 */
>> +			if (!childstate.active) {
>> +				unsigned long new_migr_bit, active = newstate.active;
>> +
>> +				new_migr_bit = find_first_bit(&active, BIT_CNT);
>> +
>> +				if (new_migr_bit != BIT_CNT) {
>> +					newstate.migrator = BIT(new_migr_bit);
>> +				} else {
>> +					newstate.migrator = TMIGR_NONE;
>> +
>> +					/* Changes need to be propagated */
>> +					walk_done = false;
>> +				}
>> +			}
>> +		}
>> +
>> +		newstate.seq++;
>> +
>> +		WARN_ON_ONCE((newstate.migrator != TMIGR_NONE) && !(newstate.active));
>> +
>> +	} while (!atomic_try_cmpxchg(&group->migr_state, &curstate.state, newstate.state));

  reply	other threads:[~2024-01-29 10:50 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-15 14:37 [PATCH v10 00/20] timers: Move from a push remote at enqueue to a pull at expiry model Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 01/20] timers: Restructure get_next_timer_interrupt() Anna-Maria Behnsen
2024-01-17 15:01   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 02/20] timers: Split out get next timer interrupt Anna-Maria Behnsen
2024-01-17 15:06   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 03/20] timers: Move marking timer bases idle into tick_nohz_stop_tick() Anna-Maria Behnsen
2024-01-17 16:02   ` Frederic Weisbecker
2024-01-22 11:45     ` Anna-Maria Behnsen
2024-01-22 21:49       ` Frederic Weisbecker
2024-02-19  8:52   ` [PATCH v10a] " Anna-Maria Behnsen
2024-02-19 22:37     ` Frederic Weisbecker
2024-02-20 10:48       ` Anna-Maria Behnsen
2024-02-20 11:41         ` Frederic Weisbecker
2024-02-20 12:02           ` Anna-Maria Behnsen
2024-02-20 12:34             ` Frederic Weisbecker
2024-02-20 14:00               ` Anna-Maria Behnsen
2024-02-20 15:10                 ` Frederic Weisbecker
2024-02-20 15:23                   ` Anna-Maria Behnsen
2024-02-20 15:25                     ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 04/20] timers: Optimization for timer_base_try_to_set_idle() Anna-Maria Behnsen
2024-01-17 16:45   ` Frederic Weisbecker
2024-01-22 11:48     ` Anna-Maria Behnsen
2024-01-22 22:22   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 05/20] timers: Introduce add_timer() variants which modify timer flags Anna-Maria Behnsen
2024-01-17 17:01   ` Frederic Weisbecker
2024-01-22 11:50     ` Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 06/20] workqueue: Use global variant for add_timer() Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 07/20] timers: add_timer_on(): Make sure TIMER_PINNED flag is set Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 08/20] timers: Ease code in run_local_timers() Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 09/20] timers: Split next timer interrupt logic Anna-Maria Behnsen
2024-01-23 14:28   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 10/20] timers: Keep the pinned timers separate from the others Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 11/20] timers: Retrieve next expiry of pinned/non-pinned timers separately Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 12/20] timers: Split out "get next timer interrupt" functionality Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 13/20] timers: Add get next timer interrupt functionality for remote CPUs Anna-Maria Behnsen
2024-02-19 16:04   ` Frederic Weisbecker
2024-02-19 16:57     ` Anna-Maria Behnsen
2024-01-15 14:37 ` [PATCH v10 14/20] timers: Restructure internal locking Anna-Maria Behnsen
2024-01-24 13:56   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 15/20] timers: Check if timers base is handled already Anna-Maria Behnsen
2024-01-24 14:22   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 16/20] tick/sched: Split out jiffies update helper function Anna-Maria Behnsen
2024-01-24 14:42   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 17/20] timers: Introduce function to check timer base is_idle flag Anna-Maria Behnsen
2024-01-24 14:52   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 18/20] timers: Implement the hierarchical pull model Anna-Maria Behnsen
2024-01-25 14:30   ` Frederic Weisbecker
2024-01-28 15:58     ` Anna-Maria Behnsen
2024-01-30 15:29       ` Frederic Weisbecker
2024-01-30 16:45         ` Anna-Maria Behnsen
2024-01-26 12:53   ` Frederic Weisbecker
2024-01-27 22:54   ` Frederic Weisbecker
2024-01-29 10:50     ` Anna-Maria Behnsen [this message]
2024-01-29 22:21       ` Frederic Weisbecker
2024-01-30 13:32         ` Anna-Maria Behnsen
2024-01-29 13:50     ` Paul E. McKenney
2024-01-29  1:04   ` Frederic Weisbecker
2024-01-30 17:56     ` Anna-Maria Behnsen
2024-01-30 21:13       ` Frederic Weisbecker
2024-01-31 11:19         ` Anna-Maria Behnsen
2024-01-30 15:37   ` Frederic Weisbecker
2024-02-01 14:59     ` Anna-Maria Behnsen
2024-02-01 15:05   ` Frederic Weisbecker
2024-02-01 16:15     ` Anna-Maria Behnsen
2024-02-01 17:43       ` Frederic Weisbecker
2024-02-01 20:52         ` Anna-Maria Behnsen
2024-02-05 13:29           ` Anna-Maria Behnsen
2024-02-05 20:30             ` Frederic Weisbecker
2024-02-06 10:06               ` Anna-Maria Behnsen
2024-02-06 10:29                 ` Frederic Weisbecker
2024-02-01 16:33   ` Frederic Weisbecker
2024-02-05 15:59     ` Anna-Maria Behnsen
2024-02-05 20:28       ` Frederic Weisbecker
2024-02-04 22:02   ` Frederic Weisbecker
2024-02-06 11:03     ` Anna-Maria Behnsen
2024-02-06 11:11       ` Frederic Weisbecker
2024-02-04 22:32   ` Frederic Weisbecker
2024-02-06 11:36     ` Anna-Maria Behnsen
2024-02-06 13:21       ` Frederic Weisbecker
2024-02-06 14:13         ` Anna-Maria Behnsen
2024-02-06 14:21           ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 19/20] timer_migration: Add tracepoints Anna-Maria Behnsen
2024-02-01 16:47   ` Frederic Weisbecker
2024-01-15 14:37 ` [PATCH v10 20/20] timers: Always queue timers on the local CPU Anna-Maria Behnsen
2024-02-01 17:36   ` Frederic Weisbecker
2024-02-01 20:58     ` Anna-Maria Behnsen
2024-02-02 11:57       ` Frederic Weisbecker
2024-01-30 22:07 ` [PATCH v10 00/20] timers: Move from a push remote at enqueue to a pull at expiry model Christian Loehle
2024-02-01 15:03   ` Anna-Maria Behnsen

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=87sf2gqups.fsf@somnus \
    --to=anna-maria@linutronix.de \
    --cc=arjan@infradead.org \
    --cc=bigeasy@linutronix.de \
    --cc=boqun.feng@gmail.com \
    --cc=edumazet@google.com \
    --cc=frederic@kernel.org \
    --cc=gautham.shenoy@amd.com \
    --cc=ggherdovich@suse.cz \
    --cc=jstultz@google.com \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lukasz.luba@arm.com \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=riel@surriel.com \
    --cc=rostedt@goodmis.org \
    --cc=srinivas.pandruvada@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).