From patchwork Mon Jul 8 20:45:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13727028 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 102C63FB1B for ; Mon, 8 Jul 2024 20:45:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720471548; cv=none; b=P0y1vg6/1bXZ8QG9FBfa4HwbUXuqNbhrk4wYQA+/Om1u2ygI6PdX7MefXcJ5LuWCtws2uSfjl1sUIsglogdGO3cnyP1RBGbPlz5Eh08nlIDiFn4cky7lnq7c3PzPZ6BhWUeXlq5pkjSWypxjU5TC2+f02OkMwyvBRWpkY6zY+xw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720471548; c=relaxed/simple; bh=x/+dExcmX8BFSpzbOz9ODe0jj/TCko7R1W/c7xC5u0Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hRAW0BpPyqlUbZxZ/ZjdF/17+vaJGmF/8gG7JrNPEtqpE51uyLp6JztyG5zeSTB79y11kLiqaKJxd1ThsTuJ5YmddHC7pGGGSk3nTZK5JXULbuii2b2ElKLXqaKwGS52Oej/fJ48sIW3V571pJGzZC9dzsVgi55McboT0AX+bEc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NOldL94h; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NOldL94h" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 72418C116B1; Mon, 8 Jul 2024 20:45:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1720471547; bh=x/+dExcmX8BFSpzbOz9ODe0jj/TCko7R1W/c7xC5u0Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NOldL94hO96WhGxyYMmFNfLNZzpzVcDabKBSaFhnwVtXZ6oxmfuAm1/7ZO0b08ETw tYDWoOCADqbtfKPVIJz1GdKwj56vqCR+917/IHCIwkJIm8x/fcfBJiWLk+Zh6iUWdL W3iUpl93/HZ9JKaGUDJsg26oJxyaetEX4oxFUDSS74UxkoJU8G0DCOKSNqZnCR4q6b U9qmYIqvycictEZdN/1SjyMT1UFsRtSEp07DYvmXBAFc1Pvw4Yf2E1S5FdAuhfxIcD QU7X0A+b2/QRUCCgUESCuq59CVRhhl1W6X+yQ2exUDXrGkUX9jAQjfkGgNt+1f/vfO WdUixK/WI2e8Q== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com, Quentin Monnet , Mykyta Yatsenko Subject: [PATCH v2 bpf-next 1/3] bpftool: improve skeleton backwards compat with old buggy libbpfs Date: Mon, 8 Jul 2024 13:45:38 -0700 Message-ID: <20240708204540.4188946-2-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240708204540.4188946-1-andrii@kernel.org> References: <20240708204540.4188946-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Old versions of libbpf don't handle varying sizes of bpf_map_skeleton struct correctly. As such, BPF skeleton generated by newest bpftool might not be compatible with older libbpf (though only when libbpf is used as a shared library), even though it, by design, should. Going forward libbpf will be fixed, plus we'll release bug fixed versions of relevant old libbpfs, but meanwhile try to mitigate from bpftool side by conservatively assuming older and smaller definition of bpf_map_skeleton, if possible. Meaning, if there are no struct_ops maps. If there are struct_ops, then presumably user would like to have auto-attaching logic and struct_ops map link placeholders, so use the full bpf_map_skeleton definition in that case. Acked-by: Quentin Monnet Co-developed-by: Mykyta Yatsenko Signed-off-by: Mykyta Yatsenko Signed-off-by: Andrii Nakryiko Acked-by: Eduard Zingerman --- tools/bpf/bpftool/gen.c | 46 ++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 51eaed76db97..70aaa32ddcc9 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -852,24 +852,41 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool { struct bpf_map *map; char ident[256]; - size_t i; + size_t i, map_sz; if (!map_cnt) return; + /* for backward compatibility with old libbpf versions that don't + * handle new BPF skeleton with new struct bpf_map_skeleton definition + * that includes link field, avoid specifying new increased size, + * unless we absolutely have to (i.e., if there are struct_ops maps + * present) + */ + map_sz = offsetof(struct bpf_map_skeleton, link); + if (populate_links) { + bpf_object__for_each_map(map, obj) { + if (bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) { + map_sz = sizeof(struct bpf_map_skeleton); + break; + } + } + } + codegen("\ \n\ - \n\ + \n\ /* maps */ \n\ s->map_cnt = %zu; \n\ - s->map_skel_sz = sizeof(*s->maps); \n\ - s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);\n\ + s->map_skel_sz = %zu; \n\ + s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt,\n\ + sizeof(*s->maps) > %zu ? sizeof(*s->maps) : %zu);\n\ if (!s->maps) { \n\ err = -ENOMEM; \n\ goto err; \n\ } \n\ ", - map_cnt + map_cnt, map_sz, map_sz, map_sz ); i = 0; bpf_object__for_each_map(map, obj) { @@ -878,23 +895,22 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool codegen("\ \n\ - \n\ - s->maps[%zu].name = \"%s\"; \n\ - s->maps[%zu].map = &obj->maps.%s; \n\ + \n\ + map = (struct bpf_map_skeleton *)((char *)s->maps + %zu * s->map_skel_sz);\n\ + map->name = \"%s\"; \n\ + map->map = &obj->maps.%s; \n\ ", - i, bpf_map__name(map), i, ident); + i, bpf_map__name(map), ident); /* memory-mapped internal maps */ if (mmaped && is_mmapable_map(map, ident, sizeof(ident))) { - printf("\ts->maps[%zu].mmaped = (void **)&obj->%s;\n", - i, ident); + printf("\tmap->mmaped = (void **)&obj->%s; \n", ident); } if (populate_links && bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) { codegen("\ \n\ - s->maps[%zu].link = &obj->links.%s;\n\ - ", - i, ident); + map->link = &obj->links.%s; \n\ + ", ident); } i++; } @@ -1463,6 +1479,7 @@ static int do_skeleton(int argc, char **argv) %1$s__create_skeleton(struct %1$s *obj) \n\ { \n\ struct bpf_object_skeleton *s; \n\ + struct bpf_map_skeleton *map __attribute__((unused));\n\ int err; \n\ \n\ s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));\n\ @@ -1753,6 +1770,7 @@ static int do_subskeleton(int argc, char **argv) { \n\ struct %1$s *obj; \n\ struct bpf_object_subskeleton *s; \n\ + struct bpf_map_skeleton *map __attribute__((unused));\n\ int err; \n\ \n\ obj = (struct %1$s *)calloc(1, sizeof(*obj)); \n\