linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Gray <bgray@linux.ibm.com>
To: Christophe Leroy <christophe.leroy@csgroup.eu>,
	"linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>
Cc: "ajd@linux.ibm.com" <ajd@linux.ibm.com>,
	"peterz@infradead.org" <peterz@infradead.org>,
	"npiggin@gmail.com" <npiggin@gmail.com>,
	"ardb@kernel.org" <ardb@kernel.org>,
	"jbaron@akamai.com" <jbaron@akamai.com>,
	"rostedt@goodmis.org" <rostedt@goodmis.org>,
	"jpoimboe@kernel.org" <jpoimboe@kernel.org>
Subject: Re: [PATCH v2 1/6] powerpc/code-patching: Implement generic text patching function
Date: Tue, 27 Sep 2022 12:57:26 +1000	[thread overview]
Message-ID: <ae7b4dfa7887ad1a4b3156dfc5c012bf73a1d8d6.camel@linux.ibm.com> (raw)
In-Reply-To: <cf9a6312-7a23-1000-8c28-4dbc1553db24@csgroup.eu>

On Mon, 2022-09-26 at 14:33 +0000, Christophe Leroy wrote:
> > +#define patch_memory(addr, val) \
> > +({ \
> > +       BUILD_BUG_ON(!__native_word(val)); \
> > +       __patch_memory(addr, (unsigned long) val, sizeof(val)); \
> > +})
> 
> Can you do a static __always_inline function instead of a macro here
> ?

I didn't before because it doesn't allow using the type as a parameter.
I considered these forms

  patch_memory(addr, val, 8);
  patch_memory(addr, val, void*);
  patch_memory(addr, val);  // size taken from val type

And thought the third was the nicest to use. Though coming back to
this, I hadn't considered

  patch_memory(addr, val, sizeof(void*))

which would still allow a type to decide the size, and not be a macro.
I've got an example implementation further down that also addresses the
size check issue.

> > +static int __always_inline ___patch_memory(void *patch_addr,
> > +                                          unsigned long data,
> > +                                          void *prog_addr,
> > +                                          size_t size)
> 
> Is it really needed in the .c file ? I would expect GCC to take the 
> right decision by itself.

I thought it'd be better to always inline it given it's only used
generically in do_patch_memory and __do_patch_memory, which both get
inlined into __patch_memory. But it does end up generating two copies
due to the different contexts it's called in, so probably not worth it.
Removed for v3.

(raw_patch_instruction gets an optimised inline of ___patch_memory
either way)

> A BUILD_BUG() would be better here I think.

BUILD_BUG() as the default case always triggers though, I assume
because the constant used for size is too far away. How about

  static __always_inline int patch_memory(void *addr, 
                                          unsigned long val, 
                                          size_t size) 
  {
      int __patch_memory(void *dest, unsigned long src, size_t size);

      BUILD_BUG_ON_MSG(!(size == sizeof(char)  ||
                         size == sizeof(short) ||
                         size == sizeof(int)   ||
                         size == sizeof(long)),
                       "Unsupported size for patch_memory");
      return __patch_memory(addr, val, size);
  }

Declaring the __patch_memory function inside of patch_memory enforces
that you can't accidentally call __patch_memory without going through
this or the *patch_instruction entry points (which hardcode the size).

> > +       }
> > 
> > -               __put_kernel_nofault(patch_addr, &val, u32,
> > failed);
> > -       } else {
> > -               u64 val = ppc_inst_as_ulong(instr);
> > +       dcbst(patch_addr);
> > +       dcbst(patch_addr + size - 1); /* Last byte of data may
> > cross a cacheline */
> 
> Or the second byte of data may cross a cacheline ...

It might, but unless we are assuming data cachelines smaller than the
native word size it will either be in the first or last byte's
cacheline. Whereas the last byte might be in it's own cacheline.

As justification the comment's misleading though, how about reducing it
to "data may cross a cacheline" and leaving the reason for flushing the
last byte implicit?

> > -static int __do_patch_instruction(u32 *addr, ppc_inst_t instr)
> > +static int __always_inline __do_patch_memory(void *dest, unsigned
> > long src, size_t size)
> >   {
> 
> Whaou, do we really want all this to be __always_inline ? Did you
> check 
> the text size increase ?

These ones are redundant because GCC will already inline them, they
were just part of experimenting inlining ___patch_memory. Will remove
for v3. 

The text size doesn't increase though because the call hierarchy is
just a linear chain of
__patch_memory -> do_patch_memory -> __do_patch_memory

The entry point __patch_memory is not inlined.

  reply	other threads:[~2022-09-27  3:16 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-26  6:43 [PATCH v2 0/6] Out-of-line static calls for powerpc64 ELF V2 Benjamin Gray
2022-09-26  6:43 ` [PATCH v2 1/6] powerpc/code-patching: Implement generic text patching function Benjamin Gray
2022-09-26  8:56   ` kernel test robot
2022-09-26 13:28   ` kernel test robot
2022-09-26 14:33   ` Christophe Leroy
2022-09-27  2:57     ` Benjamin Gray [this message]
2022-09-27  5:54       ` Christophe Leroy
2022-09-27  6:40   ` Christophe Leroy
2022-09-28  1:30     ` Benjamin Gray
2022-09-28 10:52       ` Christophe Leroy
2022-09-27  7:30   ` Christophe Leroy
2022-09-26  6:43 ` [PATCH v2 2/6] powerpc/module: Handle caller-saved TOC in module linker Benjamin Gray
2022-09-26  6:43 ` [PATCH v2 3/6] powerpc/module: Optimise nearby branches in ELF V2 ABI stub Benjamin Gray
2022-09-26 14:49   ` Christophe Leroy
2022-09-27  3:12     ` Benjamin Gray
2022-09-26  6:43 ` [PATCH v2 4/6] static_call: Move static call selftest to static_call_selftest.c Benjamin Gray
2022-09-26 14:50   ` Christophe Leroy
2022-09-26  6:43 ` [PATCH v2 5/6] powerpc/64: Add support for out-of-line static calls Benjamin Gray
2022-09-26 13:16   ` Christophe Leroy
2022-09-27  5:18     ` Benjamin Gray
2022-09-27  6:07       ` Christophe Leroy
2022-09-26 14:54   ` Christophe Leroy
2022-09-27  3:21     ` Benjamin Gray
2022-09-27  6:01       ` Christophe Leroy
2022-09-26  6:43 ` [PATCH v2 6/6] powerpc/64: Add tests " Benjamin Gray
2022-09-26 14:55   ` Christophe Leroy
2022-09-27  3:31     ` Benjamin Gray
2022-09-27  6:05       ` Christophe Leroy
2022-09-26 14:19 ` [PATCH v2 0/6] Out-of-line static calls for powerpc64 ELF V2 Christophe Leroy

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=ae7b4dfa7887ad1a4b3156dfc5c012bf73a1d8d6.camel@linux.ibm.com \
    --to=bgray@linux.ibm.com \
    --cc=ajd@linux.ibm.com \
    --cc=ardb@kernel.org \
    --cc=christophe.leroy@csgroup.eu \
    --cc=jbaron@akamai.com \
    --cc=jpoimboe@kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=npiggin@gmail.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    /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).