All of lore.kernel.org
 help / color / mirror / Atom feed
From: oleksii.kurochko@gmail.com
To: Jan Beulich <jbeulich@suse.com>
Cc: Alistair Francis <alistair.francis@wdc.com>,
	Bob Eshleman <bobbyeshleman@gmail.com>,
	Connor Davis <connojdavis@gmail.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Julien Grall <julien@xen.org>,
	Stefano Stabellini <sstabellini@kernel.org>,
	xen-devel@lists.xenproject.org
Subject: Re: [PATCH v6 3/9] xen/riscv: allow write_atomic() to work with non-scalar types
Date: Thu, 12 Sep 2024 13:15:52 +0200	[thread overview]
Message-ID: <b5eb9f937814d9d37db315cea9c53ec1faeb4be7.camel@gmail.com> (raw)
In-Reply-To: <59d3ef0f-dc1d-4d6e-9e1e-4fb3550113a8@suse.com>

On Wed, 2024-09-11 at 13:49 +0200, Jan Beulich wrote:
> On 11.09.2024 13:34, oleksii.kurochko@gmail.com wrote:
> > On Tue, 2024-09-10 at 18:05 +0200, Jan Beulich wrote:
> > > On 10.09.2024 17:28, oleksii.kurochko@gmail.com wrote:
> > > > On Tue, 2024-09-10 at 11:53 +0200, Jan Beulich wrote:
> > > > > On 02.09.2024 19:01, Oleksii Kurochko wrote:
> > > > > > @@ -72,7 +72,7 @@ static always_inline void
> > > > > > _write_atomic(volatile
> > > > > > void *p,
> > > > > >  #define write_atomic(p, x)                              \
> > > > > >  ({                                                      \
> > > > > >      typeof(*(p)) x_ = (x);                              \
> > > > > > -    _write_atomic(p, x_, sizeof(*(p)));                 \
> > > > > > +    _write_atomic(p, &x_, sizeof(*(p)));                \
> > > > > >  })
> > > > > >  
> > > > > >  static always_inline void _add_sized(volatile void *p,
> > > > > > @@ -82,27 +82,23 @@ static always_inline void
> > > > > > _add_sized(volatile
> > > > > > void *p,
> > > > > >      {
> > > > > >      case 1:
> > > > > >      {
> > > > > > -        volatile uint8_t *ptr = p;
> > > > > > -        write_atomic(ptr, read_atomic(ptr) + x);
> > > > > > +        writeb_cpu(readb_cpu(p) + x, p);
> > > > > >          break;
> > > > > >      }
> > > > > >      case 2:
> > > > > >      {
> > > > > > -        volatile uint16_t *ptr = p;
> > > > > > -        write_atomic(ptr, read_atomic(ptr) + x);
> > > > > > +        writew_cpu(readw_cpu(p) + x, p);
> > > > > >          break;
> > > > > >      }
> > > > > >      case 4:
> > > > > >      {
> > > > > > -        volatile uint32_t *ptr = p;
> > > > > > -        write_atomic(ptr, read_atomic(ptr) + x);
> > > > > > +        writel_cpu(readl_cpu(p) + x, p);
> > > > > >          break;
> > > > > >      }
> > > > > >  #ifndef CONFIG_RISCV_32
> > > > > >      case 8:
> > > > > >      {
> > > > > > -        volatile uint64_t *ptr = p;
> > > > > > -        write_atomic(ptr, read_atomic(ptr) + x);
> > > > > > +        writeq_cpu(readw_cpu(p) + x, p);
> > > > > >          break;
> > > > > >      }
> > > > > >  #endif
> > > > > 
> > > > > I'm afraid I don't understand this part, or more specifically
> > > > > the
> > > > > respective
> > > > > part of the description. It is the first parameter of
> > > > > write_atomic()
> > > > > which is
> > > > > volatile qualified. And it is the first argument that's
> > > > > volatile
> > > > > qualified
> > > > > here. Isn't the problem entirely unrelated to volatile-ness,
> > > > > and
> > > > > instead a
> > > > > result of the other parameter changing from scalar to pointer
> > > > > type,
> > > > > which
> > > > > doesn't fit the addition expressions you pass in?
> > > > if _add_sized() is defined as it was before:
> > > >    static always_inline void _add_sized(volatile void *p,
> > > >                                         unsigned long x,
> > > > unsigned
> > > > int
> > > >    size)
> > > >    {
> > > >        switch ( size )
> > > >        {
> > > >        case 1:
> > > >        {
> > > >            volatile uint8_t *ptr = p;
> > > >            write_atomic(ptr, read_atomic(ptr) + x);
> > > >            break;
> > > >        }
> > > >    ...
> > > > Then write_atomic(ptr, read_atomic(ptr) + x) will be be changed
> > > > to:
> > > >    volatile uint8_t x_ = (x);
> > > >    
> > > > And that will cause a compiler error:
> > > >    ./arch/riscv/include/asm/atomic.h:75:22: error: passing
> > > > argument
> > > > 2
> > > >    of '_write_atomic' discards 'volatile' qualifier from
> > > > pointer
> > > > target
> > > >    type [-Werror=discarded-qualifiers]
> > > >       75 |     _write_atomic(p, &x_, sizeof(*(p)));
> > > > Because it can't cast 'volatile uint8_t *' to 'void *':
> > > >    expected 'void *' but argument is of type 'volatile uint8_t
> > > > *'
> > > > {aka
> > > >    'volatile unsigned char *'}
> > > 
> > > Oh, I think I see now. What we'd like write_atomic() to derive is
> > > the
> > > bare
> > > (unqualified) type of *ptr, yet iirc only recent compilers have a
> > > way
> > > to
> > > obtain that.
> > I assume that you are speaking about typeof_unqual which requires
> > C23
> > (?).
> 
> What C version it requires doesn't matter much for our purposes. The
> question is as of which gcc / clang version (if any) this is
> supported
> as an extension.
> 
> > __auto_type seems to me can also drop volatile quilifier but in the
> > docs I don't see that it should (or not) discard qualifier. Could
> > it be
> > an option:
> >    #define write_atomic(p, x)                              \
> >    ({                                                      \
> >        __auto_type x_ = (x);                              \
> >        _write_atomic(p, &x_, sizeof(*(p)));                 \
> >    })
> 
> For our purposes __auto_type doesn't provide advantages over
> typeof().
> Plus, more importantly, the use above is wrong, just like typeof(x)
> would also be wrong. It needs to be p that the type is derived from.
> Otherwise consider what happens when ptr is unsigned long * or
> unsigned short * and you write
> 
>     write_atomic(ptr, 0);
> 
> > And another option could be just drop volatile by casting:
> >    #define write_atomic(p, x)                              \
> >    ...
> >        _write_atomic(p, (const void *)&x_,
> > sizeof(*(p)));                 
> 
> See what I said earlier about casts: You shall not cast away
> qualifiers. Besides doing so being bad practice, you'll notice the
> latest when RISC-V code also becomes subject to Misra compliance.

Then probably the best one option will be to use union:
   #define write_atomic(p, x)                                         
   \
   ({                                                                 
   \
       union { typeof(*(p)) val; char c[sizeof(*(p))]; } x_ = { .val =
   (x) };  \
       _write_atomic(p, x_.c, sizeof(*(p)));                          
   \
   })
   
~ Oleksii

  reply	other threads:[~2024-09-12 11:16 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-02 17:01 [PATCH v6 0/9] RISCV device tree mapping Oleksii Kurochko
2024-09-02 17:01 ` [PATCH v6 1/9] xen/riscv: prevent recursion when ASSERT(), BUG*(), or panic() are called Oleksii Kurochko
2024-09-03 14:19   ` [PATCH] RISCV/shutdown: Implement machine_{halt,restart}() Andrew Cooper
2024-09-03 14:23     ` Andrew Cooper
2024-09-03 14:27       ` Jan Beulich
2024-09-03 14:26     ` Jan Beulich
2024-09-03 14:27       ` Andrew Cooper
2024-09-04 10:22     ` oleksii.kurochko
2024-09-10  9:42   ` [PATCH v6 1/9] xen/riscv: prevent recursion when ASSERT(), BUG*(), or panic() are called Jan Beulich
2024-09-10 13:55     ` oleksii.kurochko
2024-09-02 17:01 ` [PATCH v6 2/9] xen/riscv: use {read,write}{b,w,l,q}_cpu() to define {read,write}_atomic() Oleksii Kurochko
2024-09-03 14:21   ` Andrew Cooper
2024-09-04 10:27     ` oleksii.kurochko
2024-09-04 10:31       ` Andrew Cooper
2024-09-05 15:45         ` oleksii.kurochko
2024-09-02 17:01 ` [PATCH v6 3/9] xen/riscv: allow write_atomic() to work with non-scalar types Oleksii Kurochko
2024-09-10  9:53   ` Jan Beulich
2024-09-10 15:28     ` oleksii.kurochko
2024-09-10 16:05       ` Jan Beulich
2024-09-11 11:34         ` oleksii.kurochko
2024-09-11 11:49           ` Jan Beulich
2024-09-12 11:15             ` oleksii.kurochko [this message]
2024-09-12 11:41               ` oleksii.kurochko
2024-09-02 17:01 ` [PATCH v6 4/9] xen/riscv: set up fixmap mappings Oleksii Kurochko
2024-09-10 10:01   ` Jan Beulich
2024-09-10 15:55     ` oleksii.kurochko
2024-09-10 16:07       ` Jan Beulich
2024-09-02 17:01 ` [PATCH v6 5/9] xen/riscv: introduce asm/pmap.h header Oleksii Kurochko
2024-09-02 17:01 ` [PATCH v6 6/9] xen/riscv: introduce functionality to work with CPU info Oleksii Kurochko
2024-09-10 10:33   ` Jan Beulich
2024-09-11 12:05     ` oleksii.kurochko
2024-09-11 12:14       ` Jan Beulich
2024-09-12  9:27         ` oleksii.kurochko
2024-09-12  9:58           ` Jan Beulich
2024-09-12 16:02     ` oleksii.kurochko
2024-09-13 12:51       ` Jan Beulich
2024-09-02 17:01 ` [PATCH v6 7/9] xen/riscv: introduce and initialize SBI RFENCE extension Oleksii Kurochko
2024-09-10 11:32   ` Jan Beulich
2024-09-02 17:01 ` [PATCH v6 8/9] xen/riscv: page table handling Oleksii Kurochko
2024-09-10 12:19   ` Jan Beulich
2024-09-11 15:09     ` oleksii.kurochko
2024-09-02 17:01 ` [PATCH v6 9/9] xen/riscv: introduce early_fdt_map() Oleksii Kurochko

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=b5eb9f937814d9d37db315cea9c53ec1faeb4be7.camel@gmail.com \
    --to=oleksii.kurochko@gmail.com \
    --cc=alistair.francis@wdc.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=bobbyeshleman@gmail.com \
    --cc=connojdavis@gmail.com \
    --cc=jbeulich@suse.com \
    --cc=julien@xen.org \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.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 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.