From patchwork Tue Nov 22 05:54:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Vernet X-Patchwork-Id: 24160 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2024913wrr; Mon, 21 Nov 2022 21:57:50 -0800 (PST) X-Google-Smtp-Source: AA0mqf7BFiFwUeNxWQUamcwWL865/9A2NhFzvXoKVERqIpO/IeeX1LXNdFLGaGEY7k9Ym7hcRSLJ X-Received: by 2002:a05:6402:294d:b0:467:6b55:3cf5 with SMTP id ed13-20020a056402294d00b004676b553cf5mr19831386edb.22.1669096670014; Mon, 21 Nov 2022 21:57:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669096670; cv=none; d=google.com; s=arc-20160816; b=PQdQwdiYEEhsM9USPXheSFumLZDSJszbtYZsYeRT6JzXi8lqNPyy75hwUSxVNhdiT0 fDgL45rbg28l4avDMW+Ufo97b91SPU3J8kW7GV5AngKhEiKEQB98Twpcy70M5UOW+WW2 BGuYoAPEL7g4vPdKynWV83P94CIPSZSsTIYTMhRdaanuW5Byhhgv9+TA0V5Kq6rduXJv ti60MLjKZdR7kHl2d2F4VQ0ANdMucoc2GldjAx0m7eb42s5Xhrl7XAg6Bc9A+GTP4MGS e7fVisuZnCy16XseGpt92JZDiJzMuQ+dSY/9t/D6zmnT4LhOXDNzV3uhqxB+dCI3MqXX df5A== 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=Vu6oCi48lK4LFBzFBf6DeUSRUKMcJZFM3TSHBmkTlQs=; b=u1s1HHllyMeaOECGsY8wvrPKEjlH2v1vPMhD/t6Db+yPGa1lLBvA1wPrI/n2cl1N10 wHlK560rSoDzjth1I4mUjq7/kkCqcVWsDjrRKgTpDw16Y9jGSRuw4GpLFyXyHv/Qe5Mh OCoV4TCsNjUxf8p1OR89QUjvKh2jmYzIW7p9Z112onX3YjBGZgTBWBYvBOOHa2fQWgVe hDJheXZAP85lA0ll90t3Y9NzX1OBd1VFIl9IMwPnkUweQz5opOim2bco+FdFJiWWh3Xu /YlXA2x0iCAlnr9qMctN4ue/K0rDu4W9vdEFxRUX2AZGnUvtiJJnw0Mk+qNRcIL0XCSf XxXg== 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 l18-20020a056402255200b00463d1e263b1si12318472edb.364.2022.11.21.21.57.26; Mon, 21 Nov 2022 21:57:49 -0800 (PST) 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 S229450AbiKVF4l (ORCPT + 99 others); Tue, 22 Nov 2022 00:56:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231838AbiKVF4S (ORCPT ); Tue, 22 Nov 2022 00:56:18 -0500 Received: from mail-qt1-f172.google.com (mail-qt1-f172.google.com [209.85.160.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48C832F03E; Mon, 21 Nov 2022 21:55:47 -0800 (PST) Received: by mail-qt1-f172.google.com with SMTP id z6so8693925qtv.5; Mon, 21 Nov 2022 21:55:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=Vu6oCi48lK4LFBzFBf6DeUSRUKMcJZFM3TSHBmkTlQs=; b=KWQDccKowSqopbnL3QihIWf//7zwlnCSZv/Te+91GC264j9kbyZw+VWbPLBu9717qQ xSPSyDHPRrvApvE7hzkZtX50KOOCcrrNv0fLN4xgLqinD1zly7KVd1fXrt0UidYwJ6YL wyNEWb5rDaqLRymDprcVqN/DMSaQP8jsszgcgKSy2zCNaPe6wSORrb22o77QIyOpgYrF kIpMwkhP0+BqdsBuZxV73R2eu3rqpUbpND8MUSrMPGiQKazG8qnBvQ32cAUR7Vw4alMN CxcGvT2lnQYXXs0NeNPqiUWcoSvUKEzN2eHvQ8/xndboSMHzukpWUfqLe0AZay3xHFQi XPGw== X-Gm-Message-State: ANoB5pklrMlKwtFT9HZyDZHR568ACrQ7pDVF6a2qqyOzTaYCNd0MTCtv bY4vyC/gTcYVEb2cKpSHFidt68/UZE8j2uxi X-Received: by 2002:ac8:4e31:0:b0:3a5:d3d:2528 with SMTP id d17-20020ac84e31000000b003a50d3d2528mr20268306qtw.619.1669096545925; Mon, 21 Nov 2022 21:55:45 -0800 (PST) Received: from localhost ([2620:10d:c091:480::1:3170]) by smtp.gmail.com with ESMTPSA id l21-20020a37f915000000b006fa7b5ea2d1sm9655368qkj.125.2022.11.21.21.55.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Nov 2022 21:55:45 -0800 (PST) From: David Vernet To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev, yhs@fb.com, song@kernel.org, sdf@google.com, john.fastabend@gmail.com, kpsingh@kernel.org, jolsa@kernel.org, haoluo@google.com, tj@kernel.org, kernel-team@fb.com, linux-kernel@vger.kernel.org Subject: [PATCH bpf-next 1/4] bpf: Enable cgroups to be used as kptrs Date: Mon, 21 Nov 2022 23:54:55 -0600 Message-Id: <20221122055458.173143-2-void@manifault.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221122055458.173143-1-void@manifault.com> References: <20221122055458.173143-1-void@manifault.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.5 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 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?1750174709828049362?= X-GMAIL-MSGID: =?utf-8?q?1750174709828049362?= Now that tasks can be used as kfuncs, and the PTR_TRUSTED flag is available for us to easily add basic acquire / get / release kfuncs, we can do the same for cgroups. This patch set adds the following kfuncs which enable using cgroups as kptrs: struct cgroup *bpf_cgroup_acquire(struct cgroup *cgrp); struct cgroup *bpf_cgroup_kptr_get(struct cgroup **cgrpp); void bpf_cgroup_release(struct cgroup *cgrp); A follow-on patch will add a selftest suite which validates these kfuncs. Signed-off-by: David Vernet --- kernel/bpf/helpers.c | 83 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 9e8a5557ea8d..420a4251cccc 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -1879,6 +1880,66 @@ void bpf_task_release(struct task_struct *p) put_task_struct_rcu_user(p); } +#ifdef CONFIG_CGROUPS +/** + * bpf_cgroup_acquire - Acquire a reference to a cgroup. A cgroup acquired by + * this kfunc which is not stored in a map as a kptr, must be released by + * calling bpf_cgroup_release(). + * @cgrp: The cgroup on which a reference is being acquired. + */ +struct cgroup *bpf_cgroup_acquire(struct cgroup *cgrp) +{ + cgroup_get(cgrp); + return cgrp; +} + +/** + * bpf_cgroup_kptr_get - Acquire a reference on a struct cgroup kptr. A cgroup + * kptr acquired by this kfunc which is not subsequently stored in a map, must + * be released by calling bpf_cgroup_release(). + * @cgrpp: A pointer to a cgroup kptr on which a reference is being acquired. + */ +struct cgroup *bpf_cgroup_kptr_get(struct cgroup **cgrpp) +{ + struct cgroup *cgrp; + + rcu_read_lock(); + /* Another context could remove the cgroup from the map and release it + * at any time, including after we've done the lookup above. This is + * safe because we're in an RCU read region, so the cgroup is + * guaranteed to remain valid until at least the rcu_read_unlock() + * below. + */ + cgrp = READ_ONCE(*cgrpp); + + if (cgrp && !cgroup_tryget(cgrp)) + /* If the cgroup had been removed from the map and freed as + * described above, cgroup_tryget() will return false. The + * cgroup will be freed at some point after the current RCU gp + * has ended, so just return NULL to the user. + */ + cgrp = NULL; + rcu_read_unlock(); + + return cgrp; +} + +/** + * bpf_cgroup_release - Release the reference acquired on a struct cgroup *. + * If this kfunc is invoked in an RCU read region, the cgroup is guaranteed to + * not be freed until the current grace period has ended, even if its refcount + * drops to 0. + * @cgrp: The cgroup on which a reference is being released. + */ +void bpf_cgroup_release(struct cgroup *cgrp) +{ + if (!cgrp) + return; + + cgroup_put(cgrp); +} +#endif /* CONFIG_CGROUPS */ + void *bpf_cast_to_kern_ctx(void *obj) { return obj; @@ -1904,6 +1965,12 @@ BTF_ID_FLAGS(func, bpf_list_pop_back, KF_ACQUIRE | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_task_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_task_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_task_release, KF_RELEASE) + +#ifdef CONFIG_CGROUPS +BTF_ID_FLAGS(func, bpf_cgroup_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_cgroup_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_cgroup_release, KF_RELEASE) +#endif BTF_SET8_END(generic_btf_ids) static const struct btf_kfunc_id_set generic_kfunc_set = { @@ -1915,6 +1982,10 @@ static const struct btf_kfunc_id_set generic_kfunc_set = { BTF_ID_LIST(generic_dtor_ids) BTF_ID(struct, task_struct) BTF_ID(func, bpf_task_release) +#ifdef CONFIG_CGROUPS +BTF_ID(struct, cgroup) +BTF_ID(func, bpf_cgroup_release) +#endif BTF_SET8_START(common_btf_ids) BTF_ID_FLAGS(func, bpf_cast_to_kern_ctx) @@ -1928,12 +1999,18 @@ static const struct btf_kfunc_id_set common_kfunc_set = { static int __init kfunc_init(void) { - int ret; + int ret, idx = 0; const struct btf_id_dtor_kfunc generic_dtors[] = { { - .btf_id = generic_dtor_ids[0], - .kfunc_btf_id = generic_dtor_ids[1] + .btf_id = generic_dtor_ids[idx++], + .kfunc_btf_id = generic_dtor_ids[idx++] }, +#ifdef CONFIG_CGROUPS + { + .btf_id = generic_dtor_ids[idx++], + .kfunc_btf_id = generic_dtor_ids[idx++] + }, +#endif }; ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &generic_kfunc_set); From patchwork Tue Nov 22 05:54:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Vernet X-Patchwork-Id: 24161 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2025033wrr; Mon, 21 Nov 2022 21:58:19 -0800 (PST) X-Google-Smtp-Source: AA0mqf4YOhHqyAVnYQ5QqEv5IiVsZY3r2A8hu45tLNXHHSU3+JANR3eluDViafAr5nDcZFS1tRA6 X-Received: by 2002:a17:906:3993:b0:7ad:f5a9:ece3 with SMTP id h19-20020a170906399300b007adf5a9ece3mr18404181eje.635.1669096699467; Mon, 21 Nov 2022 21:58:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669096699; cv=none; d=google.com; s=arc-20160816; b=uBiiThR7BsLtQn59dNbc0XuqdjfC0LoYywIY/q4+hZm1MIXLm4e84WT2doenfApy5X ZWG8MOjWJiR55I6RJpP1XfaioHAdmsi6DZNYl3KA6H5rynIXX22PxKlif2oUmJ0qFcpE wJ30sicrKhNNbPhiK5Zf7zvRLxevsye3N6JomY5tRuBZB3dgSzhcJ8/kStj6jqp0/Vck js0V5gMZhO7aCUk2Yw32Nj57CISTmd4PZmPcTrLnFps5UavyusAGtmlQMBiyILdcj4Er EH9FwuIPL2uvK/a8cqPXf/GA+1B8VqGcy8A51PoWuhc3G6D/9teyDV0OvTuFpwEg7SbX ZBeQ== 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=eZ4x5r/AX97bCLXUzrPxLnjjqC4hv8tbiW47sVTozyc=; b=VoXXJUn4Nrwzisb0mu+yQ1j4a7hcJN06lnSMDMhhYcltCUP/mCaXrWrfa0WVBSCTEB nHy3Q6SGb3ZgqggPs2G0z3mCOBHeQwFGa7psv/UqbpKUhyswB4Mg3hoSbrlFIPfw8wF0 UuLA6NJ51UYwbeUbIdY0EHPX1UHHcZUXWjagCqc03Zgptl8+I6FmOl5VBJ6gylr+duzd pBmoHUHcysIRjIa/ITu7pfzXX0OdHh5rT/5ga7eAxfnQS1caCEdkcx8q6DjwOek1NsOy NcdctC1ZscsfARnFyDY3pYCI6T+w+8Ap5YbWojRglokWJBU2BKjsPC464a1ngMjii85X +mcQ== 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 d12-20020aa7d68c000000b004691547f6besi8755949edr.280.2022.11.21.21.57.53; Mon, 21 Nov 2022 21:58:19 -0800 (PST) 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 S232224AbiKVF4t (ORCPT + 99 others); Tue, 22 Nov 2022 00:56:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232018AbiKVF4S (ORCPT ); Tue, 22 Nov 2022 00:56:18 -0500 Received: from mail-qv1-f52.google.com (mail-qv1-f52.google.com [209.85.219.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A9552654A; Mon, 21 Nov 2022 21:55:48 -0800 (PST) Received: by mail-qv1-f52.google.com with SMTP id k2so8308221qvo.1; Mon, 21 Nov 2022 21:55:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=eZ4x5r/AX97bCLXUzrPxLnjjqC4hv8tbiW47sVTozyc=; b=ZNHXvjg84k6AEEe8THUld9f+MFJAd3FU0X163NEaja3DaD8mX1PItJRybnoiT3g4zG bPWNGQ5oYw1GlhKkoph2LtlqdJq5VYVxURLP5XGzXeD+fBQW/vLZ6CvF2qHVDiw+xSjA czFmOODG1nir5LLRh7iHLuOGNoIFqL58EdoWN/aCiQsn1JQNk2y5XGy0IwpDbuGn6qIy OtNqSMmQ5O/o8BcDM3hqguNHHI44dXwcO7rQ1kYQgVsGFrZNGBNjzNSm/ZvcbE/PoE0e jsG9o9TRv0nrcgURWnJhnAC/RCkuRmMhM9O2HIjgxiqWubq7SdqdO/L0ejEiMiAXe/wo XEnw== X-Gm-Message-State: ANoB5pkZOjZ5V3oE8C1o8/nA/uQmULjgDxfhH43AeF3b3SCSoh/wBt1L MIYfcHng+WU+/YnJe35lrcPM2vCx6Q3xCyH6 X-Received: by 2002:a05:6214:1c6:b0:4ba:171b:8978 with SMTP id c6-20020a05621401c600b004ba171b8978mr3759141qvt.82.1669096547498; Mon, 21 Nov 2022 21:55:47 -0800 (PST) Received: from localhost ([2620:10d:c091:480::1:3170]) by smtp.gmail.com with ESMTPSA id u13-20020a05622a17cd00b003a530a32f67sm7823359qtk.65.2022.11.21.21.55.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Nov 2022 21:55:47 -0800 (PST) From: David Vernet To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev, yhs@fb.com, song@kernel.org, sdf@google.com, john.fastabend@gmail.com, kpsingh@kernel.org, jolsa@kernel.org, haoluo@google.com, tj@kernel.org, kernel-team@fb.com, linux-kernel@vger.kernel.org Subject: [PATCH bpf-next 2/4] selftests/bpf: Add cgroup kfunc / kptr selftests Date: Mon, 21 Nov 2022 23:54:56 -0600 Message-Id: <20221122055458.173143-3-void@manifault.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221122055458.173143-1-void@manifault.com> References: <20221122055458.173143-1-void@manifault.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS 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?1750174741177856681?= X-GMAIL-MSGID: =?utf-8?q?1750174741177856681?= This patch adds a selftest suite to validate the cgroup kfuncs that were added in the prior patch. Signed-off-by: David Vernet --- tools/testing/selftests/bpf/DENYLIST.s390x | 1 + .../selftests/bpf/prog_tests/cgrp_kfunc.c | 174 ++++++++++++ .../selftests/bpf/progs/cgrp_kfunc_common.h | 71 +++++ .../selftests/bpf/progs/cgrp_kfunc_failure.c | 260 ++++++++++++++++++ .../selftests/bpf/progs/cgrp_kfunc_success.c | 125 +++++++++ 5 files changed, 631 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c create mode 100644 tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h create mode 100644 tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c create mode 100644 tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c diff --git a/tools/testing/selftests/bpf/DENYLIST.s390x b/tools/testing/selftests/bpf/DENYLIST.s390x index 12cf2159975e..b9a3d80204c6 100644 --- a/tools/testing/selftests/bpf/DENYLIST.s390x +++ b/tools/testing/selftests/bpf/DENYLIST.s390x @@ -10,6 +10,7 @@ bpf_nf # JIT does not support calling kernel f bpf_tcp_ca # JIT does not support calling kernel function (kfunc) cb_refs # expected error message unexpected error: -524 (trampoline) cgroup_hierarchical_stats # JIT does not support calling kernel function (kfunc) +cgrp_kfunc # JIT does not support calling kernel function cgrp_local_storage # prog_attach unexpected error: -524 (trampoline) core_read_macros # unknown func bpf_probe_read#4 (overlapping) d_path # failed to auto-attach program 'prog_stat': -524 (trampoline) diff --git a/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c b/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c new file mode 100644 index 000000000000..a59b166bbcc4 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ + +#define _GNU_SOURCE +#include +#include + +#include "cgrp_kfunc_failure.skel.h" +#include "cgrp_kfunc_success.skel.h" + +static size_t log_buf_sz = 1 << 20; /* 1 MB */ +static char obj_log_buf[1048576]; + +static struct cgrp_kfunc_success *open_load_cgrp_kfunc_skel(void) +{ + struct cgrp_kfunc_success *skel; + int err; + + skel = cgrp_kfunc_success__open(); + if (!ASSERT_OK_PTR(skel, "skel_open")) + return NULL; + + skel->bss->pid = getpid(); + + err = cgrp_kfunc_success__load(skel); + if (!ASSERT_OK(err, "skel_load")) + goto cleanup; + + return skel; + +cleanup: + cgrp_kfunc_success__destroy(skel); + return NULL; +} + +static int mkdir_rm_test_dir(void) +{ + int fd; + const char *cgrp_path = "cgrp_kfunc"; + + fd = create_and_get_cgroup(cgrp_path); + if (!ASSERT_GT(fd, 0, "mkdir_cgrp_fd")) + return -1; + + close(fd); + remove_cgroup(cgrp_path); + + return 0; +} + +static void run_success_test(const char *prog_name) +{ + struct cgrp_kfunc_success *skel; + struct bpf_program *prog; + struct bpf_link *link = NULL; + + skel = open_load_cgrp_kfunc_skel(); + if (!ASSERT_OK_PTR(skel, "open_load_skel")) + return; + + if (!ASSERT_OK(skel->bss->err, "pre_mkdir_err")) + 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, "attached_link")) + goto cleanup; + + ASSERT_EQ(skel->bss->invocations, 0, "pre_rmdir_count"); + if (!ASSERT_OK(mkdir_rm_test_dir(), "cgrp_mkdir")) + goto cleanup; + + ASSERT_EQ(skel->bss->invocations, 1, "post_rmdir_count"); + ASSERT_OK(skel->bss->err, "post_rmdir_err"); + +cleanup: + bpf_link__destroy(link); + cgrp_kfunc_success__destroy(skel); +} + +static const char * const success_tests[] = { + "test_cgrp_acquire_release_argument", + "test_cgrp_acquire_leave_in_map", + "test_cgrp_xchg_release", + "test_cgrp_get_release", +}; + +static struct { + const char *prog_name; + const char *expected_err_msg; +} failure_tests[] = { + {"cgrp_kfunc_acquire_untrusted", "R1 must be referenced or trusted"}, + {"cgrp_kfunc_acquire_fp", "arg#0 pointer type STRUCT cgroup must point"}, + {"cgrp_kfunc_acquire_unsafe_kretprobe", "reg type unsupported for arg#0 function"}, + {"cgrp_kfunc_acquire_trusted_walked", "R1 must be referenced or trusted"}, + {"cgrp_kfunc_acquire_null", "arg#0 pointer type STRUCT cgroup must point"}, + {"cgrp_kfunc_acquire_unreleased", "Unreleased reference"}, + {"cgrp_kfunc_get_non_kptr_param", "arg#0 expected pointer to map value"}, + {"cgrp_kfunc_get_non_kptr_acquired", "arg#0 expected pointer to map value"}, + {"cgrp_kfunc_get_null", "arg#0 expected pointer to map value"}, + {"cgrp_kfunc_xchg_unreleased", "Unreleased reference"}, + {"cgrp_kfunc_get_unreleased", "Unreleased reference"}, + {"cgrp_kfunc_release_untrusted", "arg#0 is untrusted_ptr_or_null_ expected ptr_ or socket"}, + {"cgrp_kfunc_release_fp", "arg#0 pointer type STRUCT cgroup must point"}, + {"cgrp_kfunc_release_null", "arg#0 is ptr_or_null_ expected ptr_ or socket"}, + {"cgrp_kfunc_release_unacquired", "release kernel function bpf_cgroup_release expects"}, +}; + +static void verify_fail(const char *prog_name, const char *expected_err_msg) +{ + LIBBPF_OPTS(bpf_object_open_opts, opts); + struct cgrp_kfunc_failure *skel; + int err, i; + + opts.kernel_log_buf = obj_log_buf; + opts.kernel_log_size = log_buf_sz; + opts.kernel_log_level = 1; + + skel = cgrp_kfunc_failure__open_opts(&opts); + if (!ASSERT_OK_PTR(skel, "cgrp_kfunc_failure__open_opts")) + goto cleanup; + + for (i = 0; i < ARRAY_SIZE(failure_tests); i++) { + struct bpf_program *prog; + const char *curr_name = failure_tests[i].prog_name; + + prog = bpf_object__find_program_by_name(skel->obj, curr_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto cleanup; + + bpf_program__set_autoload(prog, !strcmp(curr_name, prog_name)); + } + + err = cgrp_kfunc_failure__load(skel); + if (!ASSERT_ERR(err, "unexpected load success")) + goto cleanup; + + if (!ASSERT_OK_PTR(strstr(obj_log_buf, expected_err_msg), "expected_err_msg")) { + fprintf(stderr, "Expected err_msg: %s\n", expected_err_msg); + fprintf(stderr, "Verifier output: %s\n", obj_log_buf); + } + +cleanup: + cgrp_kfunc_failure__destroy(skel); +} + +void test_cgrp_kfunc(void) +{ + int i, err; + + err = setup_cgroup_environment(); + if (!ASSERT_OK(err, "cgrp_env_setup")) + goto cleanup; + + for (i = 0; i < ARRAY_SIZE(success_tests); i++) { + if (!test__start_subtest(success_tests[i])) + continue; + + run_success_test(success_tests[i]); + } + + for (i = 0; i < ARRAY_SIZE(failure_tests); i++) { + if (!test__start_subtest(failure_tests[i].prog_name)) + continue; + + verify_fail(failure_tests[i].prog_name, failure_tests[i].expected_err_msg); + } + +cleanup: + cleanup_cgroup_environment(); +} diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h b/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h new file mode 100644 index 000000000000..3f18def0e45c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ + +#ifndef _CGRP_KFUNC_COMMON_H +#define _CGRP_KFUNC_COMMON_H + +#include +#include +#include +#include + +struct __cgrps_kfunc_map_value { + struct cgroup __kptr_ref * cgrp; +}; + +struct hash_map { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, int); + __type(value, struct __cgrps_kfunc_map_value); + __uint(max_entries, 1); +} __cgrps_kfunc_map SEC(".maps"); + +struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; +struct cgroup *bpf_cgroup_kptr_get(struct cgroup **pp) __ksym; +void bpf_cgroup_release(struct cgroup *p) __ksym; + +static inline struct __cgrps_kfunc_map_value *cgrps_kfunc_map_value_lookup(struct cgroup *cgrp) +{ + s32 id; + long status; + + status = bpf_probe_read_kernel(&id, sizeof(id), &cgrp->self.id); + if (status) + return NULL; + + return bpf_map_lookup_elem(&__cgrps_kfunc_map, &id); +} + +static inline int cgrps_kfunc_map_insert(struct cgroup *cgrp) +{ + struct __cgrps_kfunc_map_value local, *v; + long status; + struct cgroup *acquired, *old; + s32 id; + + status = bpf_probe_read_kernel(&id, sizeof(id), &cgrp->self.id); + if (status) + return status; + + local.cgrp = NULL; + status = bpf_map_update_elem(&__cgrps_kfunc_map, &id, &local, BPF_NOEXIST); + if (status) + return status; + + v = bpf_map_lookup_elem(&__cgrps_kfunc_map, &id); + if (!v) { + bpf_map_delete_elem(&__cgrps_kfunc_map, &id); + return -ENOENT; + } + + acquired = bpf_cgroup_acquire(cgrp); + old = bpf_kptr_xchg(&v->cgrp, acquired); + if (old) { + bpf_cgroup_release(old); + return -EEXIST; + } + + return 0; +} + +#endif /* _CGRP_KFUNC_COMMON_H */ diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c b/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c new file mode 100644 index 000000000000..a1369b5ebcf8 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_failure.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ + +#include +#include +#include + +#include "cgrp_kfunc_common.h" + +char _license[] SEC("license") = "GPL"; + +/* Prototype for all of the program trace events below: + * + * TRACE_EVENT(cgroup_mkdir, + * TP_PROTO(struct cgroup *cgrp, const char *path), + * TP_ARGS(cgrp, path) + */ + +static struct __cgrps_kfunc_map_value *insert_lookup_cgrp(struct cgroup *cgrp) +{ + int status; + + status = cgrps_kfunc_map_insert(cgrp); + if (status) + return NULL; + + return cgrps_kfunc_map_value_lookup(cgrp); +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_acquire_untrusted, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired; + struct __cgrps_kfunc_map_value *v; + + v = insert_lookup_cgrp(cgrp); + if (!v) + return 0; + + /* Can't invoke bpf_cgroup_acquire() on an untrusted pointer. */ + acquired = bpf_cgroup_acquire(v->cgrp); + bpf_cgroup_release(acquired); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_acquire_fp, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired, *stack_cgrp = (struct cgroup *)&path; + + /* Can't invoke bpf_cgroup_acquire() on a random frame pointer. */ + acquired = bpf_cgroup_acquire((struct cgroup *)&stack_cgrp); + bpf_cgroup_release(acquired); + + return 0; +} + +SEC("kretprobe/cgroup_destroy_locked") +int BPF_PROG(cgrp_kfunc_acquire_unsafe_kretprobe, struct cgroup *cgrp) +{ + struct cgroup *acquired; + + /* Can't acquire an untrusted struct cgroup * pointer. */ + acquired = bpf_cgroup_acquire(cgrp); + bpf_cgroup_release(acquired); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_acquire_trusted_walked, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired; + + /* Can't invoke bpf_cgroup_acquire() on a pointer obtained from walking a trusted cgroup. */ + acquired = bpf_cgroup_acquire(cgrp->old_dom_cgrp); + bpf_cgroup_release(acquired); + + return 0; +} + + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_acquire_null, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired; + + /* Can't invoke bpf_cgroup_acquire() on a NULL pointer. */ + acquired = bpf_cgroup_acquire(NULL); + if (!acquired) + return 0; + bpf_cgroup_release(acquired); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_acquire_unreleased, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired; + + acquired = bpf_cgroup_acquire(cgrp); + + /* Acquired cgroup is never released. */ + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_get_non_kptr_param, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr; + + /* Cannot use bpf_cgroup_kptr_get() on a non-kptr, even on a valid cgroup. */ + kptr = bpf_cgroup_kptr_get(&cgrp); + if (!kptr) + return 0; + + bpf_cgroup_release(kptr); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_get_non_kptr_acquired, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr, *acquired; + + acquired = bpf_cgroup_acquire(cgrp); + + /* Cannot use bpf_cgroup_kptr_get() on a non-map-value, even if the kptr was acquired. */ + kptr = bpf_cgroup_kptr_get(&acquired); + bpf_cgroup_release(acquired); + if (!kptr) + return 0; + + bpf_cgroup_release(kptr); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_get_null, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr; + + /* Cannot use bpf_cgroup_kptr_get() on a NULL pointer. */ + kptr = bpf_cgroup_kptr_get(NULL); + if (!kptr) + return 0; + + bpf_cgroup_release(kptr); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_xchg_unreleased, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr; + struct __cgrps_kfunc_map_value *v; + + v = insert_lookup_cgrp(cgrp); + if (!v) + return 0; + + kptr = bpf_kptr_xchg(&v->cgrp, NULL); + if (!kptr) + return 0; + + /* Kptr retrieved from map is never released. */ + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_get_unreleased, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr; + struct __cgrps_kfunc_map_value *v; + + v = insert_lookup_cgrp(cgrp); + if (!v) + return 0; + + kptr = bpf_cgroup_kptr_get(&v->cgrp); + if (!kptr) + return 0; + + /* Kptr acquired above is never released. */ + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_release_untrusted, struct cgroup *cgrp, const char *path) +{ + struct __cgrps_kfunc_map_value *v; + + v = insert_lookup_cgrp(cgrp); + if (!v) + return 0; + + /* Can't invoke bpf_cgroup_release() on an untrusted pointer. */ + bpf_cgroup_release(v->cgrp); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_release_fp, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired = (struct cgroup *)&path; + + /* Cannot release random frame pointer. */ + bpf_cgroup_release(acquired); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_release_null, struct cgroup *cgrp, const char *path) +{ + struct __cgrps_kfunc_map_value local, *v; + long status; + struct cgroup *acquired, *old; + s32 id; + + status = bpf_probe_read_kernel(&id, sizeof(id), &cgrp->self.id); + if (status) + return 0; + + local.cgrp = NULL; + status = bpf_map_update_elem(&__cgrps_kfunc_map, &id, &local, BPF_NOEXIST); + if (status) + return status; + + v = bpf_map_lookup_elem(&__cgrps_kfunc_map, &id); + if (!v) + return -ENOENT; + + acquired = bpf_cgroup_acquire(cgrp); + + old = bpf_kptr_xchg(&v->cgrp, acquired); + + /* old cannot be passed to bpf_cgroup_release() without a NULL check. */ + bpf_cgroup_release(old); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(cgrp_kfunc_release_unacquired, struct cgroup *cgrp, const char *path) +{ + /* Cannot release trusted cgroup pointer which was not acquired. */ + bpf_cgroup_release(cgrp); + + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c b/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c new file mode 100644 index 000000000000..9f4569f7598b --- /dev/null +++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ + +#include +#include +#include + +#include "cgrp_kfunc_common.h" + +char _license[] SEC("license") = "GPL"; + +int err, pid, invocations; + +/* Prototype for all of the program trace events below: + * + * TRACE_EVENT(cgroup_mkdir, + * TP_PROTO(struct cgroup *cgrp, const char *path), + * TP_ARGS(cgrp, path) + */ + +static bool is_test_kfunc_task(void) +{ + int cur_pid = bpf_get_current_pid_tgid() >> 32; + bool same = pid == cur_pid; + + if (same) + __sync_fetch_and_add(&invocations, 1); + + return same; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(test_cgrp_acquire_release_argument, struct cgroup *cgrp, const char *path) +{ + struct cgroup *acquired; + + if (!is_test_kfunc_task()) + return 0; + + acquired = bpf_cgroup_acquire(cgrp); + bpf_cgroup_release(acquired); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(test_cgrp_acquire_leave_in_map, struct cgroup *cgrp, const char *path) +{ + long status; + + if (!is_test_kfunc_task()) + return 0; + + status = cgrps_kfunc_map_insert(cgrp); + if (status) + err = 1; + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(test_cgrp_xchg_release, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr; + struct __cgrps_kfunc_map_value *v; + long status; + + if (!is_test_kfunc_task()) + return 0; + + status = cgrps_kfunc_map_insert(cgrp); + if (status) { + err = 1; + return 0; + } + + v = cgrps_kfunc_map_value_lookup(cgrp); + if (!v) { + err = 2; + return 0; + } + + kptr = bpf_kptr_xchg(&v->cgrp, NULL); + if (!kptr) { + err = 3; + return 0; + } + + bpf_cgroup_release(kptr); + + return 0; +} + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(test_cgrp_get_release, struct cgroup *cgrp, const char *path) +{ + struct cgroup *kptr; + struct __cgrps_kfunc_map_value *v; + long status; + + if (!is_test_kfunc_task()) + return 0; + + status = cgrps_kfunc_map_insert(cgrp); + if (status) { + err = 1; + return 0; + } + + v = cgrps_kfunc_map_value_lookup(cgrp); + if (!v) { + err = 2; + return 0; + } + + kptr = bpf_cgroup_kptr_get(&v->cgrp); + if (!kptr) { + err = 3; + return 0; + } + + bpf_cgroup_release(kptr); + + return 0; +} From patchwork Tue Nov 22 05:54:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Vernet X-Patchwork-Id: 24163 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2025168wrr; Mon, 21 Nov 2022 21:58:44 -0800 (PST) X-Google-Smtp-Source: AA0mqf6/pg7iPfRPPzhvRcrWQVjs6l2jAg420KsOX58sJZqYf2FK/iH8q7kYy01FRmWtfvWoHh3I X-Received: by 2002:a17:906:a1cb:b0:781:fcf6:e73a with SMTP id bx11-20020a170906a1cb00b00781fcf6e73amr18090879ejb.352.1669096724111; Mon, 21 Nov 2022 21:58:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669096724; cv=none; d=google.com; s=arc-20160816; b=imMvDIx4e5ew2NugA/79LPX+GocVpA8/wvq7OxCHbSCbEOwQ4fTRsyArcbg3lL9bwf eJGKT0QplyQAwgjAoMrmuCj+nK90veYenGVDkkzwfN6Crwe9MmQ4jEQTKRMZi6FZJzWN Wzz5XFPZxOfhN5t2tpA64sM2q5uun4os31zrG/Xb63W6pT8BmDrLVZaNtBgIgollk4cf HWgJS/OGDvk/bway90r7PUTuKy2EQB5SgbPGKxnWCiL5AHrAAl3N6T+f4uvOEsoshrMd x32GceDzCZ/aeNg3RmyhCjRMTEFXS2k7yionXfZduWaJ6gx8L8RIRI7OsmS+VnauUSw5 azBg== 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=wiOmKcYpqCsWdLOnesBEcBAxMPbH+8h/6qpIynHyMGs=; b=CD1d/2dyR59lbx9wZ13RQSc5DxQUwiGQ2gHIqHLYoksYal4zspkVPysOgJM5Ogmikc tnW2YRc6dvuYq71sDnuhfb+yxf6zFrZXzPZyfvo+tn4N+T5o1JOGwUUdU8GMP1PpyH3u zH5JuntgGam7LCpaHjfXsYCaRn9z9o0XrKJC9sa1cQHyNnz2rZZ4+OHNvUEOZmnF5Cc4 OdUvrHIO5OwXnKYM/9uWD5yT1bseqmHXipkP74SXb0eJmn82TBSU8VOra0JiSiy2c6bt xDBx88k5tq58EdLU6PpLEuDIWkZFf1J3Eagien9iW9V1W3KgOICQZnyFsdjLg+YwMJBV 8YkQ== 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 tc26-20020a1709078d1a00b0078de51e1c3dsi9723552ejc.840.2022.11.21.21.58.20; Mon, 21 Nov 2022 21:58:44 -0800 (PST) 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 S232208AbiKVF4o (ORCPT + 99 others); Tue, 22 Nov 2022 00:56:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232016AbiKVF4S (ORCPT ); Tue, 22 Nov 2022 00:56:18 -0500 Received: from mail-qv1-f42.google.com (mail-qv1-f42.google.com [209.85.219.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EBB72F03F; Mon, 21 Nov 2022 21:55:50 -0800 (PST) Received: by mail-qv1-f42.google.com with SMTP id p8so8841226qvn.5; Mon, 21 Nov 2022 21:55:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=wiOmKcYpqCsWdLOnesBEcBAxMPbH+8h/6qpIynHyMGs=; b=rqWPQWBlHMO70P9jNIqwLJtLTrbELDRwry7HZyTqPEAJW0QQe6MVvKJAU5/xIxPD+1 Zhiuoms8rMN5xIL8RkKg0aUzm3WCP+O7qY7UgvzAd3v9574dTvDHj/jHXq/IzWMDyB6q bsk4x0wmCF99hV9vylz/nSoUekNQSjh3FFYzXiIkChYnEagUPvHKyxWulJYqldibNBSO iMPfoSWcb35izLv0CKr5U/q5XdAhMEG9dn7tEQ+22ScXfYQ3rFQdBBpuYo+WJOXSXdQQ kvBoH4J+PL49w0nD0jAz8k7Y26AfNKLUjkB+cXLScWsruWDmHixdnDh/Y1MO3TO7PJku G69A== X-Gm-Message-State: ANoB5pkhcO+VAUs3SYCHBef46+CmN1aGrQfQLQbKkuSiKwESU+wFamY1 2xGDzPKUWt67wNo8p0opHdYkqrI5qiL1qa0J X-Received: by 2002:a05:6214:102b:b0:4bb:6e51:f98d with SMTP id k11-20020a056214102b00b004bb6e51f98dmr4192654qvr.56.1669096548997; Mon, 21 Nov 2022 21:55:48 -0800 (PST) Received: from localhost ([2620:10d:c091:480::1:3170]) by smtp.gmail.com with ESMTPSA id u18-20020a05620a455200b006cdd0939ffbsm9792962qkp.86.2022.11.21.21.55.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Nov 2022 21:55:48 -0800 (PST) From: David Vernet To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev, yhs@fb.com, song@kernel.org, sdf@google.com, john.fastabend@gmail.com, kpsingh@kernel.org, jolsa@kernel.org, haoluo@google.com, tj@kernel.org, kernel-team@fb.com, linux-kernel@vger.kernel.org Subject: [PATCH bpf-next 3/4] bpf: Add bpf_cgroup_ancestor() kfunc Date: Mon, 21 Nov 2022 23:54:57 -0600 Message-Id: <20221122055458.173143-4-void@manifault.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221122055458.173143-1-void@manifault.com> References: <20221122055458.173143-1-void@manifault.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.5 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 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?1750174766898118381?= X-GMAIL-MSGID: =?utf-8?q?1750174766898118381?= struct cgroup * objects have a variably sized struct cgroup *ancestors[] field which stores pointers to their ancestor cgroups. If using a cgroup as a kptr, it can be useful to access these ancestors, but doing so requires variable offset accesses for PTR_TO_BTF_ID, which is currently unsupported. This is a very useful field to access for cgroup kptrs, as programs may wish to walk their ancestor cgroups when determining e.g. their proportional cpu.weight. So as to enable this functionality with cgroup kptrs before var_off is supported for PTR_TO_BTF_ID, this patch adds a bpf_cgroup_ancestor() kfunc which accesses the cgroup node on behalf of the caller, and acquires a reference on it. Once var_off is supported for PTR_TO_BTF_ID, and fields inside a struct can be marked as trusted so they retain the PTR_TRUSTED modifier when walked, this can be removed. Signed-off-by: David Vernet --- kernel/bpf/helpers.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 420a4251cccc..e4e9db301db5 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1938,6 +1938,25 @@ void bpf_cgroup_release(struct cgroup *cgrp) cgroup_put(cgrp); } + +/** + * bpf_cgroup_ancestor - Perform a lookup on an entry in a cgroup's ancestor + * array. A cgroup returned by this kfunc which is not subsequently stored in a + * map, must be released by calling bpf_cgroup_release(). + * @cgrp: The cgroup for which we're performing a lookup. + * @level: The level of ancestor to look up. + */ +struct cgroup *bpf_cgroup_ancestor(struct cgroup *cgrp, int level) +{ + struct cgroup *ancestor; + + if (level > cgrp->level || level < 0) + return NULL; + + ancestor = cgrp->ancestors[level]; + cgroup_get(ancestor); + return ancestor; +} #endif /* CONFIG_CGROUPS */ void *bpf_cast_to_kern_ctx(void *obj) @@ -1970,6 +1989,7 @@ BTF_ID_FLAGS(func, bpf_task_release, KF_RELEASE) BTF_ID_FLAGS(func, bpf_cgroup_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_cgroup_kptr_get, KF_ACQUIRE | KF_KPTR_GET | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_cgroup_release, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_cgroup_ancestor, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) #endif BTF_SET8_END(generic_btf_ids) From patchwork Tue Nov 22 05:54:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Vernet X-Patchwork-Id: 24162 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2025158wrr; Mon, 21 Nov 2022 21:58:42 -0800 (PST) X-Google-Smtp-Source: AA0mqf7YDwFR5urbH+W77B9UmW/HdGJT1rWN8RtIoNird7SZHjCc+oopfweQLpdE1i7JBaTUXrR8 X-Received: by 2002:a17:907:3117:b0:7ae:6746:f26b with SMTP id wl23-20020a170907311700b007ae6746f26bmr18476324ejb.171.1669096722702; Mon, 21 Nov 2022 21:58:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669096722; cv=none; d=google.com; s=arc-20160816; b=IOgzAymd2vtq+fUZQJF4h9pS4sydOHHQh+YvKXFpCzQPfzmLs1kNDHwuaYzEjw2tOb WYJZJLbEsuPb2A89Ti2lsADCDnGLSGGE7Zg+TN+HxLvQJOIZ07PLSdf6pRdrfoF+K7s+ lZV6XPKO3M3fdarH3dKrjdrqg+FHsEAWwCMNwjCIfC2C7dc9hyH3GvFtB9vPbfGBDiS9 63Es9errvAa8Z7YasrrL28BcP+MAlDcQTlud05gWd01ynP46LjBVnkglnG7lU4L4MeYi RymHLgjqs128Iyxcrg2ExFHTRnqsfJNaUIiXoj/bk3ptVhz6431JfaXgVEL7oUfajsuU pKpg== 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=f0Q962li9LjosC9Js/NBZYh/Sr3ElN5/7bG9cHOxkEk=; b=b6zGuiUFTQ+0uh9nUgjG6cOrT7rD/7lBcsl5AYPN7UfncOmtqR0osR0+deoe12VYEd GkTgzEI025zh6+fgXo3Qav6lzlwCiFDRWZ2hInBMmXInB8VcHzsuteTO/jCFEXjd+1cd MpMUuZhmY/wAwKf7pn8vsxlTzos6KKIUoKrIUZksj5BCdYsbp9ZDgd17yca1Fo/gT+hS WshpCBA6Y/pKwLSCOG0AcPtCEBuUOHeAE0VhU4chHnNe1evcSXVmyElFSFKzJLmay1Fe isHYzMCdQ501fRKbTqLytyt9weDCHkMmwuNxX3Elu4DXzHF0l/PQmiteiVpO1eaFbHoO APFQ== 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 tb26-20020a1709078b9a00b00741a16e8562si10225948ejc.826.2022.11.21.21.58.19; Mon, 21 Nov 2022 21:58:42 -0800 (PST) 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 S232244AbiKVF4x (ORCPT + 99 others); Tue, 22 Nov 2022 00:56:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232119AbiKVF4S (ORCPT ); Tue, 22 Nov 2022 00:56:18 -0500 Received: from mail-qk1-f180.google.com (mail-qk1-f180.google.com [209.85.222.180]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CFAE7264BB; Mon, 21 Nov 2022 21:55:51 -0800 (PST) Received: by mail-qk1-f180.google.com with SMTP id z1so9592916qkl.9; Mon, 21 Nov 2022 21:55:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=f0Q962li9LjosC9Js/NBZYh/Sr3ElN5/7bG9cHOxkEk=; b=7T3tnxDltr3TEe+SxNJcWvo9QgGJUWYSK7ZS8hSrLOnEiiuowi0KAKocF5B3yM7nan POoXWbtVr+5tDdmO0cEhyt45ldbKvun9vl5RFwxx8fc4jy8NMgfErW9bA5b8xpmCj5Yb 8EGGdy+Vrm7sYgEYuFYnQaF+zA78BB9KR3yz1QQ5c+nKeIf6kvJcVm2Z5beuy8ecdWVH zkzuPp3ACy7gK6EPIQNzO4PklekE+/g+2i4NsuAgKuVUHP70T4F74oqmuAcbLC3X8/M5 oC7d1MCgehnKe5w60z3kk12PdoInyNEo//MKWU9RyijsCCzrUUTVFVR/qY2n1shqXuns IQng== X-Gm-Message-State: ANoB5plZiEWINZzQX+vwjFPptvyWbSPqv1ycc7iTh7v9XsLTUkohW4gW b6+3iM+SwacTOdbjmzu+34WIwcVLhu16ZwD2 X-Received: by 2002:a05:620a:2214:b0:6fa:e58e:64e3 with SMTP id m20-20020a05620a221400b006fae58e64e3mr19752385qkh.430.1669096550615; Mon, 21 Nov 2022 21:55:50 -0800 (PST) Received: from localhost ([2620:10d:c091:480::1:3170]) by smtp.gmail.com with ESMTPSA id y28-20020a37f61c000000b006fa22f0494bsm9280633qkj.117.2022.11.21.21.55.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Nov 2022 21:55:50 -0800 (PST) From: David Vernet To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev, yhs@fb.com, song@kernel.org, sdf@google.com, john.fastabend@gmail.com, kpsingh@kernel.org, jolsa@kernel.org, haoluo@google.com, tj@kernel.org, kernel-team@fb.com, linux-kernel@vger.kernel.org Subject: [PATCH bpf-next 4/4] selftests/bpf: Add selftests for bpf_cgroup_ancestor() kfunc Date: Mon, 21 Nov 2022 23:54:58 -0600 Message-Id: <20221122055458.173143-5-void@manifault.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221122055458.173143-1-void@manifault.com> References: <20221122055458.173143-1-void@manifault.com> MIME-Version: 1.0 X-Spam-Status: No, score=-1.5 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 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?1750174765321843126?= X-GMAIL-MSGID: =?utf-8?q?1750174765321843126?= bpf_cgroup_ancestor() allows BPF programs to access the ancestor of a struct cgroup *. This patch adds selftests that validate its expected behavior. Signed-off-by: David Vernet --- .../selftests/bpf/prog_tests/cgrp_kfunc.c | 1 + .../selftests/bpf/progs/cgrp_kfunc_common.h | 1 + .../selftests/bpf/progs/cgrp_kfunc_success.c | 45 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c b/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c index a59b166bbcc4..973f0c5af965 100644 --- a/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c +++ b/tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c @@ -86,6 +86,7 @@ static const char * const success_tests[] = { "test_cgrp_acquire_leave_in_map", "test_cgrp_xchg_release", "test_cgrp_get_release", + "test_cgrp_get_ancestors", }; static struct { diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h b/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h index 3f18def0e45c..7d30855bfe78 100644 --- a/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h +++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h @@ -23,6 +23,7 @@ struct hash_map { struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; struct cgroup *bpf_cgroup_kptr_get(struct cgroup **pp) __ksym; void bpf_cgroup_release(struct cgroup *p) __ksym; +struct cgroup *bpf_cgroup_ancestor(struct cgroup *cgrp, int level) __ksym; static inline struct __cgrps_kfunc_map_value *cgrps_kfunc_map_value_lookup(struct cgroup *cgrp) { diff --git a/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c b/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c index 9f4569f7598b..0c23ea32df9f 100644 --- a/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c +++ b/tools/testing/selftests/bpf/progs/cgrp_kfunc_success.c @@ -123,3 +123,48 @@ int BPF_PROG(test_cgrp_get_release, struct cgroup *cgrp, const char *path) return 0; } + +SEC("tp_btf/cgroup_mkdir") +int BPF_PROG(test_cgrp_get_ancestors, struct cgroup *cgrp, const char *path) +{ + struct cgroup *self, *ancestor1, *invalid; + + if (!is_test_kfunc_task()) + return 0; + + self = bpf_cgroup_ancestor(cgrp, cgrp->level); + if (!self) { + err = 1; + return 0; + } + + if (self->self.id != cgrp->self.id) { + bpf_cgroup_release(self); + err = 2; + return 0; + } + bpf_cgroup_release(self); + + ancestor1 = bpf_cgroup_ancestor(cgrp, cgrp->level - 1); + if (!ancestor1) { + err = 3; + return 0; + } + bpf_cgroup_release(ancestor1); + + invalid = bpf_cgroup_ancestor(cgrp, 10000); + if (invalid) { + bpf_cgroup_release(invalid); + err = 4; + return 0; + } + + invalid = bpf_cgroup_ancestor(cgrp, -1); + if (invalid) { + bpf_cgroup_release(invalid); + err = 5; + return 0; + } + + return 0; +}