public inbox for dwarves@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones
@ 2024-10-08 19:52 Arnaldo Carvalho de Melo
  2024-10-08 19:52 ` [PATCH 1/3] fprintf: Differentiate embedded flexible arrays from flexible arrays Arnaldo Carvalho de Melo
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-10-08 19:52 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: dwarves, Alan Maguire, Jiri Olsa, Clark Williams, Kate Carcia,
	Arnaldo Carvalho de Melo, Gustavo A. R. Silva

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Hi Willy, Gustavo,

	Now it has even a regression test, this now have what I think is
needed, take a look at the output of:

   pahole --with_embedded_flexible_arrays > \
	 http://vger.kernel.org/~acme/pahole--with_embedded_flexible_array-6.10.11-200.fc40.x86_64.c

And go on searching for 'flexible' :-)

	Now I'm flexibly moving to other final issues to release pahole
1.28.

- Arnaldo

Arnaldo Carvalho de Melo (3):
  fprintf: Differentiate embedded flexible arrays from flexible arrays
  fprintf: Show statistics about members with flexible arrays
  tests: Add a test for the accounting of flexible arrays

 dwarves_fprintf.c        | 32 +++++++++++++++--
 tests/flexible_arrays.sh | 77 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+), 3 deletions(-)
 create mode 100755 tests/flexible_arrays.sh

-- 
2.46.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] fprintf: Differentiate embedded flexible arrays from flexible arrays
  2024-10-08 19:52 [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Arnaldo Carvalho de Melo
@ 2024-10-08 19:52 ` Arnaldo Carvalho de Melo
  2024-10-08 19:52 ` [PATCH 2/3] fprintf: Show statistics about members with " Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-10-08 19:52 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: dwarves, Alan Maguire, Jiri Olsa, Clark Williams, Kate Carcia,
	Arnaldo Carvalho de Melo, Gustavo A. R. Silva

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Se one case where a struct has embedded flexible arrays, that was not
being notified as comments following those members:

  acme@x1:~/git/pahole$ pahole lirc_fh
  struct lirc_fh {
  	struct list_head           list;                 /*     0    16 */
  	struct rc_dev *            rc;                   /*    16     8 */
  	int                        carrier_low;          /*    24     4 */

  	/* XXX 4 bytes hole, try to pack */

  	struct {
  		union {
  			struct __kfifo kfifo;            /*    32    24 */
  			unsigned int * type;             /*    32     8 */
  			const unsigned int  * const_type; /*    32     8 */
  			char *     rectype;              /*    32     8 */
  			unsigned int * ptr;              /*    32     8 */
  			const unsigned int  * ptr_const; /*    32     8 */
  		};                                       /*    32    24 */
  		unsigned int       buf[];                /*    56     0 */
  	} rawir;                                         /*    32    24 */

  	/* XXX last struct has a flexible array */

  	struct {
  		union {
  			struct __kfifo kfifo;            /*    56    24 */
  			struct lirc_scancode * type;     /*    56     8 */
  			const struct lirc_scancode  * const_type; /*    56     8 */
  			char *     rectype;              /*    56     8 */
  			struct lirc_scancode * ptr;      /*    56     8 */
  			const struct lirc_scancode  * ptr_const; /*    56     8 */
  		};                                       /*    56    24 */
  		/* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
  		struct lirc_scancode buf[];              /*    80     0 */
  	} scancodes;                                     /*    56    24 */

  	/* XXX last struct has a flexible array */

  	wait_queue_head_t          wait_poll;            /*    80    24 */
  	u8                         send_mode;            /*   104     1 */
  	u8                         rec_mode;             /*   105     1 */

  	/* size: 112, cachelines: 2, members: 8 */
  	/* sum members: 102, holes: 1, sum holes: 4 */
  	/* padding: 6 */
  	/* last cacheline: 48 bytes */
  };

Now we need to count how many embedded flexible arrays are in a struct
to print at the end stats, right before that "last cacheline:" comment
line.

Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Willy Tarreau <w@1wt.eu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 dwarves_fprintf.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c
index 94a152183b0725cf..0d642a318fd836ef 100644
--- a/dwarves_fprintf.c
+++ b/dwarves_fprintf.c
@@ -1513,7 +1513,7 @@ static size_t class__fprintf_member_type_holes(struct class *class, const struct
 	size_t printed = 0;
 	uint16_t padding;
 	uint8_t nr_holes, nr_bit_holes, bit_padding;
-	bool first = true, has_embedded_flexible_array;
+	bool first = true, has_embedded_flexible_array, has_flexible_array;
 	/*
 	 * We may not yet have looked for holes and paddings in this member's
 	 * struct type.
@@ -1525,9 +1525,10 @@ static size_t class__fprintf_member_type_holes(struct class *class, const struct
 	bit_padding = class->bit_padding;
 	nr_holes = class->nr_holes;
 	nr_bit_holes = class->nr_bit_holes;
+	has_flexible_array = class__has_flexible_array(class, cu);
 	has_embedded_flexible_array = class__has_embedded_flexible_array(class, cu);
 
-	if (!padding && !bit_padding && !nr_holes && !nr_bit_holes && !has_embedded_flexible_array)
+	if (!padding && !bit_padding && !nr_holes && !nr_bit_holes && !has_flexible_array && !has_embedded_flexible_array)
 		return 0;
 
 	if (!(*newline)++) {
@@ -1537,11 +1538,16 @@ static size_t class__fprintf_member_type_holes(struct class *class, const struct
 
 	printed += fprintf(fp, "\n%.*s/* XXX last struct has", conf->indent, tabs);
 
-	if (has_embedded_flexible_array) {
+	if (has_flexible_array) {
 		printed += fprintf(fp, " a flexible array");
 		first = false;
 	}
 
+	if (has_embedded_flexible_array) {
+		printed += fprintf(fp, "%s embedded flexible array(s)", first ? "" : ",");
+		first = false;
+	}
+
 	if (padding) {
 		++holes->nr_paddings;
 		holes->sum_paddings += padding;
-- 
2.46.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] fprintf: Show statistics about members with flexible arrays
  2024-10-08 19:52 [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Arnaldo Carvalho de Melo
  2024-10-08 19:52 ` [PATCH 1/3] fprintf: Differentiate embedded flexible arrays from flexible arrays Arnaldo Carvalho de Melo
