From: Heiko Carstens <hca@linux.ibm.com>
To: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Juergen Christ <jchrist@linux.ibm.com>,
linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Subject: Re: [PATCH v5 1/7] s390/percpu: Infrastructure for more efficient this_cpu operations
Date: Mon, 1 Jun 2026 15:27:50 +0200 [thread overview]
Message-ID: <20260601132750.9109A3b-hca@linux.ibm.com> (raw)
In-Reply-To: <403de21c-957e-41ca-8c03-0bd110c49ec3-agordeev@linux.ibm.com>
On Mon, Jun 01, 2026 at 09:10:47AM +0200, Alexander Gordeev wrote:
> On Tue, May 26, 2026 at 07:56:56AM +0200, Heiko Carstens wrote:
> > Get rid of the conditional branch with the following code sequence:
> >
> > 11a8e6: c0 30 00 d0 c5 0d larl %r3,1b33300
>
> Annotating with similar comments as above would help:
>
> ... <- address of percpu var
> ... <- add percpu offset
>
> > 11a8ec: b9 04 00 43 lgr %r4,%r3
> > 11a8f0: eb 00 43 c0 00 52 mviy 960,4
> > 11a8f6: e3 40 03 b8 00 08 ag %r4,952
> > 11a8fc: eb 52 40 00 00 e8 laag %r5,%r2,0(%r4)
> > 11a902: eb 00 03 c0 00 52 mviy 960,0
> > 11a908: b9 08 00 25 agr %r2,%r5
> > 11a90c 07 fe br %r14
Sure.
> > +static __always_inline void percpu_entry(struct pt_regs *regs)
> > +{
> > + struct lowcore *lc = get_lowcore();
> > +
> > + if (user_mode(regs))
> > + return;
> > + regs->cpu = lc->cpu_nr;
> > + regs->percpu_register = lc->percpu_register;
> > + lc->percpu_register = 0;
>
> This assignment is required when the task is migrated to a new CPU, so
> the lowcore would not be corrupted with the stale percpu_register value.
> Otherwise, it is restored in percpu_exit() if there was no migration.
> Right?
This, but it is also required to have a "clean" starting point for the
new context (exception, irq, nmi), since the new context does not run
in a percpu code section - if that context would be interrupted then
the next context might see that the previous context was running in a
percpu code section, while it was not. Therefore lc->percpu_register
must be saved and set to 0 before the new context may use percpu ops
and/or fault.
> > + if ((insn & 0xff0f) != 0xe300)
>
> Any reason mask/not to check the register number as well?
Just to save code. If there would be a mismatch with the percpu
register, something serious would be wrong..
But that cannot happen(tm) :)
> > + /* Check if process has been migrated to a different CPU. */
> > + if (regs->cpu == lc->cpu_nr)
> > + return;
> > + /* Fixup percpu base register */
> > + regs->gprs[reg] -= __per_cpu_offset[regs->cpu];
> > + regs->gprs[reg] += lc->percpu_offset;
>
> Such one reads bit better:
>
> regs->gprs[reg] -= __per_cpu_offset[regs->cpu];
> regs->gprs[reg] += __per_cpu_offset[reg];
That reads better, but it is wrong. 'reg' is not the index of the
current cpu into __per_cpu_offset[].
It could be changed to
regs->gprs[reg] += __per_cpu_offset[lc->cpu_nr];
but then again that's exactly lc->percpu_offset. I don't see a reason
to create worse code here.
> > + * Inline assemblies making use of this typically have a code sequence like:
> > + *
> > + * MVIY_PERCPU(...) <- start of percpu code section
> > + * AG_ALT(...) <- add percpu offset; must be the second instruction
> > + * atomic_op <- atomic op
> \t here, but should be spaces?
I can't follow? We have tabs in comments all over the place in s390 code.
> Probably it worth noting that no extra instructions between atomic_op
> and MVIY_ALT may exist (e.g. in the future), especially ones that use
> the percpu_register.
That's not true. There may be additional instructions, they may just
not use the same register that is used for the percpu variable.
But that was true before this patch as well, even though it might not
have been "obvious".
> > unsigned long flags;
> > unsigned long last_break;
> > + unsigned int cpu;
> > + unsigned char percpu_register;
>
> May be name it as this_cpu and this_cpu_reg(ister)?
Here I disagree. *If* a task would be migrated then such naming would
be very confusing: regs->this_cpu would contain the cpu number of the
_previous_ cpu where the task was running on, but not the number of
the current cpu.
So you would end up with checks like:
if (regs->this_cpu != this_cpu)
to figure out if a task was migrated. This doesn't look right to me.
next prev parent reply other threads:[~2026-06-01 13:27 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-26 5:56 [PATCH v5 0/7] s390: Improve this_cpu operations Heiko Carstens
2026-05-26 5:56 ` [PATCH v5 1/7] s390/percpu: Infrastructure for more efficient " Heiko Carstens
2026-06-01 7:10 ` Alexander Gordeev
2026-06-01 13:27 ` Heiko Carstens [this message]
2026-06-01 14:49 ` Alexander Gordeev
2026-06-01 15:08 ` Heiko Carstens
2026-06-02 13:32 ` David Laight
2026-06-02 13:54 ` Heiko Carstens
2026-06-02 14:36 ` David Laight
2026-06-02 10:08 ` Alexander Gordeev
2026-05-26 5:56 ` [PATCH v5 2/7] s390/percpu: Add missing do { } while (0) constructs Heiko Carstens
2026-06-01 7:14 ` Alexander Gordeev
2026-05-26 5:56 ` [PATCH v5 3/7] s390/percpu: Use new percpu code section for arch_this_cpu_add() Heiko Carstens
2026-06-02 11:33 ` Alexander Gordeev
2026-05-26 5:56 ` [PATCH v5 4/7] s390/percpu: Use new percpu code section for arch_this_cpu_add_return() Heiko Carstens
2026-06-02 11:34 ` Alexander Gordeev
2026-05-26 5:57 ` [PATCH v5 5/7] s390/percpu: Use new percpu code section for arch_this_cpu_[and|or]() Heiko Carstens
2026-06-02 11:35 ` Alexander Gordeev
2026-05-26 5:57 ` [PATCH v5 6/7] s390/percpu: Provide arch_this_cpu_read() implementation Heiko Carstens
2026-06-02 11:40 ` Alexander Gordeev
2026-05-26 5:57 ` [PATCH v5 7/7] s390/percpu: Provide arch_this_cpu_write() implementation Heiko Carstens
2026-06-02 11:40 ` Alexander Gordeev
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=20260601132750.9109A3b-hca@linux.ibm.com \
--to=hca@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=jchrist@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=svens@linux.ibm.com \
/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