From patchwork Wed Jan 31 14:54:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 13539534 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAF5E12F587 for ; Wed, 31 Jan 2024 14:55:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712937; cv=none; b=A23OM+E8aiLQwC9ZqTsiVq49okEhpT25NW1jsS2/Vzk2hbtWTm0Ov03mY4kuqaJFz1+tgfID2YjEnhjNvmK9rZph2lAqs+LYcrChhZFSyZKWRXkjs4xCOcm67hCAg+w2rtnKJdPZon9+IMc/0o0h4P8A/yU1FhPpIpoIZr9VA7g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712937; c=relaxed/simple; bh=SV/alju8O5rBWg2UnQnqw7IiLPn/TxUJ41GVbFTyf4M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WhmelPKtHPFvijmjZCiKYEvQHQQyMTxDzSdKPDu07PT8WtMZ3GfYEFkqbeBtZ/bwo6pzweIil2gsVUVG8spyIkI6m3sRnwVmobXc0bMMrxIda5nxbWLeNj3sWLmvCN0QhwQ9Rtvh+nasY7Uj568tvHEum4u/MWqMlzsx9HuR2YA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=T7duCC0B; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T7duCC0B" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1d70b0e521eso37298705ad.1 for ; Wed, 31 Jan 2024 06:55:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706712935; x=1707317735; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CJRiE60KIROO/fALmRIpLzxZTaCorFhBQTkcmFOCFCI=; b=T7duCC0Be+Bg+g8faX/7ZE9OhX2fZSacltNWZBCr91KvTd3QuxudJOLVM7YCMGv6CJ 0sD9WFxOlFVnrRv+dhtmQJKzsfK6f8PCuyn/P20bdQZALgD/1Fdgvsr2xKDZjaoOHI02 3dKBXS6bMMDnmTWIlueE42vdFP3Tan1b7KPYTyXzrx3dZRN1IPDDoghKfasL0/wRXdSo FKt6eMYHYL2zRw5/oxlqqASwOOESeNLOdIGSpGt8s4l4g+V/sGSmBY9ijrsDLhhYpoET SfvcAC4WqXzHXBdWG5p8N9z8NQdjOQo/gOzpkenEwKRDZ6KxG4G3lMiRKJYVdkfeR8kR 3sUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706712935; x=1707317735; 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=CJRiE60KIROO/fALmRIpLzxZTaCorFhBQTkcmFOCFCI=; b=FgeV29iA2R1DmaBIw4HC3QzqpplwJk62+f1wH/WwBYoyE07UIyir1ozBRhPuZA68j0 lgYg/N7XKFQCgUjwPxeIxsyUG11a6HvF/SqcQMs5HDNUwoCycBi6i22GnyasC6qzfT0j X5dw9O0CVWg8kr2If0XabOdjfKxfDYLQjSHk3orsXtHqR2Y3OtLfRNIFiEfAjw8vzEgt mUl8ZhVrPj5rEapNbRMMifMCcPt2EvKdG/+EbZz/TWi5O0+sCcN2qpCE0w/kukYmuogA 2fnnc6eYnxW8Gsmb8pZQxBJQ6TuhPAbOMlZzUjfy6NxV925r+zUWyOewlx3sVtWTGCE9 qn6Q== X-Gm-Message-State: AOJu0Yza+YKy6BD2bMcnhxbuwNwKeTsH3HpEYz5RYmN+DPqOT2+h2pwR yWwwB1U3pBK2WYzQoC8JMTe8hF+7Qo+VUl/6/EM3xSQtQUCOyQNM X-Google-Smtp-Source: AGHT+IGbub3XqlbAoeJVByIc2rBgT48fA193T5TVQRWPHoeuHi3pIhtFZlwGVhP9nWE1J93dcwACAg== X-Received: by 2002:a17:902:ec82:b0:1d9:55b:6a17 with SMTP id x2-20020a170902ec8200b001d9055b6a17mr2421501plg.18.1706712934897; Wed, 31 Jan 2024 06:55:34 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCV5VVvoAn+a6x8Ee8D/mwZSJvaRAnlQrcUaLqhT8qnecMo5BSQwtx/E6eiatMqHLHnIwkAjxwfPvOEnn1ABGXA+1H1FXLQFev9DO61xogKyK+i+mQxsknC6qTs83hMNTQjZvyV4muw4F/i2Ydp1avx8PzltjYnC6cMKBkkKl5SJFAmx/L1PsrDpfBKQUZbEAdkUQMSe59IuNDR+EnFUXkka9xEcbvH5DS2D7oiLA2WE36xXRA1sWY5aCm/om6O5rx5haAi6O14j9Bt3E3WTdTCkeV9ihiuk3+ZX6lSVlP/nCscGSHVSD9ctUyhGYMRF87GPpB+hrerdsaBmPMSPQLWlxTZFtjAM/l6EtRkrXuwdcvkNgMjuVzoTXLanQ903Ttats2fSbMz4tOl+qR3tVCNej6ra Received: from localhost.localdomain ([183.193.177.147]) by smtp.gmail.com with ESMTPSA id s5-20020a170902a50500b001d8fe6cd0aasm3901335plq.286.2024.01.31.06.55.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jan 2024 06:55:34 -0800 (PST) From: Yafang Shao To: ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, tj@kernel.org, void@manifault.com Cc: bpf@vger.kernel.org, Yafang Shao Subject: [PATCH v5 bpf-next 1/4] bpf: Add bpf_iter_cpumask kfuncs Date: Wed, 31 Jan 2024 22:54:51 +0800 Message-Id: <20240131145454.86990-2-laoar.shao@gmail.com> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20240131145454.86990-1-laoar.shao@gmail.com> References: <20240131145454.86990-1-laoar.shao@gmail.com> 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 Add three new kfuncs for bpf_iter_cpumask. - bpf_iter_cpumask_new KF_RCU is defined because the cpumask must be a RCU trusted pointer such as task->cpus_ptr. - bpf_iter_cpumask_next - bpf_iter_cpumask_destroy These new kfuncs facilitate the iteration of percpu data, such as runqueues, psi_cgroup_cpu, and more. Signed-off-by: Yafang Shao --- kernel/bpf/cpumask.c | 82 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/kernel/bpf/cpumask.c b/kernel/bpf/cpumask.c index 2e73533a3811..c6019368d6b1 100644 --- a/kernel/bpf/cpumask.c +++ b/kernel/bpf/cpumask.c @@ -422,6 +422,85 @@ __bpf_kfunc u32 bpf_cpumask_weight(const struct cpumask *cpumask) return cpumask_weight(cpumask); } +struct bpf_iter_cpumask { + __u64 __opaque[2]; +} __aligned(8); + +struct bpf_iter_cpumask_kern { + struct cpumask *mask; + int cpu; +} __aligned(8); + +/** + * bpf_iter_cpumask_new() - Create a new bpf_iter_cpumask for a specified cpumask + * @it: The new bpf_iter_cpumask to be created. + * @mask: The cpumask to be iterated over. + * + * This function initializes a new bpf_iter_cpumask structure for iterating over + * the specified CPU mask. It assigns the provided cpumask to the newly created + * bpf_iter_cpumask @it for subsequent iteration operations. + * + * On success, 0 is returen. On failure, ERR is returned. + */ +__bpf_kfunc int bpf_iter_cpumask_new(struct bpf_iter_cpumask *it, const struct cpumask *mask) +{ + struct bpf_iter_cpumask_kern *kit = (void *)it; + + BUILD_BUG_ON(sizeof(struct bpf_iter_cpumask_kern) > sizeof(struct bpf_iter_cpumask)); + BUILD_BUG_ON(__alignof__(struct bpf_iter_cpumask_kern) != + __alignof__(struct bpf_iter_cpumask)); + + kit->mask = bpf_mem_alloc(&bpf_global_ma, cpumask_size()); + if (!kit->mask) + return -ENOMEM; + + cpumask_copy(kit->mask, mask); + kit->cpu = -1; + return 0; +} + +/** + * bpf_iter_cpumask_next() - Get the next CPU in a bpf_iter_cpumask + * @it: The bpf_iter_cpumask + * + * This function retrieves a pointer to the number of the next CPU within the + * specified bpf_iter_cpumask. It allows sequential access to CPUs within the + * cpumask. If there are no further CPUs available, it returns NULL. + * + * Returns a pointer to the number of the next CPU in the cpumask or NULL if no + * further CPUs. + */ +__bpf_kfunc int *bpf_iter_cpumask_next(struct bpf_iter_cpumask *it) +{ + struct bpf_iter_cpumask_kern *kit = (void *)it; + const struct cpumask *mask = kit->mask; + int cpu; + + if (!mask) + return NULL; + cpu = cpumask_next(kit->cpu, mask); + if (cpu >= nr_cpu_ids) + return NULL; + + kit->cpu = cpu; + return &kit->cpu; +} + +/** + * bpf_iter_cpumask_destroy() - Destroy a bpf_iter_cpumask + * @it: The bpf_iter_cpumask to be destroyed. + * + * Destroy the resource assiciated with the bpf_iter_cpumask. + */ +__bpf_kfunc void bpf_iter_cpumask_destroy(struct bpf_iter_cpumask *it) +{ + struct bpf_iter_cpumask_kern *kit = (void *)it; + + if (!kit->mask) + return; + bpf_mem_free(&bpf_global_ma, kit->mask); +} + __bpf_kfunc_end_defs(); BTF_SET8_START(cpumask_kfunc_btf_ids) @@ -450,6 +529,9 @@ BTF_ID_FLAGS(func, bpf_cpumask_copy, KF_RCU) BTF_ID_FLAGS(func, bpf_cpumask_any_distribute, KF_RCU) BTF_ID_FLAGS(func, bpf_cpumask_any_and_distribute, KF_RCU) BTF_ID_FLAGS(func, bpf_cpumask_weight, KF_RCU) +BTF_ID_FLAGS(func, bpf_iter_cpumask_new, KF_ITER_NEW | KF_RCU) +BTF_ID_FLAGS(func, bpf_iter_cpumask_next, KF_ITER_NEXT | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_iter_cpumask_destroy, KF_ITER_DESTROY) BTF_SET8_END(cpumask_kfunc_btf_ids) static const struct btf_kfunc_id_set cpumask_kfunc_set = { From patchwork Wed Jan 31 14:54:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 13539535 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6195512DDBE for ; Wed, 31 Jan 2024 14:55:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712941; cv=none; b=nkvNLb0RDLTtNBKRp5BJA5VHY71SjdYaRIXsl/XA9wQDMz152oNItrI/5p4MleqBYZpHZm++KUw3X9z4N1LawlMNQr8jw1C1dCxDgEUlzyk73qlpJl/p/VV9PGMDX5kv8vYrZ2uKUW5qa8u1KiFDf9KuokFd9FU+XdT/P1sx74Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712941; c=relaxed/simple; bh=HV8zE7fC7esadDPJK8IeoUfZuj4hhuaCLWwcNh2tp/U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=b43BipUkAHz+i2+AFdhbXFsANOmL+Tu86EcgjauzSMN3HcMQcmzCPa7Ti8wURPg1AJYUFru1nEnh1Z4J9IHniB5jRL4mVcp5CTv8D9iTtCAEegOAFX63FWKvsAhlpy37XdkaLfeKqcbPeIgQMxR3luCOiQxgxzxRwC8gbGHfOQg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VwuHe6I2; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VwuHe6I2" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1d918008b99so11836615ad.3 for ; Wed, 31 Jan 2024 06:55:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706712939; x=1707317739; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wlM6tuTN+NL34agtMlc0l/gUFiWkbI8BqHZCZ22lzIo=; b=VwuHe6I2+wKO+hc8k8viUNkBv4a2qOunIzrao36HgcyduTjChw+oXuBTueGoOR4qLi WyZWyNZfIAb9KjEv+Uzn9GiLYnv3rO2wA85Nbt5ELZBw51oEaLsw/3TnIIF3als2hodr LdCzdYel98rH7ysOHG6vNnMkd+PyHwhx1d2WXiH+GV4sf4mRXQiCRU4JhJeCiSmzzGdz Hma6xQUNW1bJv/aPTFe4AuyEyaW/VCnJMjepJ1Dbjzxkf+BHYta3d2FxLTwFUMrH+dQQ ZDr1Rx6yQLggH0ZWr1wWyvf3R5KiCuKvpikOdOJwqValgSPrdA9g0VLyC3P1whTLteTX /37Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706712939; x=1707317739; 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=wlM6tuTN+NL34agtMlc0l/gUFiWkbI8BqHZCZ22lzIo=; b=dIm1x5VeguFplIXSlQPOYNPrlznGfde0vjaJ9nK2nYGEMUGUDNmDWk+JTn56rm/Ovj hQy7vrRGpucDVkpwJ8fKmO1UwaDmOtnYvJLiervviqiEKHXsAnkgTDoTZMJ27zSAFhcJ 2yhGbjMl+HJt+x5qpiYBR3iZx+2I/6N5MskToGtevRdYm0NkJmWJKOIeGOa+TPCWM19O Nv4SLb/Q2VPnZj/CBwUzZBXfDznlldyiQ5XGKsoKgAnNKG4wYfgsIqYMyVwSd+IM4Gok ioAIpoUIFEjDApvo6PC5fciGuE1BjikpjICp6eVSmYbdpWJzaH+7wTWX+Q+PVVQ0XDss zcsA== X-Gm-Message-State: AOJu0Yz2YvviRHdLsrnp/22/QTieqYOQ/QrPLjJq9JUx8wIbl8joKJ2Z jQU6+vEyr5I8r5WpFBRPXA4YZaq42KPWblwmHGscvB0yRmCSz0Ad X-Google-Smtp-Source: AGHT+IFVXBYWAjado0VmaeEJ/cJY/PU3kBrUI0MSG8RqhFs2+HfWIueR33o2o1AubOlRc1Toq0BfmA== X-Received: by 2002:a17:903:41c9:b0:1d9:3d72:b296 with SMTP id u9-20020a17090341c900b001d93d72b296mr673384ple.35.1706712939574; Wed, 31 Jan 2024 06:55:39 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCWa7LvZOpYtqTuThTfyh+h3cWraMODUEpQxZP6hZhJrXQIGdtZpCMKWJ4qLl6cHA0NDQWzKXZ4AXu/ulmVA6ln4h6bFc6SSXNnW4u7APEGATE5h0IcPaES4pC3fie578ZUtFcF55jWwyoOeyIwX6fxsyg2aFMfoVWH/GZyit1eeWlOEwZTsJ1cuvbqk6UHCzQHLQK1PXK4goVJoY+tYWmxFTpogAL29C0VXqXUcdSAX/rnx+F0GBDSLKf8UcxdppQ0MjEZOdh1A82JSc2jGSOvMCo/MthnwW53ojmsmeUAZOiVgmh0se5KFHrIwziKg8XJWd48mijWXQVmDNX2jxPwBcVjajCx3HEPzinYo42rfsiqealgqCH7ql6DzI+/MitXWaj1QH94Sk5THaSCM7c/U4+mk Received: from localhost.localdomain ([183.193.177.147]) by smtp.gmail.com with ESMTPSA id s5-20020a170902a50500b001d8fe6cd0aasm3901335plq.286.2024.01.31.06.55.35 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jan 2024 06:55:38 -0800 (PST) From: Yafang Shao To: ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, tj@kernel.org, void@manifault.com Cc: bpf@vger.kernel.org, Yafang Shao Subject: [PATCH v5 bpf-next 2/4] bpf, docs: Add document for cpumask iter Date: Wed, 31 Jan 2024 22:54:52 +0800 Message-Id: <20240131145454.86990-3-laoar.shao@gmail.com> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20240131145454.86990-1-laoar.shao@gmail.com> References: <20240131145454.86990-1-laoar.shao@gmail.com> 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 This patch adds the document for the newly added cpumask iterator kfuncs. Signed-off-by: Yafang Shao Acked-by: Andrii Nakryiko --- Documentation/bpf/cpumasks.rst | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/Documentation/bpf/cpumasks.rst b/Documentation/bpf/cpumasks.rst index b5d47a04da5d..5cedd719874c 100644 --- a/Documentation/bpf/cpumasks.rst +++ b/Documentation/bpf/cpumasks.rst @@ -372,6 +372,66 @@ used. .. _tools/testing/selftests/bpf/progs/cpumask_success.c: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/tools/testing/selftests/bpf/progs/cpumask_success.c +3.3 cpumask iterator +-------------------- + +The cpumask iterator facilitates the iteration of per-CPU data, including +runqueues, system_group_pcpu, and other such structures. To leverage the cpumask +iterator, one can employ the bpf_for_each() macro. + +Here's an example illustrating how to determine the number of running tasks on +each CPU. + +.. code-block:: c + + /** + * Here's an example demonstrating the functionality of the cpumask iterator. + * We retrieve the cpumask associated with the specified pid, iterate through + * its elements, and ultimately expose per-CPU data to userspace through a + * seq file. + */ + const struct rq runqueues __ksym __weak; + u32 target_pid; + + SEC("iter/cgroup") + int BPF_PROG(cpu_cgroup, struct bpf_iter_meta *meta, struct cgroup *cgrp) + { + u32 nr_running = 0, nr_cpus = 0, nr_null_rq = 0; + struct task_struct *p; + struct rq *rq; + int *cpu; + + /* epilogue */ + if (cgrp == NULL) + return 0; + + p = bpf_task_from_pid(target_pid); + if (!p) + return 1; + + BPF_SEQ_PRINTF(meta->seq, "%4s %s\n", "CPU", "nr_running"); + bpf_for_each(cpumask, cpu, p->cpus_ptr) { + rq = (struct rq *)bpf_per_cpu_ptr(&runqueues, *cpu); + if (!rq) { + nr_null_rq += 1; + continue; + } + nr_cpus += 1; + + if (!rq->nr_running) + continue; + + nr_running += rq->nr_running; + BPF_SEQ_PRINTF(meta->seq, "%4u %u\n", *cpu, rq->nr_running); + } + BPF_SEQ_PRINTF(meta->seq, "Summary: nr_cpus %u, nr_running %u, nr_null_rq %u\n", + nr_cpus, nr_running, nr_null_rq); + + bpf_task_release(p); + return 0; + } + +---- 4. Adding BPF cpumask kfuncs ============================ From patchwork Wed Jan 31 14:54:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 13539536 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41AE512836C for ; Wed, 31 Jan 2024 14:55:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712946; cv=none; b=Oxrg4NyRkLLNo1P9rEeifjLxjt7SkBW2Xh0qk6jGtGMFiwAdsQ9/yUOdlipS+agERvOu9gFpwvU5g3w6BCqaiWW6YUP/duAbSe/a78BYUzICT2aWU/QwOaUrZoR9jyUTiXwqAQ30ezWvz651G054+lgM+B8Ey/xHtlaiY/dpmWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712946; c=relaxed/simple; bh=GJ21JTHXYe+0v37BT2RQZiKKXCM1Qqmf3ADdyP0hf+M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IJ3WA68duADv5zLaJhqO48FC3y0fd/N3J+7rD0sVO6puMdrb1SyW4lbYp9umH0+mQn2FvOw+/Br1HvvdFsEh9puJtwzUeyFAu7N89VY1SP+sEjU3FkKdK4Z00y+BVci01HWZ+N4PJCC+zNQW7kH7MksIxbsiIrlhWQf6FSysmn4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WrBKPrsD; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WrBKPrsD" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-1d8a66a2976so46501235ad.2 for ; Wed, 31 Jan 2024 06:55:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706712944; x=1707317744; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=WfA93j+zCEyICFj+8kPtyCRIcBQNWyTBKzbW+zoagdw=; b=WrBKPrsDk9ljlRLGN4GtMNLaVea9SROZTRndpbYHYKN9i6CuPn7kzNgobNP01WBTF6 UWCBXfojePoEui5U20riTOYypfgjD7+e6+hlUxaxBuMwyVzPbm2v4V/iDggprcPdaTi3 1meAOXxmvEBQ9VEpaDrHeMlWhqdLS1oED8Ev+IaENzDZhr3Dmyu5xB1KzoxG6sThSeQP J8j5UC9KFLRzqCHVbrcxpraqI0eKYOBTMHMi/3KGoaloBe3myWk87CcuRCPg4eQMMk38 h1X+WGDp3Gi2pheUsUklK/zoDj6N02dlOFCupZ85Z/r5i8cGVtEkn0v/3Lf7DEr+SaY+ OtXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706712944; x=1707317744; 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=WfA93j+zCEyICFj+8kPtyCRIcBQNWyTBKzbW+zoagdw=; b=IboB9lpLtD7qYdTB9y1HIqv3ebSBJkPdutwtiBAfTu/Drr7BXHK5T8z28bghH+hWwX Fmj4YanqNoRZnif4DOHNbfjxt/DPciUAr37BuoYa7atdoyKLXPmlrFaCkOE8qT2lZovu 8hQO6v4YXDiTyqs5HqHBNywxTUDpK6vuO3LJZu+ybk/43I7QxUNzuuxXBsQwnWIikd5+ 4ZFZPLF9QVxPjUAgeiQMmahqarl++vBQ62RCzVFC+JqinCNvqH+NJ0b8StRS4OWdxUgL AdCH6qby4ciiN0uOHepEkx8WBD4HTOYON7QIQx+TAmi7fSfRpikxX0vs1pzovWtIa+iU bbAg== X-Gm-Message-State: AOJu0Yw2qskt6pjl/4UBslA+AAIY6dqth1AP76NoLptuqa3vBwiyUb8z hAWwHugfFXhso8CEYl+/4ijpZaJ7ZoR3EPAEOubW2D+s3dkIm778gA/+OQoi4BvFekMN X-Google-Smtp-Source: AGHT+IFDKR+r2uoNP9w0sjoN0eWDlxt52QG4sTjeNvUCUZKC1csZRC8ErFrPj/h5oZRpGzdl7FNl7w== X-Received: by 2002:a17:902:f812:b0:1d7:6bac:5f1e with SMTP id ix18-20020a170902f81200b001d76bac5f1emr1489917plb.11.1706712944474; Wed, 31 Jan 2024 06:55:44 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCWeXxiANXGcvHBW1bp9OVp6eYeUMu0B7es6i9VEq+wRKemoznPEiqWu+y2imI4T5zHEyBxkp+93xpuUIZBmaDpFgoRbLdAyAn5Mh0SdKHo44X5fX/20QPUZmsnhI+bq49gHEIXBHOkzC1zV3/hoyToscIJuHtcq9ZytnU34KLkNdYWvtu0frDYZGfrbE53WvXE2uNosxvkLz933cfD/ZAcFfPpgrnCVA7UJv00KXwrRAHuLpg+CgdjEQE5N8hCGcRftJso81ItXM+Fc1tk+Vy90i0rFa/aTf9iFj8m69PLUVkR+YZ8zNLtkUyI8WpGRhaLPQ1sZsdoyplVLNSrPm8T1AbTB4cEWHnQh9EMJHBVfkW/iho7fuXLVj/cZKS41Xk7HrlqjRus8wkUNq3w9uLZ3Pah7 Received: from localhost.localdomain ([183.193.177.147]) by smtp.gmail.com with ESMTPSA id s5-20020a170902a50500b001d8fe6cd0aasm3901335plq.286.2024.01.31.06.55.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jan 2024 06:55:43 -0800 (PST) From: Yafang Shao To: ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, tj@kernel.org, void@manifault.com Cc: bpf@vger.kernel.org, Yafang Shao Subject: [PATCH v5 bpf-next 3/4] selftests/bpf: Fix error checking for cpumask_success__load() Date: Wed, 31 Jan 2024 22:54:53 +0800 Message-Id: <20240131145454.86990-4-laoar.shao@gmail.com> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20240131145454.86990-1-laoar.shao@gmail.com> References: <20240131145454.86990-1-laoar.shao@gmail.com> 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 We should verify the return value of cpumask_success__load(). Signed-off-by: Yafang Shao Cc: David Vernet Acked-by: Andrii Nakryiko --- tools/testing/selftests/bpf/prog_tests/cpumask.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/cpumask.c b/tools/testing/selftests/bpf/prog_tests/cpumask.c index c2e886399e3c..ecf89df78109 100644 --- a/tools/testing/selftests/bpf/prog_tests/cpumask.c +++ b/tools/testing/selftests/bpf/prog_tests/cpumask.c @@ -27,7 +27,7 @@ static void verify_success(const char *prog_name) struct bpf_program *prog; struct bpf_link *link = NULL; pid_t child_pid; - int status; + int status, err; skel = cpumask_success__open(); if (!ASSERT_OK_PTR(skel, "cpumask_success__open")) @@ -36,8 +36,8 @@ static void verify_success(const char *prog_name) skel->bss->pid = getpid(); skel->bss->nr_cpus = libbpf_num_possible_cpus(); - cpumask_success__load(skel); - if (!ASSERT_OK_PTR(skel, "cpumask_success__load")) + err = cpumask_success__load(skel); + if (!ASSERT_OK(err, "cpumask_success__load")) goto cleanup; prog = bpf_object__find_program_by_name(skel->obj, prog_name); From patchwork Wed Jan 31 14:54:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yafang Shao X-Patchwork-Id: 13539537 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C349D5A7A1 for ; Wed, 31 Jan 2024 14:55:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712951; cv=none; b=RrZRYCl59dr5rwXhMMDjXSchoZq3oqxIb+IaB7n+h+d9yXVtDHudCv/fgFrOT8eccPvlRzLAflP+ZSenuou2XLpUHIGp91eDh6O1MzbSiAuUjHL0w+vkqJWZV63SLBAoUJvTXs+OX42VIZDNKnKIirhY90g6D7f1Z5P/MaKnrf4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706712951; c=relaxed/simple; bh=QO5MIjxJ7/x8+8ylOf3p3QOCyCIxltZM6GSyZXgPXEA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=S8BM/ybHuDQm84vxrHRGZ7hFxMy2PKnFkiL6xUAowJsNLUl8eiYp+5HCK4ZADcZV2Z7kViJW8qTVqM1xD3Z8KY+J4ZHsNGt1LgpX/AvKM04BCPnc+PkUUnhlxVXeYvz9wp8gsILV/P0D6RrjxOpBUvYkPNHwJb2ySvUfJl90Rc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bK9IRsxg; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bK9IRsxg" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-1d911c9240dso13929485ad.2 for ; Wed, 31 Jan 2024 06:55:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706712949; x=1707317749; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oSzFTJ0yiPmz775UN9q2r6hu07LtuGqAxTUcHaz+IlI=; b=bK9IRsxgOYINgoRjAFVckLVR1GUUDgD4UVhOujgJ7VJt5PLCt5nOlf+YJKAWKPzlJG RJpa6N8TFmP0hL7ZwzFMWNX36DoIYkpW8iIrTfOj3558u1e2rgvqjbWhmmZnYcapuwU+ NF2O36WizN1cDVxPEgmdj/owYHSuo8fTDosLaamM85GC149F9I739zCFqeH4m/DAUT9+ K8IaNWYs0FlocZQmMS+14bqcgfFgv/P+C14dWOyfqXZtWAhLMchU0ZMej5IxFGAHPhhG I+txIV+7JRtI7+Z+lDaOWbsS/SSteSZaVLhe6R8pHKwyfTPbogeljPuAWcw4XJ7/KIFv v3MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706712949; x=1707317749; 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=oSzFTJ0yiPmz775UN9q2r6hu07LtuGqAxTUcHaz+IlI=; b=EFWP0QJi6wSFC/SLMOUAY40SDbGnLbnoiNnPtUaqtXF1QhUdkPughaw6GZVHlm2GOn C3s3lRqoyX6b4lfDjTSh9VUqnkhqUhf+zVIw8UNk45mviBEafwin2+gN8mYFtdmPsfOS HWy+2B1q5fwtZZqrcJ6e7fYtwvFR+uqfHqfqDNPI0kI5EGD7IPqA58BaWuT+nDyi44q4 pDOb4I89pGUN8M5NQOIwMxfpAdkbcoaGzYwc69VV1/UfacCduvehqSPPp2kMxJpqHPBs ewee27KLz/VKKISHHpQgXfhtvbDhg3QTwNgQB2NzuSZfgdrEsgFN9gteVf/MH4LCuAy9 jEVg== X-Gm-Message-State: AOJu0YwK0eBhbN4R0xCsaJpMrY2dhtzUCHLMcBap5JTB8Q8aJRso/ZOE CXsvI6p2V6btyBHt/NW8ydr1xhJs/PvkNtr2bulcrfQYpgv5RDpB X-Google-Smtp-Source: AGHT+IFEOsqUO6HTqtMz6F1EKFa57X3q0cnCdIJGTF6DHnZk7h4m4iZEChQtkll6NUyenNOAJdJShw== X-Received: by 2002:a17:902:e804:b0:1d7:357c:b87 with SMTP id u4-20020a170902e80400b001d7357c0b87mr2005780plg.51.1706712948772; Wed, 31 Jan 2024 06:55:48 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCU4F0NUtkFsJfyd/1r5ay6qJZyMpi2dierEuFAhDf3whtFgveayOHEeD+JuvWcvpbXLmxkA95SepB1wFDE3F31T+B87RLxmnJlilLPCoTp650NykXw2ZJX/vMVEA3W86l8VH9bmD8+a3IHkDYJhYQx7TIDlr1UtIxVwq8tX47w8pDmGo9oFmj38rw5qyAOgYzRH+xbXAGGr5dZ2lYmE+3bcUkWZq0mQBYVusF5ImrnyPg14XzZkKjvPCR++epE+4hWiM13ABIlqn7WbWiUgKYULPf2jVAsAaUrWwUHdPp2jLwB1Xxcl1ZJcAoK3wOMuzUg6X3766Ja1gbHbIxXBXEBsctmtSoqnhmWmpQg36iKaLcnDeJGSnIE9VjtOM7VpFMZziXsD++x9Jn/8Zfj+pkYeBreL Received: from localhost.localdomain ([183.193.177.147]) by smtp.gmail.com with ESMTPSA id s5-20020a170902a50500b001d8fe6cd0aasm3901335plq.286.2024.01.31.06.55.44 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jan 2024 06:55:48 -0800 (PST) From: Yafang Shao To: ast@kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, andrii@kernel.org, martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, tj@kernel.org, void@manifault.com Cc: bpf@vger.kernel.org, Yafang Shao Subject: [PATCH v5 bpf-next 4/4] selftests/bpf: Add selftests for cpumask iter Date: Wed, 31 Jan 2024 22:54:54 +0800 Message-Id: <20240131145454.86990-5-laoar.shao@gmail.com> X-Mailer: git-send-email 2.30.1 (Apple Git-130) In-Reply-To: <20240131145454.86990-1-laoar.shao@gmail.com> References: <20240131145454.86990-1-laoar.shao@gmail.com> 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 Add selftests for the newly added cpumask iter. - cpumask_iter_success - The number of CPUs should be expected when iterating over the cpumask - percpu data extracted from the percpu struct should be expected - It can work in both non-sleepable and sleepable prog - RCU lock is only required by bpf_iter_cpumask_new() - It is fine without calling bpf_iter_cpumask_next() - cpumask_iter_failure - RCU lock is required in sleepable prog - The cpumask to be iterated over can't be NULL - bpf_iter_cpumask_destroy() is required after calling bpf_iter_cpumask_new() - bpf_iter_cpumask_destroy() can only destroy an initilialized iter - bpf_iter_cpumask_next() must use an initilialized iter The result as follows, #64/37 cpumask/test_cpumask_iter:OK #64/38 cpumask/test_cpumask_iter_sleepable:OK #64/39 cpumask/test_cpumask_iter_sleepable:OK #64/40 cpumask/test_cpumask_iter_next_no_rcu:OK #64/41 cpumask/test_cpumask_iter_no_next:OK #64/42 cpumask/test_cpumask_iter:OK #64/43 cpumask/test_cpumask_iter_no_rcu:OK #64/44 cpumask/test_cpumask_iter_no_destroy:OK #64/45 cpumask/test_cpumask_iter_null_pointer:OK #64/46 cpumask/test_cpumask_iter_next_uninit:OK #64/47 cpumask/test_cpumask_iter_destroy_uninit:OK #64 cpumask:OK Signed-off-by: Yafang Shao --- tools/testing/selftests/bpf/config | 1 + .../selftests/bpf/prog_tests/cpumask.c | 152 ++++++++++++++++++ .../selftests/bpf/progs/cpumask_common.h | 3 + .../bpf/progs/cpumask_iter_failure.c | 99 ++++++++++++ .../bpf/progs/cpumask_iter_success.c | 126 +++++++++++++++ 5 files changed, 381 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/cpumask_iter_failure.c create mode 100644 tools/testing/selftests/bpf/progs/cpumask_iter_success.c diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config index 01f241ea2c67..dd4b0935e35f 100644 --- a/tools/testing/selftests/bpf/config +++ b/tools/testing/selftests/bpf/config @@ -78,6 +78,7 @@ CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_DEFRAG_IPV4=y CONFIG_NF_DEFRAG_IPV6=y CONFIG_NF_NAT=y +CONFIG_PSI=y CONFIG_RC_CORE=y CONFIG_SECURITY=y CONFIG_SECURITYFS=y diff --git a/tools/testing/selftests/bpf/prog_tests/cpumask.c b/tools/testing/selftests/bpf/prog_tests/cpumask.c index ecf89df78109..78423745689c 100644 --- a/tools/testing/selftests/bpf/prog_tests/cpumask.c +++ b/tools/testing/selftests/bpf/prog_tests/cpumask.c @@ -1,9 +1,15 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ +#define _GNU_SOURCE +#include + #include #include "cpumask_failure.skel.h" #include "cpumask_success.skel.h" +#include "cpumask_iter_success.skel.h" +#include "cpumask_iter_failure.skel.h" +#include "cgroup_helpers.h" static const char * const cpumask_success_testcases[] = { "test_alloc_free_cpumask", @@ -61,6 +67,142 @@ static void verify_success(const char *prog_name) cpumask_success__destroy(skel); } +static const char * const cpumask_iter_success_testcases[] = { + "test_cpumask_iter", + "test_cpumask_iter_sleepable", +}; + +static int read_percpu_data(struct bpf_link *link, int nr_cpu_exp, int nr_running_exp) +{ + int iter_fd, len, item, nr_running, psi_running, nr_cpus, err = -1; + char buf[128]; + size_t left; + char *p; + + iter_fd = bpf_iter_create(bpf_link__fd(link)); + if (!ASSERT_GE(iter_fd, 0, "iter_fd")) + return -1; + + memset(buf, 0, sizeof(buf)); + left = ARRAY_SIZE(buf); + p = buf; + while ((len = read(iter_fd, p, left)) > 0) { + p += len; + left -= len; + } + + item = sscanf(buf, "nr_running %u nr_cpus %u psi_running %u\n", + &nr_running, &nr_cpus, &psi_running); + if (!ASSERT_EQ(item, 3, "seq_format")) + goto out; + if (!ASSERT_EQ(nr_cpus, nr_cpu_exp, "nr_cpus")) + goto out; + if (!ASSERT_GE(nr_running, nr_running_exp, "nr_running")) + goto out; + if (!ASSERT_GE(psi_running, nr_running_exp, "psi_running")) + goto out; + + err = 0; +out: + close(iter_fd); + return err; +} + +static void verify_iter_success(const char *prog_name) +{ + DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts); + int cgrp_fd, nr_cpus, err, i, chosen = 0; + struct cpumask_iter_success *skel; + union bpf_iter_link_info linfo; + struct bpf_program *prog; + struct bpf_link *link; + cpu_set_t set; + + if (setup_cgroup_environment()) + return; + + /* Utilize the cgroup iter */ + cgrp_fd = get_root_cgroup(); + if (!ASSERT_GE(cgrp_fd, 0, "create_cgrp")) + goto cleanup; + + skel = cpumask_iter_success__open(); + if (!ASSERT_OK_PTR(skel, "cpumask_iter_success__open")) + goto close_fd; + + skel->bss->pid = getpid(); + nr_cpus = libbpf_num_possible_cpus(); + + err = cpumask_iter_success__load(skel); + if (!ASSERT_OK(err, "cpumask_iter_success__load")) + goto destroy; + + prog = bpf_object__find_program_by_name(skel->obj, prog_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto destroy; + + memset(&linfo, 0, sizeof(linfo)); + linfo.cgroup.cgroup_fd = cgrp_fd; + linfo.cgroup.order = BPF_CGROUP_ITER_SELF_ONLY; + opts.link_info = &linfo; + opts.link_info_len = sizeof(linfo); + link = bpf_program__attach_iter(prog, &opts); + if (!ASSERT_OK_PTR(link, "bpf_program__attach")) + goto destroy; + + /* Case 1): Enable all possible CPUs */ + CPU_ZERO(&set); + for (i = 0; i < nr_cpus; i++) + CPU_SET(i, &set); + err = sched_setaffinity(skel->bss->pid, sizeof(set), &set); + if (!ASSERT_OK(err, "setaffinity_all_cpus")) + goto free_link; + err = read_percpu_data(link, nr_cpus, 1); + if (!ASSERT_OK(err, "read_percpu_data")) + goto free_link; + if (!ASSERT_OK(skel->bss->err, "null_rq")) + goto free_link; + + /* Case 2): CPU0 only */ + CPU_ZERO(&set); + CPU_SET(0, &set); + err = sched_setaffinity(skel->bss->pid, sizeof(set), &set); + if (!ASSERT_OK(err, "setaffinity_cpu0")) + goto free_link; + err = read_percpu_data(link, 1, 1); + if (!ASSERT_OK(err, "read_percpu_data")) + goto free_link; + if (!ASSERT_OK(skel->bss->err, "null_rq_psi")) + goto free_link; + + /* Case 3): Partial CPUs */ + CPU_ZERO(&set); + for (i = 0; i < nr_cpus; i++) { + if (i < 4 && i & 0x1) + continue; + if (i > 8 && i & 0x2) + continue; + CPU_SET(i, &set); + chosen++; + } + err = sched_setaffinity(skel->bss->pid, sizeof(set), &set); + if (!ASSERT_OK(err, "setaffinity_partial_cpus")) + goto free_link; + err = read_percpu_data(link, chosen, 1); + if (!ASSERT_OK(err, "read_percpu_data")) + goto free_link; + ASSERT_OK(skel->bss->err, "null_rq_psi"); + +free_link: + bpf_link__destroy(link); +destroy: + cpumask_iter_success__destroy(skel); +close_fd: + close(cgrp_fd); +cleanup: + cleanup_cgroup_environment(); +} + void test_cpumask(void) { int i; @@ -74,4 +216,14 @@ void test_cpumask(void) RUN_TESTS(cpumask_success); RUN_TESTS(cpumask_failure); + + for (i = 0; i < ARRAY_SIZE(cpumask_iter_success_testcases); i++) { + if (!test__start_subtest(cpumask_iter_success_testcases[i])) + continue; + + verify_iter_success(cpumask_iter_success_testcases[i]); + } + + RUN_TESTS(cpumask_iter_success); + RUN_TESTS(cpumask_iter_failure); } diff --git a/tools/testing/selftests/bpf/progs/cpumask_common.h b/tools/testing/selftests/bpf/progs/cpumask_common.h index 0cd4aebb97cf..cdb9dc95e9d9 100644 --- a/tools/testing/selftests/bpf/progs/cpumask_common.h +++ b/tools/testing/selftests/bpf/progs/cpumask_common.h @@ -55,6 +55,9 @@ void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym u32 bpf_cpumask_any_distribute(const struct cpumask *src) __ksym; u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1, const struct cpumask *src2) __ksym; u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym; +int bpf_iter_cpumask_new(struct bpf_iter_cpumask *it, const struct cpumask *mask) __ksym; +int *bpf_iter_cpumask_next(struct bpf_iter_cpumask *it) __ksym; +void bpf_iter_cpumask_destroy(struct bpf_iter_cpumask *it) __ksym; void bpf_rcu_read_lock(void) __ksym; void bpf_rcu_read_unlock(void) __ksym; diff --git a/tools/testing/selftests/bpf/progs/cpumask_iter_failure.c b/tools/testing/selftests/bpf/progs/cpumask_iter_failure.c new file mode 100644 index 000000000000..3d304cee0a72 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/cpumask_iter_failure.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2024 Yafang Shao */ + +#include "vmlinux.h" +#include +#include + +#include "bpf_misc.h" +#include "task_kfunc_common.h" +#include "cpumask_common.h" + +char _license[] SEC("license") = "GPL"; + +SEC("iter.s/cgroup") +__failure __msg("R2 must be a rcu pointer") +int BPF_PROG(test_cpumask_iter_no_rcu, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct task_struct *p; + int *cpu; + + p = bpf_task_from_pid(1); + if (!p) + return 1; + + bpf_for_each(cpumask, cpu, p->cpus_ptr) { + } + bpf_task_release(p); + return 0; +} + +SEC("iter/cgroup") +__failure __msg("Possibly NULL pointer passed to trusted arg1") +int BPF_PROG(test_cpumask_iter_null_pointer, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct cpumask *mask = NULL; + int *cpu; + + bpf_for_each(cpumask, cpu, mask) { + } + return 0; +} + +SEC("iter.s/cgroup") +__failure __msg("Unreleased reference id=3 alloc_insn=10") +int BPF_PROG(test_cpumask_iter_no_destroy, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct bpf_iter_cpumask it; + struct task_struct *p; + + p = bpf_task_from_pid(1); + if (!p) + return 1; + + bpf_rcu_read_lock(); + bpf_iter_cpumask_new(&it, p->cpus_ptr); + bpf_rcu_read_unlock(); + + bpf_iter_cpumask_next(&it); + bpf_task_release(p); + return 0; +} + +SEC("iter/cgroup") +__failure __msg("expected an initialized iter_cpumask as arg #1") +int BPF_PROG(test_cpumask_iter_next_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct bpf_iter_cpumask *it = NULL; + + bpf_iter_cpumask_next(it); + return 0; +} + +SEC("iter/cgroup") +__failure __msg("expected an initialized iter_cpumask as arg #1") +int BPF_PROG(test_cpumask_iter_next_uninit2, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct bpf_iter_cpumask it = {}; + + bpf_iter_cpumask_next(&it); + return 0; +} + +SEC("iter/cgroup") +__failure __msg("expected an initialized iter_cpumask as arg #1") +int BPF_PROG(test_cpumask_iter_destroy_uninit, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct bpf_iter_cpumask_kern it = {.cpu = -1}; + struct bpf_cpumask *mask; + + mask = bpf_cpumask_create(); + if (!mask) + return 1; + + bpf_cpumask_setall(mask); + it.mask = &mask->cpumask; + bpf_iter_cpumask_destroy((struct bpf_iter_cpumask *)&it); + bpf_cpumask_release(mask); + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/cpumask_iter_success.c b/tools/testing/selftests/bpf/progs/cpumask_iter_success.c new file mode 100644 index 000000000000..4ce14ef98451 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/cpumask_iter_success.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (c) 2024 Yafang Shao */ + +#include "vmlinux.h" +#include +#include + +#include "task_kfunc_common.h" +#include "cpumask_common.h" + +char _license[] SEC("license") = "GPL"; + +extern const struct psi_group_cpu system_group_pcpu __ksym __weak; +extern const struct rq runqueues __ksym __weak; + +int pid; + +#define READ_PERCPU_DATA(meta, cgrp, mask) \ +{ \ + u32 nr_running = 0, psi_nr_running = 0, nr_cpus = 0; \ + struct psi_group_cpu *groupc; \ + struct rq *rq; \ + int *cpu; \ + \ + bpf_for_each(cpumask, cpu, mask) { \ + rq = (struct rq *)bpf_per_cpu_ptr(&runqueues, *cpu); \ + if (!rq) { \ + err += 1; \ + continue; \ + } \ + nr_running += rq->nr_running; \ + nr_cpus += 1; \ + \ + groupc = (struct psi_group_cpu *)bpf_per_cpu_ptr(&system_group_pcpu, *cpu); \ + if (!groupc) { \ + err += 1; \ + continue; \ + } \ + psi_nr_running += groupc->tasks[NR_RUNNING]; \ + } \ + BPF_SEQ_PRINTF(meta->seq, "nr_running %u nr_cpus %u psi_running %u\n", \ + nr_running, nr_cpus, psi_nr_running); \ +} + +SEC("iter.s/cgroup") +int BPF_PROG(test_cpumask_iter_sleepable, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct task_struct *p; + + /* epilogue */ + if (!cgrp) + return 0; + + bpf_rcu_read_lock(); + p = bpf_task_from_pid(pid); + if (!p) { + bpf_rcu_read_unlock(); + return 1; + } + + READ_PERCPU_DATA(meta, cgrp, p->cpus_ptr); + bpf_task_release(p); + bpf_rcu_read_unlock(); + return 0; +} + +SEC("iter/cgroup") +int BPF_PROG(test_cpumask_iter, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct task_struct *p; + + /* epilogue */ + if (!cgrp) + return 0; + + p = bpf_task_from_pid(pid); + if (!p) + return 1; + + READ_PERCPU_DATA(meta, cgrp, p->cpus_ptr); + bpf_task_release(p); + return 0; +} + +SEC("iter.s/cgroup") +int BPF_PROG(test_cpumask_iter_next_no_rcu, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct bpf_iter_cpumask it; + struct task_struct *p; + + p = bpf_task_from_pid(1); + if (!p) + return 1; + + /* RCU is only required by bpf_iter_cpumask_new(). */ + bpf_rcu_read_lock(); + bpf_iter_cpumask_new(&it, p->cpus_ptr); + bpf_rcu_read_unlock(); + + bpf_iter_cpumask_next(&it); + bpf_iter_cpumask_destroy(&it); + + bpf_task_release(p); + return 0; +} + +SEC("iter.s/cgroup") +int BPF_PROG(test_cpumask_iter_no_next, struct bpf_iter_meta *meta, struct cgroup *cgrp) +{ + struct bpf_iter_cpumask it; + struct task_struct *p; + + p = bpf_task_from_pid(1); + if (!p) + return 1; + + bpf_rcu_read_lock(); + bpf_iter_cpumask_new(&it, p->cpus_ptr); + bpf_rcu_read_unlock(); + + /* It is fine without calling bpf_iter_cpumask_next(). */ + + bpf_iter_cpumask_destroy(&it); + bpf_task_release(p); + return 0; +}