@ 2024-10-08 19:52 ` Arnaldo Carvalho de Melo
  2024-10-08 19:52 ` [PATCH 3/3] tests: Add a test for the accounting of " Arnaldo Carvalho de Melo
  2024-10-13  9:51 ` [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Willy Tarreau
  3 siblings, 0 replies; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-10-08 19:52 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: dwarves, Alan Maguire, Jiri Olsa, Clark Williams, Kate Carcia,
	Arnaldo Carvalho de Melo, Gustavo A. R. Silva

From: Arnaldo Carvalho de Melo <acme@redhat.com>

For instance, this one has embedded flexible arrays:

  $ pahole lirc_fh
  struct lirc_fh {
  	struct list_head           list;                 /*     0    16 */
  	struct rc_dev *            rc;                   /*    16     8 */
  	int                        carrier_low;          /*    24     4 */

  	/* XXX 4 bytes hole, try to pack */

  	struct {
  		union {
  			struct __kfifo kfifo;            /*    32    24 */
  			unsigned int * type;             /*    32     8 */
  			const unsigned int  * const_type; /*    32     8 */
  			char *     rectype;              /*    32     8 */
  			unsigned int * ptr;              /*    32     8 */
  			const unsigned int  * ptr_const; /*    32     8 */
  		};                                       /*    32    24 */
  		unsigned int       buf[];                /*    56     0 */
  	} rawir;                                         /*    32    24 */

  	/* XXX last struct has a flexible array */

  	struct {
  		union {
  			struct __kfifo kfifo;            /*    56    24 */
  			struct lirc_scancode * type;     /*    56     8 */
  			const struct lirc_scancode  * const_type; /*    56     8 */
  			char *     rectype;              /*    56     8 */
  			struct lirc_scancode * ptr;      /*    56     8 */
  			const struct lirc_scancode  * ptr_const; /*    56     8 */
  		};                                       /*    56    24 */
  		/* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
  		struct lirc_scancode buf[];              /*    80     0 */
  	} scancodes;                                     /*    56    24 */

  	/* XXX last struct has a flexible array */

  	wait_queue_head_t          wait_poll;            /*    80    24 */
  	u8                         send_mode;            /*   104     1 */
  	u8                         rec_mode;             /*   105     1 */

  	/* size: 112, cachelines: 2, members: 8 */
  	/* sum members: 102, holes: 1, sum holes: 4 */
  	/* padding: 6 */
  	/* flexible array members: end: 2 */
  	/* last cacheline: 48 bytes */
  };
  $

'end' means that the members with flexible arrays have them in the
"classical" sense, i.e. the last member of those member types is a []
member.

When 'middle' appears it means another level, just like the above
'struct lirc_fh' has multiple members in its midle that are flexible
arrays.

If we use 'pahole --with_embedded_flexible_array' we'll see quite a few
in the Linux kernel (using BTF info from /sys/kernel/btf/vmlinux, mostly
available in most kernels these days), using --sizes so that we get just
one line per Linux kernel struct that have embedded flexible arrays (and
its sizes and number of alignment holes, as bonuses):

  $ pahole --sizes --with_embedded_flexible_array | head
  mem_cgroup	2240	10
  pglist_data	175424	7
  zone	1728	5
  cgroup	1984	3
  cgroup_root	6272	1
  page_counter	192	1
  cpu_hw_events	5200	6
  crypto_shash	40	1
  crypto_aead	40	0
  crypto_ahash	48	2
  $

  $ pahole crypto_shash
  struct crypto_shash {
  	unsigned int               descsize;             /*     0     4 */

  	/* XXX 4 bytes hole, try to pack */

  	struct crypto_tfm          base;                 /*     8    32 */

  	/* XXX last struct has a flexible array, 1 hole */

  	/* size: 40, cachelines: 1, members: 2 */
  	/* sum members: 36, holes: 1, sum holes: 4 */
  	/* member types with holes: 1, total: 1 */
  	/* flexible array members: end: 1 */
  	/* last cacheline: 40 bytes */
  };
  $

If we expand it all:

  $ pahole -E crypto_shash
  struct crypto_shash {
  	unsigned int               descsize;                                             /*     0     4 */

  	/* XXX 4 bytes hole, try to pack */

  	struct crypto_tfm {
  		/* typedef refcount_t */ struct refcount_struct {
  			/* typedef atomic_t */ struct {
  				int counter;                                             /*     8     4 */
  			} refs; /*     8     4 */
  		} refcnt; /*     8     4 */
  		/* typedef u32 -> __u32 */ unsigned int       crt_flags;                 /*    12     4 */
  		int                node;                                                 /*    16     4 */

  		/* XXX 4 bytes hole, try to pack */

  		void               (*exit)(struct crypto_tfm *);                         /*    24     8 */
  		struct crypto_alg * __crt_alg;                                           /*    32     8 */
  		void *             __crt_ctx[];                                          /*    40     0 */
  	} base; /*     8    32 */

  	/* XXX last struct has a flexible array, 1 hole */

  	/* size: 40, cachelines: 1, members: 2 */
  	/* sum members: 36, holes: 1, sum holes: 4 */
  	/* member types with holes: 1, total: 1 */
  	/* flexible array members: end: 1 */
  	/* last cacheline: 40 bytes */
  };
  $

Interesting, but we don't see the "middle" case...

Maybe 'struct cgroup'?

  $ pahole cgroup | tail
  	struct cgroup *            ancestors[];          /*  1984     0 */

  	/* size: 1984, cachelines: 31, members: 42 */
  	/* sum members: 1952, holes: 3, sum holes: 32 */
  	/* member types with holes: 3, total: 3 */
  	/* paddings: 1, sum paddings: 4 */
  	/* forced alignments: 1 */
  	/* flexible array members: end: 1 */
  };

  $

Humm, maybe some data structure embeds 'struct cgroup'? Lets see with:

  $ pahole --contains cgroup
  cgroup_root
  $

A-ha, finally that 'middle' stat:

  $ pahole cgroup_root
  struct cgroup_root {
  	struct kernfs_root *       kf_root;              /*     0     8 */
  	unsigned int               subsys_mask;          /*     8     4 */
  	int                        hierarchy_id;         /*    12     4 */
  	struct list_head           root_list;            /*    16    16 */
  	struct callback_head       rcu;                  /*    32    16 */

  	/* XXX 16 bytes hole, try to pack */

  	/* --- cacheline 1 boundary (64 bytes) --- */
  	struct cgroup              cgrp __attribute__((__aligned__(64))); /*    64  1984 */

  	/* XXX last struct has a flexible array, embedded flexible array(s), 3 holes */

  	/* --- cacheline 32 boundary (2048 bytes) --- */
  	struct cgroup *            cgrp_ancestor_storage; /*  2048     8 */
  	atomic_t                   nr_cgrps;             /*  2056     4 */
  	unsigned int               flags;                /*  2060     4 */
  	char                       release_agent_path[4096]; /*  2064  4096 */
  	/* --- cacheline 96 boundary (6144 bytes) was 16 bytes ago --- */
  	char                       name[64];             /*  6160    64 */

  	/* size: 6272, cachelines: 98, members: 11 */
  	/* sum members: 6208, holes: 1, sum holes: 16 */
  	/* padding: 48 */
  	/* member types with holes: 1, total: 3 */
  	/* forced alignments: 1, forced holes: 1, sum forced holes: 16 */
  	/* flexible array members: end: 1, middle: 1 */
  } __attribute__((__aligned__(64)));
  $

Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Willy Tarreau <w@1wt.eu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 dwarves_fprintf.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c
index 0d642a318fd836ef..e16a6b4da65ed2cd 100644
--- a/dwarves_fprintf.c
+++ b/dwarves_fprintf.c
@@ -1502,6 +1502,8 @@ struct member_types_holes {
 	uint16_t nr_with_bit_holes;
 	uint16_t total_nr_holes;
 	uint16_t total_nr_bit_holes;
+	uint16_t nr_flexible_array_members;
+	uint16_t nr_embedded_flexible_array_members;
 	uint32_t sum_paddings;
 	uint32_t sum_bit_paddings;
 };
@@ -1540,11 +1542,13 @@ static size_t class__fprintf_member_type_holes(struct class *class, const struct
 
 	if (has_flexible_array) {
 		printed += fprintf(fp, " a flexible array");
+		++holes->nr_flexible_array_members;
 		first = false;
 	}
 
 	if (has_embedded_flexible_array) {
 		printed += fprintf(fp, "%s embedded flexible array(s)", first ? "" : ",");
+		++holes->nr_embedded_flexible_array_members;
 		first = false;
 	}
 
@@ -1985,6 +1989,22 @@ next_member:
 		}
 		printed += fprintf(fp, " */\n");
 	}
+	if (member_types_holes.nr_flexible_array_members > 0 ||
+	    member_types_holes.nr_embedded_flexible_array_members > 0) {
+		printed += fprintf(fp, "%.*s/* flexible array members: ",
+				   cconf.indent, tabs);
+
+		if (member_types_holes.nr_flexible_array_members > 0)
+			printed += fprintf(fp, "end: %u", member_types_holes.nr_flexible_array_members);
+
+		if (member_types_holes.nr_embedded_flexible_array_members > 0) {
+			printed += fprintf(fp, "%smiddle: %u",
+					   member_types_holes.nr_flexible_array_members ? ", " : "",
+					   member_types_holes.nr_embedded_flexible_array_members);
+		}
+
+		printed += fprintf(fp, " */\n");
+	}
 	cacheline = (cconf.base_offset + type->size) % conf_fprintf__cacheline_size(conf);
 	if (cacheline != 0)
 		printed += fprintf(fp, "%.*s/* last cacheline: %u bytes */\n",
-- 
2.46.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] tests: Add a test for the accounting of flexible arrays
  2024-10-08 19:52 [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Arnaldo Carvalho de Melo
  2024-10-08 19:52 ` [PATCH 1/3] fprintf: Differentiate embedded flexible arrays from flexible arrays Arnaldo Carvalho de Melo
  2024-10-08 19:52 ` [PATCH 2/3] fprintf: Show statistics about members with " Arnaldo Carvalho de Melo
@ 2024-10-08 19:52 ` Arnaldo Carvalho de Melo
  2024-10-13  9:51 ` [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Willy Tarreau
  3 siblings, 0 replies; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-10-08 19:52 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: dwarves, Alan Maguire, Jiri Olsa, Clark Williams, Kate Carcia,
	Arnaldo Carvalho de Melo, Gustavo A. R. Silva

From: Arnaldo Carvalho de Melo <acme@redhat.com>

  acme@x1:~/git/pahole$ tests/flexible_arrays.sh
  Flexible arrays accounting: Ok
  acme@x1:~/git/pahole$ VERBOSE=1 tests/flexible_arrays.sh
  Flexible arrays accounting: end: mem_cgroup: 2 2
  middle: mem_cgroup: 3 3
  end: pglist_data: 2 2
  middle: pglist_data: 0 0
  end: zone: 3 3
  middle: zone: 0 0
  end: cgroup: 1 1
  middle: cgroup: 0 0
  end: cgroup_root: 1 1
  middle: cgroup_root: 1 1
  end: page_counter: 2 2
  middle: page_counter: 0 0
  end: cpu_hw_events: 1 1
  middle: cpu_hw_events: 0 0
  end: crypto_shash: 1 1
  middle: crypto_shash: 0 0
  end: crypto_aead: 1 1
  middle: crypto_aead: 0 0
  end: crypto_ahash: 1 1
  middle: crypto_ahash: 0 0
  end: crypto_skcipher: 1 1
  middle: crypto_skcipher: 0 0
  end: crypto_sync_skcipher: 0 0
  middle: crypto_sync_skcipher: 1 1
  <SNIP>
  end: bpf_ctx_convert: 2 2
  middle: bpf_ctx_convert: 0 0
  Ok
  acme@x1:~/git/pahole$

Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Willy Tarreau <w@1wt.eu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tests/flexible_arrays.sh | 77 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100755 tests/flexible_arrays.sh

diff --git a/tests/flexible_arrays.sh b/tests/flexible_arrays.sh
new file mode 100755
index 0000000000000000..7c21253a7e08c9d3
--- /dev/null
+++ b/tests/flexible_arrays.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Match flexible array member info with the per struct final stats.
+#
+# Arnaldo Carvalho de Melo <acme@redhat.com> (C) 2024-
+
+vmlinux=${vmlinux:-$1}
+
+if [ -z "$vmlinux" ] ; then
+	vmlinux=$(pahole --running_kernel_vmlinux)
+fi
+
+if [ ! -f "$vmlinux" ] ; then
+	echo "$vmlinux file not available, please specify another"
+	exit 2
+fi
+
+pretty=$(mktemp /tmp/flexible_arrays.data.sh.XXXXXX.c)
+
+echo -n "Flexible arrays accounting: "
+
+for struct in $(pahole -F btf --sizes --with_embedded_flexible_array $vmlinux | cut -f1) ; do
+	pahole $struct > $pretty
+
+	# We need to check for just one tab before the comment as when expanding unnamed
+	# structs with members with flexible arrays inside another struct we would mess
+	# up the accounting, see 'pahole fanotify_fid_event' for instance, circa October 2024:
+	# $ pahole fanotify_fid_event
+	# struct fanotify_fid_event {
+	#	struct fanotify_event      fae;                  /*     0    48 */
+	#	__kernel_fsid_t            fsid;                 /*    48     8 */
+	#	struct {
+	#		struct fanotify_fh object_fh;            /*    56     4 */
+	#		/* XXX last struct has a flexible array */
+	#		unsigned char      _inline_fh_buf[12];   /*    60    12 */
+	#	};                                               /*    56    16 */
+
+	#	/* XXX last struct has embedded flexible array(s) */
+	#	/* size: 72, cachelines: 2, members: 3 */
+	#	/* flexible array members: middle: 1 */
+	#	/* last cacheline: 8 bytes */
+	# }
+
+	nr_flexible_arrays=$(grep $'^\t/\* XXX last struct has a flexible array' $pretty | wc -l)
+	nr_embedded_flexible_arrays=$(grep $'^\t/\* XXX last struct.*embedded flexible array' $pretty | wc -l)
+	stat_nr_flexible_arrays=$(grep "flexible array members:.*end:" $pretty | sed -r 's/.*end: *([[:digit:]]+).*/\1/g')
+	[ -z "$stat_nr_flexible_arrays" ] && stat_nr_flexible_arrays=0
+	stat_nr_embedded_flexible_arrays=$(grep "flexible array members:.*middle:" $pretty | sed -r 's/.*middle: *([[:digit:]]+).*/\1/g')
+	[ -z "$stat_nr_embedded_flexible_arrays" ] && stat_nr_embedded_flexible_arrays=0
+	test -n "$VERBOSE" && echo "end: $struct: $nr_flexible_arrays $stat_nr_flexible_arrays"
+	test -n "$VERBOSE" && echo "middle: $struct: $nr_embedded_flexible_arrays $stat_nr_embedded_flexible_arrays"
+
+	if [ "$nr_embedded_flexible_arrays" != "$stat_nr_embedded_flexible_arrays" ] ; then
+		test -n "$VERBOSE" && printf "struct %s: The number of embedded flexible arrays (%s) doesn't match the number of members marked as such (%s)\n" \
+			"$struct" "$stat_nr_embedded_flexible_arrays" "$nr_embedded_flexible_arrays"
+		test -n "$VERBOSE" && pahole $struct
+		FAILED=1
+	fi
+
+	if [ "$nr_flexible_arrays" != "$stat_nr_flexible_arrays" ] ; then
+		test -n "$VERBOSE" && printf "struct %s: The number of flexible arrays (%s) doesn't match the number of members marked as such (%s)\n" \
+			"$struct" "$stat_nr_flexible_arrays" "$nr_flexible_arrays"
+		test -n "$VERBOSE" && pahole $struct
+		FAILED=1
+	fi
+
+	rm -f $pretty
+done
+
+if [ -n "$FAILED" ] ; then
+	echo "FAILED"
+	exit 1
+fi
+
+echo "Ok"
+exit 0
-- 
2.46.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones
  2024-10-08 19:52 [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Arnaldo Carvalho de Melo
                   ` (2 preceding siblings ...)
  2024-10-08 19:52 ` [PATCH 3/3] tests: Add a test for the accounting of " Arnaldo Carvalho de Melo
@ 2024-10-13  9:51 ` Willy Tarreau
  3 siblings, 0 replies; 5+ messages in thread
