NetBSD Problem Report #58729
From www@netbsd.org Tue Oct 8 13:47:39 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 18F961A923B
for <gnats-bugs@gnats.NetBSD.org>; Tue, 8 Oct 2024 13:47:39 +0000 (UTC)
Message-Id: <20241008134737.EE4561A923D@mollari.NetBSD.org>
Date: Tue, 8 Oct 2024 13:47:37 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: container_of is not documented or available in userland
X-Send-Pr-Version: www-1.0
>Number: 58729
>Category: lib
>Synopsis: container_of is not documented or available in userland
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 08 13:50:00 +0000 2024
>Last-Modified: Tue Oct 08 22:55:01 +0000 2024
>Originator: Taylor R Campbell
>Release: current, 10, 9, ...
>Organization:
The Struct &NetBSD->foundation
>Environment:
>Description:
1. container_of is missing a man page
2. container_of is defined in libkern.h, not, say, sys/container_of.h, so it isn't available in userland
>How-To-Repeat:
discussion on tech-userlevel
>Fix:
Yes, please!
>Audit-Trail:
From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Cc:
Subject: Re: lib/58729: container_of is not documented or available in userland
Date: Tue, 8 Oct 2024 14:28:33 +0000
Small complication: container_of is defined in libkern.h and uses
offsetof which, for the kernel, is also defined in libkern.h.
So just moving container_of to another header file would create a
circular dependency (libkern.h uses sys/container_of.h for
container_of, and is used by sys/container_of.h for offsetof).
To avoid that, we could:
(a) split offsetof into another header file (maybe we should add
sys/stddef.h), or
(b) update all container_of users in kernel to use sys/container_of.h
explicitly so libkern.h doesn't have to expose container_of
itself.
From: Jason Thorpe <thorpej@me.com>
To: Taylor Campbell <riastradh@netbsd.org>
Cc: "gnats-bugs@netbsd.org" <gnats-bugs@NetBSD.org>,
"netbsd-bugs@netbsd.org" <netbsd-bugs@NetBSD.org>
Subject: Re: lib/58729: container_of is not documented or available in
userland
Date: Tue, 8 Oct 2024 09:28:31 -0700
> On Oct 8, 2024, at 7:28=E2=80=AFAM, Taylor R Campbell =
<riastradh@netbsd.org> wrote:
>=20
> (a) split offsetof into another header file (maybe we should add
> sys/stddef.h), or
This seems like the best solution.
-- thorpej
From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Cc:
Subject: Re: lib/58729: container_of is not documented or available in userland
Date: Tue, 8 Oct 2024 17:18:20 +0000
This is a multi-part message in MIME format.
--=_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS
Here's a draft that just duplicates the include/stddef.h definition of
offsetof for now. It coexists peacefully in the kernel with the
libkern.h definition -- with #ifndef offsetof hacks in both places.
Not great but it'll serve to address the immediate issue without
deciding how best to disentangle things.
Another thought I had is that it might be worthwhile to have
__container_of and __offsetof macros that would avoid namespace
pollution, and only expose container_of and offsetof if you explicitly
ask for a header file defined to use them. But I don't have a use
case for this right now so I won't do anything about this.
--=_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS
Content-Type: text/plain; charset="ISO-8859-1"; name="pr58729-containerofh"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="pr58729-containerofh.patch"
# HG changeset patch
# User Taylor R Campbell <riastradh@NetBSD.org>
# Date 1728402416 0
# Tue Oct 08 15:46:56 2024 +0000
# Branch trunk
# Node ID 32a19974e47ea523810619381ab6d96671c537c9
# Parent 324886ee2905fda3948217e0fd3c6ca7f4cf32dc
# EXP-Topic riastradh-pr58729-containerof
container_of: New header file sys/container_of.h for this.
PR lib/58729: container_of is not documented or available in userland
diff -r 324886ee2905 -r 32a19974e47e sys/lib/libkern/libkern.h
--- a/sys/lib/libkern/libkern.h Tue Oct 08 12:49:01 2024 +0000
+++ b/sys/lib/libkern/libkern.h Tue Oct 08 15:46:56 2024 +0000
@@ -323,46 +323,7 @@ tolower(int ch)
#endif
#endif
=20
-/*
- * Return the container of an embedded struct. Given x =3D &c->f,
- * container_of(x, T, f) yields c, where T is the type of c. Example:
- *
- * struct foo { ... };
- * struct bar {
- * int b_x;
- * struct foo b_foo;
- * ...
- * };
- *
- * struct bar b;
- * struct foo *fp =3D &b.b_foo;
- *
- * Now we can get at b from fp by:
- *
- * struct bar *bp =3D container_of(fp, struct bar, b_foo);
- *
- * The 0*sizeof((PTR) - ...) causes the compiler to warn if the type of
- * *fp does not match the type of struct bar::b_foo.
- * We skip the validation for coverity runs to avoid warnings.
- */
-#if defined(__COVERITY__) || defined(__LGTM_BOT__)
-#define __validate_container_of(PTR, TYPE, FIELD) 0
-#define __validate_const_container_of(PTR, TYPE, FIELD) 0
-#else
-#define __validate_container_of(PTR, TYPE, FIELD) \
- (0 * sizeof((PTR) - &((TYPE *)(((char *)(PTR)) - \
- offsetof(TYPE, FIELD)))->FIELD))
-#define __validate_const_container_of(PTR, TYPE, FIELD) \
- (0 * sizeof((PTR) - &((const TYPE *)(((const char *)(PTR)) - \
- offsetof(TYPE, FIELD)))->FIELD))
-#endif
-
-#define container_of(PTR, TYPE, FIELD) \
- ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, FIELD)) \
- + __validate_container_of(PTR, TYPE, FIELD))
-#define const_container_of(PTR, TYPE, FIELD) \
- ((const TYPE *)(((const char *)(PTR)) - offsetof(TYPE, FIELD)) \
- + __validate_const_container_of(PTR, TYPE, FIELD))
+#include <sys/container_of.h>
=20
/* Prototypes for which GCC built-ins exist. */
void *memcpy(void *, const void *, size_t);
diff -r 324886ee2905 -r 32a19974e47e sys/sys/container_of.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/sys/container_of.h Tue Oct 08 15:46:56 2024 +0000
@@ -0,0 +1,101 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTO=
RS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIM=
ITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICU=
LAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTO=
RS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF =
THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_CONTAINER_OF_H_
+#define _SYS_CONTAINER_OF_H_
+
+#include <sys/ansi.h>
+
+#ifdef _BSD_SIZE_T_
+typedef _BSD_SIZE_T_ size_t;
+#undef _BSD_SIZE_T_
+#endif
+
+/*
+ * XXX Avoid duplicating this with sys/lib/libkern/libkern.h and
+ * include/stddef.h.
+ */
+#ifndef offsetof
+#if __GNUC_PREREQ__(4, 0)
+#define offsetof(type, member) __builtin_offsetof(type, member)
+#elif !defined(__cplusplus)
+#define offsetof(type, member) ((size_t)(unsigned long)(&((type *)0)->memb=
er))
+#else
+#if !__GNUC_PREREQ__(3, 4)
+#define __offsetof__(a) a
+#endif
+#define offsetof(type, member) __offsetof__((reinterpret_cast<size_t> \
+ (&reinterpret_cast<const volatile char &>(static_cast<type *>(0)->memb=
er))))
+#endif
+#endif
+
+/*
+ * Return the container of an embedded struct. Given x =3D &c->f,
+ * container_of(x, T, f) yields c, where T is the type of c. Example:
+ *
+ * struct foo { ... };
+ * struct bar {
+ * int b_x;
+ * struct foo b_foo;
+ * ...
+ * };
+ *
+ * struct bar b;
+ * struct foo *fp =3D &b.b_foo;
+ *
+ * Now we can get at b from fp by:
+ *
+ * struct bar *bp =3D container_of(fp, struct bar, b_foo);
+ *
+ * The 0*sizeof((PTR) - ...) causes the compiler to warn if the type of
+ * *fp does not match the type of struct bar::b_foo.
+ * We skip the validation for coverity runs to avoid warnings.
+ */
+#if defined(__COVERITY__) || defined(__LGTM_BOT__)
+#define __validate_container_of(PTR, TYPE, FIELD) 0
+#define __validate_const_container_of(PTR, TYPE, FIELD) 0
+#else
+#define __validate_container_of(PTR, TYPE, FIELD) \
+ (0 * sizeof((PTR) - &((TYPE *)(((char *)(PTR)) - \
+ offsetof(TYPE, FIELD)))->FIELD))
+#define __validate_const_container_of(PTR, TYPE, FIELD) \
+ (0 * sizeof((PTR) - &((const TYPE *)(((const char *)(PTR)) - \
+ offsetof(TYPE, FIELD)))->FIELD))
+#endif
+
+#define container_of(PTR, TYPE, FIELD) \
+ ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, FIELD)) \
+ + __validate_container_of(PTR, TYPE, FIELD))
+#define const_container_of(PTR, TYPE, FIELD) \
+ ((const TYPE *)(((const char *)(PTR)) - offsetof(TYPE, FIELD)) \
+ + __validate_const_container_of(PTR, TYPE, FIELD))
+
+#endif /* _SYS_CONTAINER_OF_H_ */
# HG changeset patch
# User Taylor R Campbell <riastradh@NetBSD.org>
# Date 1728407830 0
# Tue Oct 08 17:17:10 2024 +0000
# Branch trunk
# Node ID 4529dd9470d4274e62fb97bbbfc358f45342be28
# Parent 32a19974e47ea523810619381ab6d96671c537c9
# EXP-Topic riastradh-pr58729-containerof
container_of(3): New man page.
PR lib/58729: container_of is not documented or available in userland
diff -r 32a19974e47e -r 4529dd9470d4 distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi Tue Oct 08 15:46:56 2024 +0000
+++ b/distrib/sets/lists/comp/mi Tue Oct 08 17:17:10 2024 +0000
@@ -7024,8 +7024,10 @@
./usr/share/man/cat3/conj.0 comp-c-catman complex,.cat
./usr/share/man/cat3/conjf.0 comp-c-catman complex,.cat
./usr/share/man/cat3/conjl.0 comp-c-catman complex,.cat
+./usr/share/man/cat3/const_container_of.0 comp-c-catman .cat
./usr/share/man/cat3/consttime_bcmp.0 comp-obsolete obsolete
./usr/share/man/cat3/consttime_memequal.0 comp-c-catman .cat
+./usr/share/man/cat3/container_of.0 comp-c-catman .cat
./usr/share/man/cat3/copysign.0 comp-c-catman .cat
./usr/share/man/cat3/copysignf.0 comp-c-catman .cat
./usr/share/man/cat3/copysignl.0 comp-c-catman .cat
@@ -15552,8 +15554,10 @@
./usr/share/man/html3/conj.html comp-c-htmlman complex,html
./usr/share/man/html3/conjf.html comp-c-htmlman complex,html
./usr/share/man/html3/conjl.html comp-c-htmlman complex,html
+./usr/share/man/html3/const_container_of.html comp-c-htmlman html
./usr/share/man/html3/consttime_bcmp.html comp-obsolete obsolete
./usr/share/man/html3/consttime_memequal.html comp-c-htmlman html
+./usr/share/man/html3/container_of.html comp-c-htmlman html
./usr/share/man/html3/copysign.html comp-c-htmlman html
./usr/share/man/html3/copysignf.html comp-c-htmlman html
./usr/share/man/html3/copysignl.html comp-c-htmlman html
@@ -24025,8 +24029,10 @@
./usr/share/man/man3/conj.3 comp-c-man complex,.man
./usr/share/man/man3/conjf.3 comp-c-man complex,.man
./usr/share/man/man3/conjl.3 comp-c-man complex,.man
+./usr/share/man/man3/const_container_of.3 comp-c-man .man
./usr/share/man/man3/consttime_bcmp.3 comp-obsolete obsolete
./usr/share/man/man3/consttime_memequal.3 comp-c-man .man
+./usr/share/man/man3/container_of.3 comp-c-man .man
./usr/share/man/man3/copysign.3 comp-c-man .man
./usr/share/man/man3/copysignf.3 comp-c-man .man
./usr/share/man/man3/copysignl.3 comp-c-man .man
diff -r 32a19974e47e -r 4529dd9470d4 share/man/man3/Makefile
--- a/share/man/man3/Makefile Tue Oct 08 15:46:56 2024 +0000
+++ b/share/man/man3/Makefile Tue Oct 08 17:17:10 2024 +0000
@@ -7,7 +7,8 @@ MAN=3D _DIAGASSERT.3 __CONCAT.3 __FPTRCAST
__builtin_return_address.3 \
__builtin_types_compatible_p.3 __insn_barrier.3 \
assert.3 attribute.3 bitmap.3 bitops.3 bits.3 bitstring.3 \
- cdefs.3 dirent.3 dlfcn.3 dlinfo.3 dl_iterate_phdr.3 end.3 \
+ cdefs.3 container_of.3 \
+ dirent.3 dlfcn.3 dlinfo.3 dl_iterate_phdr.3 end.3 \
fast_divide32.3 ffs32.3 gcq.3 \
ilog2.3 intro.3 inttypes.3 iso646.3 limits.3 \
makedev.3 offsetof.3 param.3 paths.3 queue.3 rbtree.3 sigevent.3 \
@@ -54,6 +55,7 @@ MLINKS+=3Dbits.3 __BIT.3 \
bits.3 __SHIFTOUT_MASK.3
MLINKS+=3Dcdefs.3 __RCSID.3 \
cdefs.3 __KERNEL_RCSID.3
+MLINKS+=3Dcontainer_of.3 const_container_of.3
MLINKS+=3Dend.3 edata.3 end.3 etext.3
MLINKS+=3Dfast_divide32.3 fast_divide32_prepare.3 \
fast_divide32.3 fast_remainder32.3
diff -r 32a19974e47e -r 4529dd9470d4 share/man/man3/container_of.3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/share/man/man3/container_of.3 Tue Oct 08 17:17:10 2024 +0000
@@ -0,0 +1,109 @@
+.\" $NetBSD$
+.\"
+.\" Copyright (c) 2024 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUT=
ORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LI=
MITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTIC=
ULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUT=
ORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINE=
SS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF=
THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd October 8, 2024
+.Dt CONTAINER_OF 3
+.Os
+.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"""""
+.Sh NAME
+.Nm container_of ,
+.Nm const_container_of
+.Nd struct container accessor macros
+.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"""""
+.Sh SYNOPSIS
+.In sys/container_of.h
+.Ft struct_type *
+.Fn container_of "member_type *ptr" "struct_type" "member"
+.Ft const struct_type *
+.Fn const_container_of "const member_type *ptr" "struct_type" "member"
+.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"""""
+.Sh DESCRIPTION
+Given a pointer to a member of a structure, the
+.Fn container_of
+macro returns a pointer to the containing structure.
+.Pp
+The caller must specify the containing structure's type and the name of
+the member in the containing structure, which must have type compatible
+with what the input pointer points to.
+.Pp
+The
+.Fn const_container_of
+macro does similarly for a const-qualified pointer.
+.Pp
+The call
+.Fn container_of P T M
+is essentially equivalent to
+.Dl "(" Ns Fa T Li "*)((char *)" Ns Fa P Li "-" Fn offsetof T M Ns ")" ,
+but it is safer because it checks the type of
+.Fa P
+against the type of member
+.Fa M
+of structure type
+.Fa T .
+.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"""""
+.Sh EXAMPLES
+.Bd -literal
+/* Gizmo data structure */
+struct gizmo {
+ ...
+ struct work gz_work;
+ ...
+};
+
+/* Enqueue gizmo-related work */
+ struct gizmo *gz =3D ...;
+ struct work =3D &gz->gz_work;
+
+ workqueue_enqueue(gizmo_workqueue, work, NULL);
+
+/* Function to process queued gizmo-related work */
+void
+gizmo_work(struct work *work, void *cookie)
+{
+ struct gizmo *gz =3D container_of(work, struct gizmo, gz_work);
+
+ ...
+}
+.Ed
+.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"""""
+.Sh SEE ALSO
+.Xr offsetof 3
+.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"""""
+.Sh HISTORY
+The
+.Fn container_of
+and
+.Fn const_container_of
+macros first appeared in
+.Nx 8.0
+in
+.In libkern.h
+for kernel use.
+They were moved in
+.Nx 11.0
+to
+.In sys/container_of.h
+for use by both kernel and userland.
--=_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS--
From: Christos Zoulas <christos@zoulas.com>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, campbell+netbsd@mumble.net
Subject: Re: lib/58729: container_of is not documented or available in userland
Date: Tue, 8 Oct 2024 16:15:35 -0400
I am testing a diff that moves sttdef.h to sys
christos
> On Oct 8, 2024, at 1:20=E2=80=AFPM, Taylor R Campbell via gnats <gnats-adm=
in@netbsd.org> wrote:
>=20
> =EF=BB=BFThe following reply was made to PR lib/58729; it has been noted b=
y GNATS.
>=20
> From: Taylor R Campbell <riastradh@NetBSD.org>
> To: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
> Cc:
> Subject: Re: lib/58729: container_of is not documented or available in use=
rland
> Date: Tue, 8 Oct 2024 17:18:20 +0000
>=20
> This is a multi-part message in MIME format.
> --=3D_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS
>=20
> Here's a draft that just duplicates the include/stddef.h definition of
> offsetof for now. It coexists peacefully in the kernel with the
> libkern.h definition -- with #ifndef offsetof hacks in both places.
> Not great but it'll serve to address the immediate issue without
> deciding how best to disentangle things.
>=20
> Another thought I had is that it might be worthwhile to have
> __container_of and __offsetof macros that would avoid namespace
> pollution, and only expose container_of and offsetof if you explicitly
> ask for a header file defined to use them. But I don't have a use
> case for this right now so I won't do anything about this.
>=20
> --=3D_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS
> Content-Type: text/plain; charset=3D"ISO-8859-1"; name=3D"pr58729-containe=
rofh"
> Content-Transfer-Encoding: quoted-printable
> Content-Disposition: attachment; filename=3D"pr58729-containerofh.patch"
>=20
> # HG changeset patch
> # User Taylor R Campbell <riastradh@NetBSD.org>
> # Date 1728402416 0
> # Tue Oct 08 15:46:56 2024 +0000
> # Branch trunk
> # Node ID 32a19974e47ea523810619381ab6d96671c537c9
> # Parent 324886ee2905fda3948217e0fd3c6ca7f4cf32dc
> # EXP-Topic riastradh-pr58729-containerof
> container_of: New header file sys/container_of.h for this.
>=20
> PR lib/58729: container_of is not documented or available in userland
>=20
> diff -r 324886ee2905 -r 32a19974e47e sys/lib/libkern/libkern.h
> --- a/sys/lib/libkern/libkern.h Tue Oct 08 12:49:01 2024 +0000
> +++ b/sys/lib/libkern/libkern.h Tue Oct 08 15:46:56 2024 +0000
> @@ -323,46 +323,7 @@ tolower(int ch)
> #endif
> #endif
> =3D20
> -/*
> - * Return the container of an embedded struct. Given x =3D3D &c->f,
> - * container_of(x, T, f) yields c, where T is the type of c. Example:
> - *
> - * struct foo { ... };
> - * struct bar {
> - * int b_x;
> - * struct foo b_foo;
> - * ...
> - * };
> - *
> - * struct bar b;
> - * struct foo *fp =3D3D &b.b_foo;
> - *
> - * Now we can get at b from fp by:
> - *
> - * struct bar *bp =3D3D container_of(fp, struct bar, b_foo);
> - *
> - * The 0*sizeof((PTR) - ...) causes the compiler to warn if the type of
> - * *fp does not match the type of struct bar::b_foo.
> - * We skip the validation for coverity runs to avoid warnings.
> - */
> -#if defined(__COVERITY__) || defined(__LGTM_BOT__)
> -#define __validate_container_of(PTR, TYPE, FIELD) 0
> -#define __validate_const_container_of(PTR, TYPE, FIELD) 0
> -#else
> -#define __validate_container_of(PTR, TYPE, FIELD) \
> - (0 * sizeof((PTR) - &((TYPE *)(((char *)(PTR)) - \
> - offsetof(TYPE, FIELD)))->FIELD))
> -#define __validate_const_container_of(PTR, TYPE, FIELD) \
> - (0 * sizeof((PTR) - &((const TYPE *)(((const char *)(PTR)) - \
> - offsetof(TYPE, FIELD)))->FIELD))
> -#endif
> -
> -#define container_of(PTR, TYPE, FIELD) \
> - ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, FIELD)) \
> - + __validate_container_of(PTR, TYPE, FIELD))
> -#define const_container_of(PTR, TYPE, FIELD) \
> - ((const TYPE *)(((const char *)(PTR)) - offsetof(TYPE, FIELD)) \
> - + __validate_const_container_of(PTR, TYPE, FIELD))
> +#include <sys/container_of.h>
> =3D20
> /* Prototypes for which GCC built-ins exist. */
> void *memcpy(void *, const void *, size_t);
> diff -r 324886ee2905 -r 32a19974e47e sys/sys/container_of.h
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/sys/sys/container_of.h Tue Oct 08 15:46:56 2024 +0000
> @@ -0,0 +1,101 @@
> +/* $NetBSD$ */
> +
> +/*-
> + * Copyright (c) 2013 The NetBSD Foundation, Inc.
> + * All rights reserved.
> + *
> + * This code is derived from software contributed to The NetBSD Foundatio=
n
> + * by Taylor R. Campbell.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the=
> + * documentation and/or other materials provided with the distribution=
.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUT=
O=3D
> RS
> + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LI=
M=3D
> ITED
> + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTIC=
U=3D
> LAR
> + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUT=
O=3D
> RS
> + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR=
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINE=
SS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER I=
N
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE=
)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF=
=3D
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _SYS_CONTAINER_OF_H_
> +#define _SYS_CONTAINER_OF_H_
> +
> +#include <sys/ansi.h>
> +
> +#ifdef _BSD_SIZE_T_
> +typedef _BSD_SIZE_T_ size_t;
> +#undef _BSD_SIZE_T_
> +#endif
> +
> +/*
> + * XXX Avoid duplicating this with sys/lib/libkern/libkern.h and
> + * include/stddef.h.
> + */
> +#ifndef offsetof
> +#if __GNUC_PREREQ__(4, 0)
> +#define offsetof(type, member) __builtin_offsetof(type, member)
> +#elif !defined(__cplusplus)
> +#define offsetof(type, member) ((size_t)(unsigned long)(&((type *)0=
)->memb=3D
> er))
> +#else
> +#if !__GNUC_PREREQ__(3, 4)
> +#define __offsetof__(a) a
> +#endif
> +#define offsetof(type, member) __offsetof__((reinterpret_cast<size_t> \=
> + (&reinterpret_cast<const volatile char &>(static_cast<type *>(0)->mem=
b=3D
> er))))
> +#endif
> +#endif
> +
> +/*
> + * Return the container of an embedded struct. Given x =3D3D &c->f,
> + * container_of(x, T, f) yields c, where T is the type of c. Example:
> + *
> + * struct foo { ... };
> + * struct bar {
> + * int b_x;
> + * struct foo b_foo;
> + * ...
> + * };
> + *
> + * struct bar b;
> + * struct foo *fp =3D3D &b.b_foo;
> + *
> + * Now we can get at b from fp by:
> + *
> + * struct bar *bp =3D3D container_of(fp, struct bar, b_foo);
> + *
> + * The 0*sizeof((PTR) - ...) causes the compiler to warn if the type of
> + * *fp does not match the type of struct bar::b_foo.
> + * We skip the validation for coverity runs to avoid warnings.
> + */
> +#if defined(__COVERITY__) || defined(__LGTM_BOT__)
> +#define __validate_container_of(PTR, TYPE, FIELD) 0
> +#define __validate_const_container_of(PTR, TYPE, FIELD) 0
> +#else
> +#define __validate_container_of(PTR, TYPE, FIELD) \
> + (0 * sizeof((PTR) - &((TYPE *)(((char *)(PTR)) - \
> + offsetof(TYPE, FIELD)))->FIELD))
> +#define __validate_const_container_of(PTR, TYPE, FIELD) \
> + (0 * sizeof((PTR) - &((const TYPE *)(((const char *)(PTR)) - \
> + offsetof(TYPE, FIELD)))->FIELD))
> +#endif
> +
> +#define container_of(PTR, TYPE, FIELD) \
> + ((TYPE *)(((char *)(PTR)) - offsetof(TYPE, FIELD)) \
> + + __validate_container_of(PTR, TYPE, FIELD))
> +#define const_container_of(PTR, TYPE, FIELD) \
> + ((const TYPE *)(((const char *)(PTR)) - offsetof(TYPE, FIELD)) \
> + + __validate_const_container_of(PTR, TYPE, FIELD))
> +
> +#endif /* _SYS_CONTAINER_OF_H_ */
> # HG changeset patch
> # User Taylor R Campbell <riastradh@NetBSD.org>
> # Date 1728407830 0
> # Tue Oct 08 17:17:10 2024 +0000
> # Branch trunk
> # Node ID 4529dd9470d4274e62fb97bbbfc358f45342be28
> # Parent 32a19974e47ea523810619381ab6d96671c537c9
> # EXP-Topic riastradh-pr58729-containerof
> container_of(3): New man page.
>=20
> PR lib/58729: container_of is not documented or available in userland
>=20
> diff -r 32a19974e47e -r 4529dd9470d4 distrib/sets/lists/comp/mi
> --- a/distrib/sets/lists/comp/mi Tue Oct 08 15:46:56 2024 +0000
> +++ b/distrib/sets/lists/comp/mi Tue Oct 08 17:17:10 2024 +0000
> @@ -7024,8 +7024,10 @@
> ./usr/share/man/cat3/conj.0 comp-c-catman complex,.cat
> ./usr/share/man/cat3/conjf.0 comp-c-catman complex,.cat=
> ./usr/share/man/cat3/conjl.0 comp-c-catman complex,.cat=
> +./usr/share/man/cat3/const_container_of.0 comp-c-catman .cat
> ./usr/share/man/cat3/consttime_bcmp.0 comp-obsolete obsolet=
e
> ./usr/share/man/cat3/consttime_memequal.0 comp-c-catman .cat
> +./usr/share/man/cat3/container_of.0 comp-c-catman .cat
> ./usr/share/man/cat3/copysign.0 comp-c-catman .cat
> ./usr/share/man/cat3/copysignf.0 comp-c-catman .cat
> ./usr/share/man/cat3/copysignl.0 comp-c-catman .cat
> @@ -15552,8 +15554,10 @@
> ./usr/share/man/html3/conj.html comp-c-htmlman complex,=
html
> ./usr/share/man/html3/conjf.html comp-c-htmlman complex,htm=
l
> ./usr/share/man/html3/conjl.html comp-c-htmlman complex,htm=
l
> +./usr/share/man/html3/const_container_of.html comp-c-htmlman ht=
ml
> ./usr/share/man/html3/consttime_bcmp.html comp-obsolete obsolet=
e
> ./usr/share/man/html3/consttime_memequal.html comp-c-htmlman ht=
ml
> +./usr/share/man/html3/container_of.html comp-c-htmlman html=
> ./usr/share/man/html3/copysign.html comp-c-htmlman html
> ./usr/share/man/html3/copysignf.html comp-c-htmlman html
> ./usr/share/man/html3/copysignl.html comp-c-htmlman html
> @@ -24025,8 +24029,10 @@
> ./usr/share/man/man3/conj.3 comp-c-man complex,.man
> ./usr/share/man/man3/conjf.3 comp-c-man complex,.man
> ./usr/share/man/man3/conjl.3 comp-c-man complex,.man
> +./usr/share/man/man3/const_container_of.3 comp-c-man .man
> ./usr/share/man/man3/consttime_bcmp.3 comp-obsolete obsolet=
e
> ./usr/share/man/man3/consttime_memequal.3 comp-c-man .man
> +./usr/share/man/man3/container_of.3 comp-c-man .man
> ./usr/share/man/man3/copysign.3 comp-c-man .man
> ./usr/share/man/man3/copysignf.3 comp-c-man .man
> ./usr/share/man/man3/copysignl.3 comp-c-man .man
> diff -r 32a19974e47e -r 4529dd9470d4 share/man/man3/Makefile
> --- a/share/man/man3/Makefile Tue Oct 08 15:46:56 2024 +0000
> +++ b/share/man/man3/Makefile Tue Oct 08 17:17:10 2024 +0000
> @@ -7,7 +7,8 @@ MAN=3D3D _DIAGASSERT.3 __CONCAT.3 __FPTRCAST
> __builtin_return_address.3 \
> __builtin_types_compatible_p.3 __insn_barrier.3 \
> assert.3 attribute.3 bitmap.3 bitops.3 bits.3 bitstring.3 \
> - cdefs.3 dirent.3 dlfcn.3 dlinfo.3 dl_iterate_phdr.3 end.3 \
> + cdefs.3 container_of.3 \
> + dirent.3 dlfcn.3 dlinfo.3 dl_iterate_phdr.3 end.3 \
> fast_divide32.3 ffs32.3 gcq.3 \
> ilog2.3 intro.3 inttypes.3 iso646.3 limits.3 \
> makedev.3 offsetof.3 param.3 paths.3 queue.3 rbtree.3 sigevent.3 \
> @@ -54,6 +55,7 @@ MLINKS+=3D3Dbits.3 __BIT.3 \
> bits.3 __SHIFTOUT_MASK.3
> MLINKS+=3D3Dcdefs.3 __RCSID.3 \
> cdefs.3 __KERNEL_RCSID.3
> +MLINKS+=3D3Dcontainer_of.3 const_container_of.3
> MLINKS+=3D3Dend.3 edata.3 end.3 etext.3
> MLINKS+=3D3Dfast_divide32.3 fast_divide32_prepare.3 \
> fast_divide32.3 fast_remainder32.3
> diff -r 32a19974e47e -r 4529dd9470d4 share/man/man3/container_of.3
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/share/man/man3/container_of.3 Tue Oct 08 17:17:10 2024 +0000
> @@ -0,0 +1,109 @@
> +.\" $NetBSD$
> +.\"
> +.\" Copyright (c) 2024 The NetBSD Foundation, Inc.
> +.\" All rights reserved.
> +.\"
> +.\" Redistribution and use in source and binary forms, with or without
> +.\" modification, are permitted provided that the following conditions
> +.\" are met:
> +.\" 1. Redistributions of source code must retain the above copyright
> +.\" notice, this list of conditions and the following disclaimer.
> +.\" 2. Redistributions in binary form must reproduce the above copyright
> +.\" notice, this list of conditions and the following disclaimer in th=
e
> +.\" documentation and/or other materials provided with the distributio=
n.
> +.\"
> +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBU=
T=3D
> ORS
> +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT L=
I=3D
> MITED
> +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTI=
C=3D
> ULAR
> +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBU=
T=3D
> ORS
> +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, O=
R
> +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSIN=
E=3D
> SS
> +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER I=
N
> +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS=
E)
> +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED O=
F=3D
> THE
> +.\" POSSIBILITY OF SUCH DAMAGE.
> +.\"
> +.Dd October 8, 2024
> +.Dt CONTAINER_OF 3
> +.Os
> +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"=3D
> """""
> +.Sh NAME
> +.Nm container_of ,
> +.Nm const_container_of
> +.Nd struct container accessor macros
> +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"=3D
> """""
> +.Sh SYNOPSIS
> +.In sys/container_of.h
> +.Ft struct_type *
> +.Fn container_of "member_type *ptr" "struct_type" "member"
> +.Ft const struct_type *
> +.Fn const_container_of "const member_type *ptr" "struct_type" "member"
> +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"=3D
> """""
> +.Sh DESCRIPTION
> +Given a pointer to a member of a structure, the
> +.Fn container_of
> +macro returns a pointer to the containing structure.
> +.Pp
> +The caller must specify the containing structure's type and the name of
> +the member in the containing structure, which must have type compatible
> +with what the input pointer points to.
> +.Pp
> +The
> +.Fn const_container_of
> +macro does similarly for a const-qualified pointer.
> +.Pp
> +The call
> +.Fn container_of P T M
> +is essentially equivalent to
> +.Dl "(" Ns Fa T Li "*)((char *)" Ns Fa P Li "-" Fn offsetof T M Ns ")" ,
> +but it is safer because it checks the type of
> +.Fa P
> +against the type of member
> +.Fa M
> +of structure type
> +.Fa T .
> +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"=3D
> """""
> +.Sh EXAMPLES
> +.Bd -literal
> +/* Gizmo data structure */
> +struct gizmo {
> + ...
> + struct work gz_work;
> + ...
> +};
> +
> +/* Enqueue gizmo-related work */
> + struct gizmo *gz =3D3D ...;
> + struct work =3D3D &gz->gz_work;
> +
> + workqueue_enqueue(gizmo_workqueue, work, NULL);
> +
> +/* Function to process queued gizmo-related work */
> +void
> +gizmo_work(struct work *work, void *cookie)
> +{
> + struct gizmo *gz =3D3D container_of(work, struct gizmo, gz_work);
> +
> + ...
> +}
> +.Ed
> +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"=3D
> """""
> +.Sh SEE ALSO
> +.Xr offsetof 3
> +.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""=
"=3D
> """""
> +.Sh HISTORY
> +The
> +.Fn container_of
> +and
> +.Fn const_container_of
> +macros first appeared in
> +.Nx 8.0
> +in
> +.In libkern.h
> +for kernel use.
> +They were moved in
> +.Nx 11.0
> +to
> +.In sys/container_of.h
> +for use by both kernel and userland.
>=20
> --=3D_9iRVuQui7SP0XI0my0i42KB+RbbJU+ZS--
>=20
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/58729 CVS commit: src
Date: Tue, 8 Oct 2024 18:53:21 -0400
Module Name: src
Committed By: christos
Date: Tue Oct 8 22:53:21 UTC 2024
Modified Files:
src/distrib/sets/lists/comp: mi
src/include: Makefile
src/sys/sys: Makefile
Added Files:
src/sys/sys: container_of.h stddef.h
Removed Files:
src/include: stddef.h
Log Message:
PR/58729: Taylor R Campbell: container_of is not documented or available
in userland
To generate a diff of this commit:
cvs rdiff -u -r1.2474 -r1.2475 src/distrib/sets/lists/comp/mi
cvs rdiff -u -r1.148 -r1.149 src/include/Makefile
cvs rdiff -u -r1.24 -r0 src/include/stddef.h
cvs rdiff -u -r1.184 -r1.185 src/sys/sys/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/sys/container_of.h src/sys/sys/stddef.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.