From patchwork Mon Jun 5 20:05:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Vernet X-Patchwork-Id: 103473 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp2930403vqr; Mon, 5 Jun 2023 13:17:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5juBoc32oF0gnIzg2ifrLUcsMUK3QIdvYoJgPZ8rOAUZML++DjVDiMxfgKsRMnElx81ltS X-Received: by 2002:ac8:4e8a:0:b0:3f6:a807:c9b1 with SMTP id 10-20020ac84e8a000000b003f6a807c9b1mr11187086qtp.6.1685996225777; Mon, 05 Jun 2023 13:17:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685996225; cv=none; d=google.com; s=arc-20160816; b=YNc4D530exKXQRLoAqlZZf9yzv5MxRSsOMfreczTG0S7cDYI+C2yHcguCxfpto43sX to4/tQIS/Nh+iLHqknI0zxZ1E9Fgr42SvPIUVv181eVIwYHOXqC3r2hYeMNh8h8XtWyE q4SyWOQbZg5cfvfq7kun4PqG3mRC43UWHe03e7W9ifp0fX3L1jag2Q4upIYyS2XA0XLp 7Mh5SiUYDIy7I7CwPJoMHPfuVvF+jfm5akxtS9jUo7TH+h3ZU57DKf4xLzKWhuzBnK71 Uhkf3YIue1jUQ78CE69KkTMD5Gv3OkdQ2xP8r9C39dwsLrEo5txGE7OZJ9XXTlTSNqnt aHJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=D72YnjZDedFXVKdKEyBmiBE+/IO/0eCEyvcyGBPY8yw=; b=qxCJKkd/NPCN79IDEk2mjDpW5RrFSiToBDws+AmcX3tZC62EGMpzL0o6G8Y6/CCCna hth4YTlgXCKx1ZTq8kXPK8Ahg5gvGtatq4aiA2rn3AFSncpnaUnB4AEL5VbJPaTJ1kV2 iwXw5wnU1k9SqG82ExIl1suXMKmVw11ariAkNRAk6tYyGhEOFZbMRF9FNFsmFbrx5SAe Orite/8VHG4znBhgLhCP46o7iLKSEKsh2f5T4gKD+/a5dYFVY/1rWtOCBfum8EbdjUQW hJhPil9rQ0hb/mp9IevKzVnWudV927ba8UfhXjrIDEAeyxVbEJF+hCbHrE8jvWtZq36C rSaw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o13-20020ac85a4d000000b003f73fffbe5bsi5207402qta.240.2023.06.05.13.16.51; Mon, 05 Jun 2023 13:17:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229742AbjFEUF3 (ORCPT + 99 others); Mon, 5 Jun 2023 16:05:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229511AbjFEUFY (ORCPT ); Mon, 5 Jun 2023 16:05:24 -0400 Received: from mail-qt1-f171.google.com (mail-qt1-f171.google.com [209.85.160.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29D6798; Mon, 5 Jun 2023 13:05:23 -0700 (PDT) Received: by mail-qt1-f171.google.com with SMTP id d75a77b69052e-3f9aeba6cc4so1358231cf.2; Mon, 05 Jun 2023 13:05:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685995522; x=1688587522; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=D72YnjZDedFXVKdKEyBmiBE+/IO/0eCEyvcyGBPY8yw=; b=SGHzllnPbQUz+D7zY4y9y5iI5Gyukx9kyU6nCbsmCoE2WBM0y/iTVvfKxStKm3U++A bII1BbhEhmseOC8NMeZZN69A3GHnYtRXBbExJ8X7LmMLHfUj15PVf/2sEk/lLEvDZe25 Mdqihg5aG6/3KahX58Ud4tiYHAvduIJgw3/YJBEjP9Zi4LaPVDEpY6GAa2SSFTGoLFYR ik5hdT3gBPxHFxFS7LVlQ/jrOXayc8XqiPE7Dh+MWciv8APxforlbVf7cITc7MUxWYFh BOIytil+vQ0ZBkTGq+ly8AWXOj9aJCJE3KfRG4YxPffiaAjjRh1aSmUiWW1FEmjEhj99 wn4w== X-Gm-Message-State: AC+VfDwO3vyM0SF+WdDr4rNR0hI8kxK6YXc4Dc+ciw2OdEy4J49+jfBe KHG89CJ1drSZK6ZSYhaJsCAM931kk08ta39C X-Received: by 2002:a05:622a:282:b0:3f3:8b8a:75a6 with SMTP id z2-20020a05622a028200b003f38b8a75a6mr9184668qtw.23.1685995521777; Mon, 05 Jun 2023 13:05:21 -0700 (PDT) Received: from localhost ([2620:10d:c091:400::5:7447]) by smtp.gmail.com with ESMTPSA id i6-20020ac87646000000b003f6b0562ad7sm5000210qtr.16.2023.06.05.13.05.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Jun 2023 13:05:21 -0700 (PDT) From: David Vernet To: bpf@vger.kernel.org Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, linux-kernel@vger.kernel.org, kernel-team@meta.com, davemarchevsky@meta.com Subject: [PATCH bpf-next 2/2] selftests/bpf: Test bpf_for_each_map_elem on BPF_MAP_TYPE_HASH_OF_MAPS Date: Mon, 5 Jun 2023 15:05:08 -0500 Message-Id: <20230605200508.1888874-2-void@manifault.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230605200508.1888874-1-void@manifault.com> References: <20230605200508.1888874-1-void@manifault.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767895178704945610?= X-GMAIL-MSGID: =?utf-8?q?1767895178704945610?= Now that we support using the bpf_for_each_map_elem() on the BPF_MAP_TYPE_HASH_OF_MAPS map type, we should add selftests that verify expected behavior. This patch addds those selftests. Included in this is a new test_btf_map_in_map_failure.c BPF prog that can be used to verify expected map-in-map failures in the verifier. Signed-off-by: David Vernet --- .../selftests/bpf/prog_tests/btf_map_in_map.c | 44 +++++++++++ .../selftests/bpf/progs/test_btf_map_in_map.c | 73 ++++++++++++++++++- .../bpf/progs/test_btf_map_in_map_failure.c | 39 ++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/progs/test_btf_map_in_map_failure.c diff --git a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c index a8b53b8736f0..257b5b5a08ba 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c +++ b/tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c @@ -4,6 +4,7 @@ #include #include "test_btf_map_in_map.skel.h" +#include "test_btf_map_in_map_failure.skel.h" static int duration; @@ -154,6 +155,43 @@ static void test_diff_size(void) test_btf_map_in_map__destroy(skel); } +static void test_hash_iter(const char *prog_name) +{ + struct test_btf_map_in_map *skel; + struct bpf_program *prog; + struct bpf_link *link = NULL; + int err, child_pid, status; + + skel = test_btf_map_in_map__open(); + if (!ASSERT_OK_PTR(skel, "test_btf_map_in_map__open\n")) + return; + + skel->bss->pid = getpid(); + err = test_btf_map_in_map__load(skel); + if (!ASSERT_OK(err, "test_btf_map_in_map__load")) + goto cleanup; + + prog = bpf_object__find_program_by_name(skel->obj, prog_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto cleanup; + + link = bpf_program__attach(prog); + if (!ASSERT_OK_PTR(link, "bpf_program__attach")) + goto cleanup; + + child_pid = fork(); + if (!ASSERT_GT(child_pid, -1, "child_pid")) + goto cleanup; + if (child_pid == 0) + _exit(0); + waitpid(child_pid, &status, 0); + ASSERT_OK(skel->bss->err, "post_wait_err"); + +cleanup: + bpf_link__destroy(link); + test_btf_map_in_map__destroy(skel); +} + void test_btf_map_in_map(void) { if (test__start_subtest("lookup_update")) @@ -161,4 +199,10 @@ void test_btf_map_in_map(void) if (test__start_subtest("diff_size")) test_diff_size(); + + if (test__start_subtest("hash_iter")) + test_hash_iter("test_iter_hash_of_maps"); + + RUN_TESTS(test_btf_map_in_map); + RUN_TESTS(test_btf_map_in_map_failure); } diff --git a/tools/testing/selftests/bpf/progs/test_btf_map_in_map.c b/tools/testing/selftests/bpf/progs/test_btf_map_in_map.c index c218cf8989a9..905392de6a3b 100644 --- a/tools/testing/selftests/bpf/progs/test_btf_map_in_map.c +++ b/tools/testing/selftests/bpf/progs/test_btf_map_in_map.c @@ -1,7 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2020 Facebook */ -#include +#include #include +#include +#include + +#include "bpf_misc.h" + +int err, pid; struct inner_map { __uint(type, BPF_MAP_TYPE_ARRAY); @@ -120,6 +126,13 @@ struct outer_sockarr_sz1 { int input = 0; +static bool is_test_task(void) +{ + int cur_pid = bpf_get_current_pid_tgid() >> 32; + + return pid == cur_pid; +} + SEC("raw_tp/sys_enter") int handle__sys_enter(void *ctx) { @@ -147,4 +160,62 @@ int handle__sys_enter(void *ctx) return 0; } +struct callback_ctx { + bool invoked; + bool failed; +}; + +static __u64 set_invoked(struct bpf_map *map, __u64 *key, __u64 *val, struct callback_ctx *ctx) +{ + struct bpf_map *inner_map; + + ctx->invoked = true; + inner_map = bpf_map_lookup_elem(map, key); + if (!inner_map) { + ctx->failed = true; + return 1; + } + + return 0; +} + +SEC("tp_btf/task_newtask") +int BPF_PROG(test_iter_hash_of_maps, struct task_struct *task, u64 clone_flags) +{ + long ret; + struct callback_ctx callback_ctx = { + .invoked = false, + .failed = false, + }; + + if (!is_test_task()) + return 0; + + ret = bpf_for_each_map_elem(&outer_hash, set_invoked, &callback_ctx, 0); + if (ret < 1) + err = 1; + + if (!callback_ctx.invoked) + err = 2; + + if (callback_ctx.failed) + err = 3; + + return 0; +} + +static __u64 empty_cb(struct bpf_map *map, __u64 *key, __u64 *val, void *ctx) +{ + return 0; +} + +SEC("tp_btf/task_newtask") +__success +int BPF_PROG(test_iter_hash_of_maps_no_ctx, struct task_struct *task, u64 clone_flags) +{ + /* Should be able to iterate with no context as well. */ + bpf_for_each_map_elem(&outer_hash, empty_cb, NULL, 0); + return 0; +} + char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_btf_map_in_map_failure.c b/tools/testing/selftests/bpf/progs/test_btf_map_in_map_failure.c new file mode 100644 index 000000000000..6b7a94fe15c7 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_btf_map_in_map_failure.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ + +#include +#include +#include +#include + +#include "bpf_misc.h" + +struct inner_map { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} inner_map1 SEC(".maps"), + inner_map2 SEC(".maps"); + +struct outer_hash { + __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); + __uint(max_entries, 2); + __type(key, int); + __array(values, struct inner_map); +} outer_hash SEC(".maps") = { + .values = { + [0] = &inner_map2, + [1] = &inner_map1, + }, +}; + +SEC("tp_btf/task_newtask") +__failure +__msg("R2 type=scalar expected=func") +int BPF_PROG(test_iter_hash_of_maps_null_cb, struct task_struct *task, u64 clone_flags) +{ + /* Can't iterate over a NULL callback. */ + bpf_for_each_map_elem(&outer_hash, NULL, NULL, 0); + return 0; +}