From: David Laight <david.laight.linux@gmail.com>
To: Joel Granados <joel.granados@kernel.org>
Cc: Wen Yang <wen.yang@linux.dev>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 00/39] sysctl: replace overloaded extra pointers with typed bounds and context
Date: Sat, 7 Nov 2026 17:05:07 +0000 [thread overview]
Message-ID: <20261107170507.0d66cc2e@pumpkin> (raw)
In-Reply-To: <au85ISJ2qUsB7y-6@hobbes>
On Sat, 7 Nov 2026 16:27:39 +0100
Joel Granados <joel.granados@kernel.org> wrote:
> On Mon, Nov 02, 2026 at 11:40:40PM +0800, Wen Yang wrote:
> >
> >
> > On 10/29/26 18:58, David Laight wrote:
> > > On Thu, 29 Oct 2026 00:34:39 +0800
> > > wen.yang@linux.dev wrote:
> > >
> > > > From: Wen Yang <wen.yang@linux.dev>
> > > >
> > > > struct ctl_table describes an entry with data, maxlen and, until this
> > > > series, two untyped misc pointers in extra1 and extra2. Those two pointers
> > > > have accumulated at least seven unrelated jobs: a fixed bound, a bound read
> > > > through a pointer on every call, an object or namespace pointer, a small
> > > > integer cookie encoded into the pointer, a lock signal, NULL standing for
> > > > "no bound", and a value the core itself casts to unsigned int while
> > > > validating a u8 range. Nothing in the entry says which job applies, so
> > > > readers infer it from the handler, and the core gets it wrong where it
> > > > treats extra1 as an unsigned int.
> <--- snip --->
> > > > (~574 new min/max initializers) instead of pointing at constants. The
> > > > sysctl ABI is unchanged; the parport spintime minimum is corrected as
> > > > described above.
> > > >
> > > > The cost is 8 bytes per ctl_table entry on 64-bit (56 -> 64) and 4 bytes on
> > > > 32-bit, because priv is appended; the range read path gains no indirection
> > > > and the migrated entries no longer dereference a bound pointer.
> > >
> > > Can you remove the little-used 'priv' parameter by making the extra
> > > information just follow the table entry (nested structure) and have
> > > the relevant functions use container_of() to get the outer structure
> > > and extra values?
> > >
> >
> >
> > Hi David, Hi Joel,
> >
> > I reworked the context side of the series so that priv is gone entirely;
> > and the final tree has no per-entry context pointer.
> > A small helper recovers the enclosing object, but it needs the slot
> > index from the caller:
> >
> > #define sysctl_table_container(entry, type, member, index) ({ \
> > static_assert(__same_type(*(entry), \
> > typeof_member(type, member[0])), \
> > "pointer type mismatch"); \
> > (type *)((void *)(entry) - offsetof(type, member) - \
> > (size_t)(index) * sizeof(*(entry))); \
> > })
> >
> > The reason plain container_of() is not enough is that the core keeps the
> > table as a contiguous array. For
> >
> > struct addrconf_sysctl_table {
> > struct addrconf_sysctl_ctx context;
> > struct ctl_table table[];
> > };
> >
> > the handler receives an interior entry, and
> >
> > container_of(ctl, struct addrconf_sysctl_table, table)
> > == (char *)outer + index * sizeof(struct ctl_table)
> >
> > for ctl == &outer->table[index]. It only returns the outer object for
> > index 0. Passing the index explicitly keeps the original registered
> > entry usable:
> >
> > static int addrconf_sysctl_forward(const struct ctl_table *ctl, ...)
> > {
> > struct addrconf_sysctl_table *t =
> > sysctl_table_container(ctl, struct addrconf_sysctl_table,
> > table, ADDRCONF_SYSCTL_FORWARDING);
> > const struct addrconf_sysctl_ctx *ctx = &t->context;
> > ...
> > }
> >
> > Shared handlers get one wrapper per slot; the common body does not need
> > to know its position:
> >
> > #define DEVINET_CONF_WRAPPER(attr) \
> > static int devinet_conf_##attr(const struct ctl_table *ctl, ...) \
> > { \
> > struct devinet_sysctl_table *t = \
> > sysctl_table_container(ctl, \
> > struct devinet_sysctl_table, devinet_vars, \
> > IPV4_DEVCONF_##attr - 1); \
> > return devinet_conf_proc_common(ctl, &t->context, ...); \
> > }
>
> Two questions before seeing the actual implementation of this.
>
> 1. This means that we will have to add more macros to the sysctl
> callers? There is a clear signal in [1] against overuse of macros.
> 2. I understand that you are doing this to avoid having priv. Is it to
> save memory? Yes. priv is a void* and we are also trying to get rid
> of these. But this changes removes the use of two void pointers and
> replaces it with just one.
The idea behind removing the 'void *priv' is mostly to save memory.
There are a lot of systctl and hardly any need it.
This solution does look nasty.
I suggested another where the size of the array entries was passed in
by the caller.
If that works it would allow the per-value function use container_of()
to get extra fields.
That only really helps if only a few 'private' functions need it.
David
>
> Best
>
> [1] https://lore.kernel.org/CAHk-=wjUmLrJd4KM4xvJHUN4P0r8oSu5LyvG4JipnhxizBrE9Q@mail.gmail.com
> >
> > Single-entry tables simply use slot 0:
> >
> > struct devinet_forward_table *t =
> > sysctl_table_container(ctl, struct devinet_forward_table, table,
> > 0);
> >
> >
> > The series is 20 commits over 134 files, with no priv at any point. If
> > you would prefer a different shape for the helper or the wrappers, I am
> > happy to adjust it.
> >
> >
> > Thanks,
> > Wen
> >
> > > David
> > >
prev parent reply other threads:[~2026-11-07 17:05 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 16:34 wen.yang
2026-10-28 16:34 ` [RFC PATCH 01/39] " wen.yang
2026-10-28 21:09 ` David Laight
2026-11-07 17:43 ` Joel Granados
2026-10-28 16:34 ` [RFC PATCH 02/39] test_sysctl: convert bounds to numeric values wen.yang
2026-10-28 16:34 ` [RFC PATCH 03/39] sysctl: add KUnit coverage for numeric bounds and handlers wen.yang
2026-10-28 16:34 ` [RFC PATCH 04/39] sysctl: cover runtime ranges and context lifecycles in KUnit wen.yang
2026-10-28 16:34 ` [RFC PATCH 05/39] sysctl: cover priv in KUnit and the debug test module wen.yang
2026-10-28 16:34 ` [RFC PATCH 06/39] sysctl: convert core table bounds to numeric values wen.yang
2026-10-28 16:34 ` [RFC PATCH 07/39] sysctl: store architecture sysctl bounds by value wen.yang
2026-10-28 16:34 ` [RFC PATCH 08/39] sysctl: store crypto " wen.yang
2026-10-28 16:34 ` [RFC PATCH 09/39] sysctl: store device " wen.yang
2026-10-28 16:34 ` [RFC PATCH 10/39] sysctl: store filesystem " wen.yang
2026-10-28 16:34 ` [RFC PATCH 11/39] sysctl: store message-queue " wen.yang
2026-10-28 16:34 ` [RFC PATCH 12/39] sysctl: store kernel " wen.yang
2026-10-28 16:34 ` [RFC PATCH 13/39] sysctl: store memory-management " wen.yang
2026-10-28 16:34 ` [RFC PATCH 14/39] sysctl: store IPv6 scalar " wen.yang
2026-10-28 16:34 ` [RFC PATCH 15/39] sysctl: store netfilter " wen.yang
2026-10-28 16:34 ` [RFC PATCH 16/39] sysctl: store RPC " wen.yang
2026-10-28 16:34 ` [RFC PATCH 17/39] sysctl: store remaining network " wen.yang
2026-10-28 16:34 ` [RFC PATCH 18/39] sysctl: store security " wen.yang
2026-10-28 16:34 ` [RFC PATCH 19/39] io_uring: store its " wen.yang
2026-10-28 16:34 ` [RFC PATCH 20/39] sysctl: refresh dynamic scheduler and PID bounds per call wen.yang
2026-10-28 16:35 ` [RFC PATCH 21/39] sysctl: refresh device-dependent " wen.yang
2026-10-28 16:35 ` [RFC PATCH 22/39] sysctl: refresh namespace IPC " wen.yang
2026-10-28 16:35 ` [RFC PATCH 23/39] yama: preserve scope locking with numeric sysctl bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 24/39] net: refresh core sysctl limits without bound pointers wen.yang
2026-10-28 16:35 ` [RFC PATCH 25/39] sctp: resolve numeric ranges from the current namespace wen.yang
2026-10-28 16:35 ` [RFC PATCH 26/39] rds: preserve live reconnect limits with numeric bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 27/39] ipv4: preserve live and vector bounds with numeric sysctls wen.yang
2026-10-28 16:35 ` [RFC PATCH 28/39] net: refresh fragment and remaining dynamic sysctl bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 29/39] neighbour: derive sysctl ownership independently of bounds wen.yang
2026-10-28 16:35 ` [RFC PATCH 30/39] net: resolve sysctl owners from their backing data wen.yang
2026-10-28 16:35 ` [RFC PATCH 31/39] ipvs: derive sysctl ownership from numeric storage wen.yang
2026-10-28 16:35 ` [RFC PATCH 32/39] sysctl: remove obsolete nr_open bound variables wen.yang
2026-10-28 16:35 ` [RFC PATCH 33/39] ipv6: move address sysctl context to priv wen.yang
2026-10-28 16:35 ` [RFC PATCH 34/39] ipv4: move device " wen.yang
2026-10-28 16:35 ` [RFC PATCH 35/39] netfilter: move logger " wen.yang
2026-10-28 16:35 ` [RFC PATCH 36/39] parport: move device " wen.yang
2026-10-28 16:35 ` [RFC PATCH 37/39] net: move namespace " wen.yang
2026-10-28 16:35 ` [RFC PATCH 38/39] arm64: move vector-length " wen.yang
2026-10-28 16:35 ` [RFC PATCH 39/39] sysctl: remove the extra pointers and the compatibility bounds read wen.yang
2026-10-29 10:58 ` [RFC PATCH 00/39] sysctl: replace overloaded extra pointers with typed bounds and context David Laight
2026-11-02 15:40 ` Wen Yang
2026-11-02 16:54 ` David Laight
2026-11-04 18:32 ` Wen Yang
2026-11-07 15:27 ` Joel Granados
2026-11-07 17:05 ` David Laight [this message]
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=20261107170507.0d66cc2e@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=joel.granados@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=wen.yang@linux.dev \
/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
all inboxes | Powered by JetHome®