All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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.