BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability
@ 2024-09-06 13:24 Mykyta Yatsenko
  2024-09-06 19:56 ` Eduard Zingerman
  2024-09-06 21:11 ` patchwork-bot+netdevbpf
  0 siblings, 2 replies; 5+ messages in thread
From: Mykyta Yatsenko @ 2024-09-06 13:24 UTC (permalink / raw)
  To: bpf, ast, andrii, daniel, kafai, kernel-team; +Cc: Mykyta Yatsenko

From: Mykyta Yatsenko <yatsenko@meta.com>

Existing algorithm for BTF C dump sorting uses only types and names of
the structs and unions for ordering. As dump contains structs with the
same names but different contents, relative to each other ordering of
those structs will be accidental.
This patch addresses this problem by introducing a new sorting field
that contains hash of the struct/union field names and types to
disambiguate comparison of the non-unique named structs.

Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
---
 tools/bpf/bpftool/btf.c | 80 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 75 insertions(+), 5 deletions(-)

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index 3b57ba095ab6..7d2af1ff3c8d 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -50,6 +50,7 @@ struct sort_datum {
 	int type_rank;
 	const char *sort_name;
 	const char *own_name;
+	__u64 disambig_hash;
 };
 
 static const char *btf_int_enc_str(__u8 encoding)
@@ -584,20 +585,88 @@ static const char *btf_type_sort_name(const struct btf *btf, __u32 index, bool f
 	return NULL;
 }
 
+static __u64 hasher(__u64 hash, __u64 val)
+{
+	return hash * 31 + val;
+}
+
+static __u64 btf_name_hasher(__u64 hash, const struct btf *btf, __u32 name_off)
+{
+	if (!name_off)
+		return hash;
+
+	return hasher(hash, str_hash(btf__name_by_offset(btf, name_off)));
+}
+
+static __u64 btf_type_disambig_hash(const struct btf *btf, __u32 id, bool include_members)
+{
+	const struct btf_type *t = btf__type_by_id(btf, id);
+	int i;
+	size_t hash = 0;
+
+	hash = btf_name_hasher(hash, btf, t->name_off);
+
+	switch (btf_kind(t)) {
+	case BTF_KIND_ENUM:
+	case BTF_KIND_ENUM64:
+		for (i = 0; i < btf_vlen(t); i++) {
+			__u32 name_off = btf_is_enum(t) ?
+				btf_enum(t)[i].name_off :
+				btf_enum64(t)[i].name_off;
+
+			hash = btf_name_hasher(hash, btf, name_off);
+		}
+		break;
+	case BTF_KIND_STRUCT:
+	case BTF_KIND_UNION:
+		if (!include_members)
+			break;
+		for (i = 0; i < btf_vlen(t); i++) {
+			const struct btf_member *m = btf_members(t) + i;
+
+			hash = btf_name_hasher(hash, btf, m->name_off);
+			/* resolve field type's name and hash it as well */
+			hash = hasher(hash, btf_type_disambig_hash(btf, m->type, false));
+		}
+		break;
+	case BTF_KIND_TYPE_TAG:
+	case BTF_KIND_CONST:
+	case BTF_KIND_PTR:
+	case BTF_KIND_VOLATILE:
+	case BTF_KIND_RESTRICT:
+	case BTF_KIND_TYPEDEF:
+	case BTF_KIND_DECL_TAG:
+		hash = hasher(hash, btf_type_disambig_hash(btf, t->type, include_members));
+		break;
+	case BTF_KIND_ARRAY: {
+		struct btf_array *arr = btf_array(t);
+
+		hash = hasher(hash, arr->nelems);
+		hash = hasher(hash, btf_type_disambig_hash(btf, arr->type, include_members));
+		break;
+	}
+	default:
+		break;
+	}
+	return hash;
+}
+
 static int btf_type_compare(const void *left, const void *right)
 {
 	const struct sort_datum *d1 = (const struct sort_datum *)left;
 	const struct sort_datum *d2 = (const struct sort_datum *)right;
 	int r;
 
-	if (d1->type_rank != d2->type_rank)
-		return d1->type_rank < d2->type_rank ? -1 : 1;
-
-	r = strcmp(d1->sort_name, d2->sort_name);
+	r = d1->type_rank - d2->type_rank;
+	r = r ?: strcmp(d1->sort_name, d2->sort_name);
+	r = r ?: strcmp(d1->own_name, d2->own_name);
 	if (r)
 		return r;
 
-	return strcmp(d1->own_name, d2->own_name);
+	if (d1->disambig_hash != d2->disambig_hash)
+		return d1->disambig_hash < d2->disambig_hash ? -1 : 1;
+
+	return d1->index - d2->index;
 }
 
 static struct sort_datum *sort_btf_c(const struct btf *btf)