From: Willy Tarreau @ 2024-10-13  9:51 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: dwarves, Alan Maguire, Jiri Olsa, Clark Williams, Kate Carcia,
	Arnaldo Carvalho de Melo, Gustavo A. R. Silva

Hi Arnaldo,

On Tue, Oct 08, 2024 at 04:52:06PM -0300, Arnaldo Carvalho de Melo wrote:
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> Hi Willy, Gustavo,
> 
> 	Now it has even a regression test, this now have what I think is
> needed, take a look at the output of:
> 
>    pahole --with_embedded_flexible_arrays > \
> 	 http://vger.kernel.org/~acme/pahole--with_embedded_flexible_array-6.10.11-200.fc40.x86_64.c

First, thanks for this great work! Please note that above it's
"--with_embedded_flexible_array" (without the trailing 's').

I'm seeing that it seems to catch entries added for padding as well:

  struct mem_cgroup {
  ...
        long unsigned int          move_lock_flags;      /*  1480     8 */

        /* XXX 48 bytes hole, try to pack */

        /* --- cacheline 24 boundary (1536 bytes) --- */
        struct cacheline_padding   _pad1_;               /*  1536     0 */

        /* XXX last struct has a flexible array */

I think that we could avoid emitting it if the entire struct or union is
of size zero, as I don't think we'd be using variable length arrays in
a structure of a single field which is that one anyway.

I also tried to catch this case that we discussed about, which is almost
always wrong: fma at the end of a struct, followed by padding in the
container struct, suggesting that the caller meant for the fma to map
to the next field and failed. But it didn't match it when combined
with "--padding_ge 1".

  $ cat pad1.c
  struct foo {
          void *ptr;
          int number;
          char array[];
  } foo;
  
  struct bar {
          int number;
          struct foo foo;
          char storage[16];
  } bar;
  
  int main(void)
  {
          return 0;
  }

  $ gcc -g pad1.c
  $ ../pahole/build/pahole --with_embedded_flexible_array --padding_ge 1 -E ./a.out 
  $
  $ ../pahole/build/pahole --with_embedded_flexible_array -E ./a.out 
  struct bar {
          int                        number;                                               /*     0     4 */
  
          /* XXX 4 bytes hole, try to pack */
  
          struct foo {
                  void *             ptr;                                                  /*     8     8 */
                  int                number;                                               /*    16     4 */
                  char               array[];                                              /*    20     0 */
          } foo; /*     8    16 */
  
          /* XXX last struct has a flexible array, 4 bytes of padding */
  
          char                       storage[16];                                          /*    24    16 */
  
          /* size: 40, cachelines: 1, members: 3 */
          /* sum members: 36, holes: 1, sum holes: 4 */
          /* paddings: 1, sum paddings: 4 */
          /* flexible array members: end: 1 */
          /* last cacheline: 40 bytes */
  };

I think I can reliably spot it by grepping for 'flexible.*padding' but
that removes some of its beauty and efficiency :-)

