libbpf: Walk types in btf_dump_resize(), not in mark_referenced()

btf_dump_mark_referenced() both walks every type added since the last
resize and decides what each one references. Move the walk out to
btf_dump_resize() and hand the function one type at a time, so a second
per-type job can share the same pass instead of adding another one.

No functional change.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://patch.msgid.link/20260929234608.48503-2-ihor.solodrai@linux.dev
This commit is contained in:
Ihor Solodrai authored and Andrii Nakryiko committed 2026-10-02 05:41:50 -07:00
1 parent 28826c4922
commit 04312c5dfc
1 file changed
+60 -62
+60 -62
View File
@@ -143,7 +143,7 @@ static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
va_end(args); va_end(args);
} }
static int btf_dump_mark_referenced(struct btf_dump *d); static int btf_dump_mark_referenced(struct btf_dump *d, const struct btf_type *t);
static int btf_dump_resize(struct btf_dump *d); static int btf_dump_resize(struct btf_dump *d);
struct btf_dump *btf_dump__new(const struct btf *btf, struct btf_dump *btf_dump__new(const struct btf *btf,
@@ -195,6 +195,8 @@ err:
static int btf_dump_resize(struct btf_dump *d) static int btf_dump_resize(struct btf_dump *d)
{ {
int err, last_id = btf__type_cnt(d->btf) - 1; int err, last_id = btf__type_cnt(d->btf) - 1;
const struct btf_type *t;
__u32 i;
if (last_id <= d->last_id) if (last_id <= d->last_id)
return 0; return 0;
@@ -212,10 +214,13 @@ static int btf_dump_resize(struct btf_dump *d)
d->type_states[0].emit_state = EMITTED; d->type_states[0].emit_state = EMITTED;
} }
/* eagerly determine referenced types for anon enums */ for (i = d->last_id + 1; i <= last_id; i++) {
err = btf_dump_mark_referenced(d); t = btf__type_by_id(d->btf, i);
if (err)
return err; err = btf_dump_mark_referenced(d, t);
if (err)
return err;
}
d->last_id = last_id; d->last_id = last_id;
return 0; return 0;
@@ -312,71 +317,64 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
* top-level anonymous enum won't be referenced by anything, while embedded * top-level anonymous enum won't be referenced by anything, while embedded
* one will. * one will.
*/ */
static int btf_dump_mark_referenced(struct btf_dump *d) static int btf_dump_mark_referenced(struct btf_dump *d, const struct btf_type *t)
{ {
int i, j, n = btf__type_cnt(d->btf); __u32 j, vlen = btf_vlen(t);
const struct btf_type *t;
__u32 vlen;
for (i = d->last_id + 1; i < n; i++) { switch (btf_kind(t)) {
t = btf__type_by_id(d->btf, i); case BTF_KIND_INT:
vlen = btf_vlen(t); case BTF_KIND_ENUM:
case BTF_KIND_ENUM64:
case BTF_KIND_FWD:
case BTF_KIND_FLOAT:
case BTF_KIND_LOC_PARAM:
case BTF_KIND_LOC_PROTO:
case BTF_KIND_LOCSEC:
break;
switch (btf_kind(t)) { case BTF_KIND_VOLATILE:
case BTF_KIND_INT: case BTF_KIND_CONST:
case BTF_KIND_ENUM: case BTF_KIND_RESTRICT:
case BTF_KIND_ENUM64: case BTF_KIND_PTR:
case BTF_KIND_FWD: case BTF_KIND_TYPEDEF:
case BTF_KIND_FLOAT: case BTF_KIND_FUNC:
case BTF_KIND_LOC_PARAM: case BTF_KIND_VAR:
case BTF_KIND_LOC_PROTO: case BTF_KIND_DECL_TAG:
case BTF_KIND_LOCSEC: case BTF_KIND_TYPE_TAG:
break; d->type_states[t->type].referenced = 1;
break;
case BTF_KIND_VOLATILE: case BTF_KIND_ARRAY: {
case BTF_KIND_CONST: const struct btf_array *a = btf_array(t);
case BTF_KIND_RESTRICT:
case BTF_KIND_PTR:
case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC:
case BTF_KIND_VAR:
case BTF_KIND_DECL_TAG:
case BTF_KIND_TYPE_TAG:
d->type_states[t->type].referenced = 1;
break;
case BTF_KIND_ARRAY: { d->type_states[a->index_type].referenced = 1;
const struct btf_array *a = btf_array(t); d->type_states[a->type].referenced = 1;
break;
}
case BTF_KIND_STRUCT:
case BTF_KIND_UNION: {
const struct btf_member *m = btf_members(t);
d->type_states[a->index_type].referenced = 1; for (j = 0; j < vlen; j++, m++)
d->type_states[a->type].referenced = 1; d->type_states[m->type].referenced = 1;
break; break;
} }
case BTF_KIND_STRUCT: case BTF_KIND_FUNC_PROTO: {
case BTF_KIND_UNION: { const struct btf_param *p = btf_params(t);
const struct btf_member *m = btf_members(t);
for (j = 0; j < vlen; j++, m++) for (j = 0; j < vlen; j++, p++)
d->type_states[m->type].referenced = 1; d->type_states[p->type].referenced = 1;
break; break;
} }
case BTF_KIND_FUNC_PROTO: { case BTF_KIND_DATASEC: {
const struct btf_param *p = btf_params(t); const struct btf_var_secinfo *v = btf_var_secinfos(t);
for (j = 0; j < vlen; j++, p++) for (j = 0; j < vlen; j++, v++)
d->type_states[p->type].referenced = 1; d->type_states[v->type].referenced = 1;
break; break;
} }
case BTF_KIND_DATASEC: { default:
const struct btf_var_secinfo *v = btf_var_secinfos(t); return -EINVAL;
for (j = 0; j < vlen; j++, v++)
d->type_states[v->type].referenced = 1;
break;
}
default:
return -EINVAL;
}
} }
return 0; return 0;
} }