@@ -618,6 +687,7 @@ static struct sort_datum *sort_btf_c(const struct btf *btf)
 		d->type_rank = btf_type_rank(btf, i, false);
 		d->sort_name = btf_type_sort_name(btf, i, false);
 		d->own_name = btf__name_by_offset(btf, t->name_off);
+		d->disambig_hash = btf_type_disambig_hash(btf, i, true);
 	}
 
 	qsort(datums, n, sizeof(struct sort_datum), btf_type_compare);
-- 
2.46.0


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

* Re: [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability
  2024-09-06 13:24 [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability Mykyta Yatsenko
@ 2024-09-06 19:56 ` Eduard Zingerman
  2024-09-06 21:07   ` Andrii Nakryiko
  2024-09-06 22:00   ` Mykyta Yatsenko
  2024-09-06 21:11 ` patchwork-bot+netdevbpf
  1 sibling, 2 replies; 5+ messages in thread
From: Eduard Zingerman @ 2024-09-06 19:56 UTC (permalink / raw)
  To: Mykyta Yatsenko, bpf, ast, andrii, daniel, kafai, kernel-team
  Cc: Mykyta Yatsenko

On Fri, 2024-09-06 at 14:24 +0100, Mykyta Yatsenko wrote:
> From: Mykyta Yatsenko <yatsenko@meta.com>
> 
> Existing algorithm for BTF C dump sorting uses only types and names of
> the structs and unions for ordering. As dump contains structs with the
> same names but different contents, relative to each other ordering of
> those structs will be accidental.
> This patch addresses this problem by introducing a new sorting field
> that contains hash of the struct/union field names and types to
> disambiguate comparison of the non-unique named structs.
> 
> Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
> ---

Note, this is still not fully stable, e.g.:

$ for i in $(seq 1 10); \
  do touch ./kernel/bpf/verifier.c && \
     ccache-kernel-make.sh -j23 && \
     ./tools/bpf/bpftool/bpftool btf dump file vmlinux format c > ~/work/tmp/vmlinux.h.$i; \
  done
  ...
$ md5sum ~/work/tmp/vmlinux.h.* | sort -k1
76c9b22274c4aa6253ffaafa33ceffd3  /home/eddy/work/tmp/vmlinux.h.2
76c9b22274c4aa6253ffaafa33ceffd3  /home/eddy/work/tmp/vmlinux.h.4
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.1
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.10
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.3
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.5
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.6
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.7
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.8
a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.9

[...]


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

* Re: [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability
  2024-09-06 19:56 ` Eduard Zingerman
@ 2024-09-06 21:07   ` Andrii Nakryiko
  2024-09-06 22:00   ` Mykyta Yatsenko
  1 sibling, 0 replies; 5+ messages in thread
From: Andrii Nakryiko @ 2024-09-06 21:07 UTC (permalink / raw)
  To: Eduard Zingerman
  Cc: Mykyta Yatsenko, bpf, ast, andrii, daniel, kafai, kernel-team,
	Mykyta Yatsenko

On Fri, Sep 6, 2024 at 12:56 PM Eduard Zingerman <eddyz87@gmail.com> wrote:
>
> On Fri, 2024-09-06 at 14:24 +0100, Mykyta Yatsenko wrote:
> > From: Mykyta Yatsenko <yatsenko@meta.com>
> >
> > Existing algorithm for BTF C dump sorting uses only types and names of
> > the structs and unions for ordering. As dump contains structs with the
> > same names but different contents, relative to each other ordering of
> > those structs will be accidental.
> > This patch addresses this problem by introducing a new sorting field
> > that contains hash of the struct/union field names and types to
> > disambiguate comparison of the non-unique named structs.
> >
> > Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
> > ---
>
> Note, this is still not fully stable, e.g.:
>
> $ for i in $(seq 1 10); \
>   do touch ./kernel/bpf/verifier.c && \
>      ccache-kernel-make.sh -j23 && \
>      ./tools/bpf/bpftool/bpftool btf dump file vmlinux format c > ~/work/tmp/vmlinux.h.$i; \
>   done
>   ...
> $ md5sum ~/work/tmp/vmlinux.h.* | sort -k1
> 76c9b22274c4aa6253ffaafa33ceffd3  /home/eddy/work/tmp/vmlinux.h.2
> 76c9b22274c4aa6253ffaafa33ceffd3  /home/eddy/work/tmp/vmlinux.h.4
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.1
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.10
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.3
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.5
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.6
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.7
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.8
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.9

Still, quite stable, compared to what it is right now. I think the
second part is more consistent ordering between CUs inside the pahole
to keep it even more stable.

Applied to bpf-next, thanks!

>
> [...]
>

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

* Re: [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability
  2024-09-06 13:24 [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability Mykyta Yatsenko
  2024-09-06 19:56 ` Eduard Zingerman
@ 2024-09-06 21:11 ` patchwork-bot+netdevbpf
  1 sibling, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-09-06 21:11 UTC (permalink / raw)
  To: Mykyta Yatsenko; +Cc: bpf, ast, andrii, daniel, kafai, kernel-team, yatsenko

Hello:

This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <andrii@kernel.org>:

On Fri,  6 Sep 2024 14:24:53 +0100 you wrote:
> From: Mykyta Yatsenko <yatsenko@meta.com>
> 
> Existing algorithm for BTF C dump sorting uses only types and names of
> the structs and unions for ordering. As dump contains structs with the
> same names but different contents, relative to each other ordering of
> those structs will be accidental.
> This patch addresses this problem by introducing a new sorting field
> that contains hash of the struct/union field names and types to
> disambiguate comparison of the non-unique named structs.
> 
> [...]

Here is the summary with links:
  - [bpf-next,v2] bpftool: improve btf c dump sorting stability
    https://git.kernel.org/bpf/bpf-next/c/f8c6b7913dfa

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

* Re: [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability
  2024-09-06 19:56 ` Eduard Zingerman
  2024-09-06 21:07   ` Andrii Nakryiko
@ 2024-09-06 22:00   ` Mykyta Yatsenko
  1 sibling, 0 replies; 5+ messages in thread
From: Mykyta Yatsenko @ 2024-09-06 22:00 UTC (permalink / raw)
  To: Eduard Zingerman, bpf, ast, andrii, daniel, kafai, kernel-team
  Cc: Mykyta Yatsenko

On 06/09/2024 20:56, Eduard Zingerman wrote:
> On Fri, 2024-09-06 at 14:24 +0100, Mykyta Yatsenko wrote:
>> From: Mykyta Yatsenko <yatsenko@meta.com>
>>
>> Existing algorithm for BTF C dump sorting uses only types and names of
>> the structs and unions for ordering. As dump contains structs with the
>> same names but different contents, relative to each other ordering of
>> those structs will be accidental.
>> This patch addresses this problem by introducing a new sorting field
>> that contains hash of the struct/union field names and types to
>> disambiguate comparison of the non-unique named structs.
>>
>> Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
>> ---
> Note, this is still not fully stable, e.g.:
>
> $ for i in $(seq 1 10); \
>    do touch ./kernel/bpf/verifier.c && \
>       ccache-kernel-make.sh -j23 && \
>       ./tools/bpf/bpftool/bpftool btf dump file vmlinux format c > ~/work/tmp/vmlinux.h.$i; \
>    done
>    ...
> $ md5sum ~/work/tmp/vmlinux.h.* | sort -k1
> 76c9b22274c4aa6253ffaafa33ceffd3  /home/eddy/work/tmp/vmlinux.h.2
> 76c9b22274c4aa6253ffaafa33ceffd3  /home/eddy/work/tmp/vmlinux.h.4
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.1
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.10
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.3
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.5
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.6
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.7
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.8
> a1c90a62e6cca59869a9cdffbaa3c4de  /home/eddy/work/tmp/vmlinux.h.9
>
> [...]
>
Interesting, thanks for showing this, I'll try to replicate this test.



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

end of thread, other threads:[~2024-09-06 22:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-06 13:24 [PATCH bpf-next v2] bpftool: improve btf c dump sorting stability Mykyta Yatsenko
2024-09-06 19:56 ` Eduard Zingerman
2024-09-06 21:07   ` Andrii Nakryiko
2024-09-06 22:00   ` Mykyta Yatsenko
2024-09-06 21:11 ` patchwork-bot+netdevbpf

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