Maybe it's a different case and it would need a different option, such
as --with_padded_embedded_flexible_array ?

> And go on searching for 'flexible' :-)

Regardless of the status of the points above, that's still really awesome
and an amazing time-saver! Thanks a lot!

> 	Now I'm flexibly moving to other final issues to release pahole 1.28.

Since you're speaking about final issues, I noticed this:
  - forgetting to pass -g to gcc yields:

    $ ../pahole/build/pahole --with_embedded_flexible_array -E ./a.out
    libbpf: failed to find '.BTF' ELF section in ./a.out
    pahole: file './a.out' has no supported type information.

    For me that was not clear, I thought I faced an incompatibility
    related to bpf or something, plus my working binaries don't seem
    to have such a '.BTF' section either. Maybe just asking "were debug
    symbols omitted?" would be clearer.

  - on my laptop, starting 'pahole' segfaults. I traced it to trying to
    open(NULL) after failing to find vmlinux:

    $ strace ./build/pahole
    ...
    access("/sys/kernel/btf/vmlinux", R_OK) = -1 ENOENT (No such file or directory)
    uname({sysname="Linux", nodename="wtap.local", ...}) = 0
    openat(AT_FDCWD, "/sys/kernel/notes", O_RDONLY) = 3
    read(3, "\4\0\0\0\24\0\0\0\3\0\0\0", 12) = 12
    read(3, "GNU\0", 4)                     = 4
    read(3, "\350N\202\23\31g9\302VB(\17u\251\245\"O Xq", 20) = 20
    close(3)                                = 0
    openat(AT_FDCWD, "vmlinux", O_RDONLY)   = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/boot/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/boot/vmlinux-6.1.91", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.1.91", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/modules/6.1.91/build/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/debug/lib/modules/6.1.91/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.1.91.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, NULL, O_RDONLY)        = -1 EFAULT (Bad address)
    --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
    +++ killed by SIGSEGV +++

    I've bisected it to this recent commit:

      commit c08046f98a3f84881133f9172f6bb417add61879
      Author: Arnaldo Carvalho de Melo <acme@redhat.com>
      Date:   Wed Aug 28 16:19:17 2024 -0300

          core: Add function to return the path to the running kernel vmlinux

Hoping this helps!
Willy

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-10-13 10:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-08 19:52 [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Arnaldo Carvalho de Melo
2024-10-08 19:52 ` [PATCH 1/3] fprintf: Differentiate embedded flexible arrays from flexible arrays Arnaldo Carvalho de Melo
2024-10-08 19:52 ` [PATCH 2/3] fprintf: Show statistics about members with " Arnaldo Carvalho de Melo
2024-10-08 19:52 ` [PATCH 3/3] tests: Add a test for the accounting of " Arnaldo Carvalho de Melo
2024-10-13  9:51 ` [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones Willy Tarreau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox