From: Thomas Gleixner <tglx@linutronix.de>
To: Kent Overstreet <kent.overstreet@linux.dev>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
Jens Axboe <axboe@kernel.dk>,
brauner@kernel.org, viro@zeniv.linux.org.uk,
Bernd Schubert <bernd.schubert@fastmail.fm>,
linux-mm@kvack.org, Josef Bacik <josef@toxicpanda.com>
Subject: Re: [PATCH 3/5] fs: sys_ringbuffer
Date: Mon, 24 Jun 2024 01:16:15 +0200 [thread overview]
Message-ID: <87a5jb9rnk.ffs@tglx> (raw)
In-Reply-To: <odohwdryb2yhzi5kzvlwv65kazbhzqyps6fzr2wukksdewukmr@gono7fdsth5d>
Kent!
On Sun, Jun 23 2024 at 18:21, Kent Overstreet wrote:
> On Mon, Jun 24, 2024 at 12:13:36AM +0200, Thomas Gleixner wrote:
>> > + /*
>> > + * We use u32s because this type is shared between the kernel and
>> > + * userspace - ulong/size_t won't work here, we might be 32bit userland
>> > + * and 64 bit kernel, and u64 would be preferable (reduced probability
>> > + * of ABA) but not all architectures can atomically read/write to a u64;
>> > + * we need to avoid torn reads/writes.
>>
>> union rbmagic {
>> u64 __val64;
>> struct {
>> // TOOTIRED: Add big/little endian voodoo
>> u32 __val32;
>> u32 __unused;
>> };
>> };
>>
>> Plus a bunch of accessors which depend on BITS_PER_LONG, no?
>
> Not sure I follow?
>
> I know biendian machines exist, but I've never heard of both big and
> little endian being used at the same time. Nor why we'd care about
> BITS_PER_LONG? This just uses fixed size integer types.
Read your comment above. Ideally you want to use u64, right?
The problem is that you can't do this unconditionally because of 32-bit
systems which do not support 64-bit atomics.
So a binary which is compiled for 32-bit might unconditionally want the
32-bit accessors. Ditto for 32-bit kernels.
The 64bit kernel where it runs on wants to utilize u64, right?
That's fortunately a unidirectional problem as 64-bit user space cannot
run on a 32-bit kernel ever.
struct ringbuffer_ctrl {
union rbmagic head;
...
};
#ifdef __BITS_PER_LONG == 64
static __always_inline u64 read_head(struct ringbuffer_ctrl *rb)
{
return rb->head.__val64;
}
static __always_inline void write_head(struct ringbuffer_ctrl *rb, u64 val)
{
rb->head.__val64 = val;
}
#else
static __always_inline u64 read_head(struct ringbuffer_ctrl *rb)
{
return rb->head.__val32;
}
static __always_inline void write_head(struct ringbuffer_ctrl *rb, u64 val)
{
rb->head.__val32 = (u32)val;
}
#endif
A 64-bit kernel uses u64 while a 32-bit kernel uses u32. Same for user
space.
The ABA concern for 32-bit does not go away, but for 64-bit userspace
you get what you want, no?
Now why do you have to care about endianess?
union rbmagic {
u64 __val64;
struct {
u32 __val32;
u32 __unused;
};
};
works only correctly for LE. But it does not work for BE because BE
obviously requires the u32 members to be in reverse order:
union rbmagic {
u64 __val64;
struct {
u32 __unused;
u32 __val32;
};
};
That's a compile time decision. You can't run a BE binary on a LE kernel
or the other way around.
So they have to agree on the endianess, but BE has the reverse byte
order. That's why you need to have another #ifdef there.
Thanks,
tglx
next prev parent reply other threads:[~2024-06-23 23:16 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-03 0:32 [PATCH 0/5] sys_ringbuffer Kent Overstreet
2024-06-03 0:32 ` [PATCH 1/5] darray: lift from bcachefs Kent Overstreet
2024-06-03 5:00 ` kernel test robot
2024-06-03 0:32 ` [PATCH 2/5] darray: Fix darray_for_each_reverse() when darray is empty Kent Overstreet
2024-06-03 0:33 ` [PATCH 3/5] fs: sys_ringbuffer Kent Overstreet
2024-06-03 4:16 ` kernel test robot
2024-06-03 4:38 ` kernel test robot
2024-06-23 22:13 ` Thomas Gleixner
2024-06-23 22:21 ` Kent Overstreet
2024-06-23 23:16 ` Thomas Gleixner [this message]
2024-06-24 0:27 ` Kent Overstreet
2024-06-03 0:33 ` [PATCH 4/5] ringbuffer: Test device Kent Overstreet
2024-06-03 0:33 ` [PATCH 5/5] ringbuffer: Userspace test helper Kent Overstreet
2024-06-07 1:49 ` [PATCH 0/5] sys_ringbuffer Stefan Hajnoczi
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=87a5jb9rnk.ffs@tglx \
--to=tglx@linutronix.de \
--cc=axboe@kernel.dk \
--cc=bernd.schubert@fastmail.fm \
--cc=brauner@kernel.org \
--cc=josef@toxicpanda.com \
--cc=kent.overstreet@linux.dev \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=viro@zeniv.linux.org.uk \
/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.