Received: by 2002:ab2:6203:0:b0:1f5:f2ab:c469 with SMTP id o3csp1135591lqt; Sat, 20 Apr 2024 02:10:07 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUuOTgj0eELzyTFM18E70NIqOKZooLopOsvRSaYscVY36Bl80GpP/iND/+CAjgRJwC7z1ihdrJj/jxykSyEroEcx6U42m0TybnDMFqxlg== X-Google-Smtp-Source: AGHT+IHy2UvoiH7+0iesvz6h2G7IYxIkgKCg3pXHq1Qws0Dtiv7ldXOt0hv/lg2KfWEe/PBB3T5b X-Received: by 2002:a17:902:c945:b0:1e7:b6f4:2d77 with SMTP id i5-20020a170902c94500b001e7b6f42d77mr6619624pla.22.1713604207436; Sat, 20 Apr 2024 02:10:07 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713604207; cv=pass; d=google.com; s=arc-20160816; b=Pk6tAKROMDcaFbvKKpl05TynEk9GGh2a+3tiNK5HULPAEFTyf+ukHXxc3ebWZgRFyh PnOWDBfj5nsSMx+qvptTT1GrV/o4bVIoLTdUVm+Sfeq3WzWVLVWunjpWfdlol6iAHiG0 g0sbVAfYD2txZXn6YmMl+ipZXkj+d4v3mzeGG7tiEqGo8LzWsTCBGIg9NHOdNGvWu9bP w6cPYEunu0ppOPyTLyiKSjxbOQ/X/19ynxGuxe/PNEV/tiTBbtlkq2TKMj/dZLaCTM2W Nxqc0MlPH3HAgNPaj6U8tG/PUpZKxOqydUvjwNpcxcM2ZZ1gcNDCFmxIOegCmzbKgk1T 6pGQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=uc12ujou+4Kwg9OjYPYRmo+RcyudhYjndmZnhVk1F7A=; fh=Cxwo/A+C89tjOzVq8R/o/DH+l+P6Lpt8VwbqwppZI0Y=; b=zacmP9Q1iMxeP8DC69pHAE4kGKTEoo5H8UzMQbFDVIqwlosGfcOx1MatxeETSK4RAF S5sI5D64KYx3RhDVnhHA6wVSKAkOLdodzWksdOzS7ejVlrRxd+DA3UUVLcstVPfuC9Le eEdapFTZMkObbUEYkjth3PhodWTJ7n/qykOIRXdogDkJuGrZeWCLhPqya4SrtaI3/Gmj vlElvT9A+OSp9SY9XsmazK0cB6QIUK9MVS2LlfO7sEC4YgLm64HHzXmt0eGnfXtWl5o7 qibxuZASUkYWWLgyXu1zT9Wi7evtg3Vw3TC9EAI+T3uYq+asZKoXkgbdAQrjPysXSEki Esbg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=bNyEcNXe; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-152185-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-152185-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id n6-20020a170902f60600b001defa2d6abasi4787182plg.71.2024.04.20.02.10.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Apr 2024 02:10:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-152185-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=bNyEcNXe; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-152185-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-152185-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 52CB7B21981 for ; Sat, 20 Apr 2024 09:10:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B85CB18041; Sat, 20 Apr 2024 09:09:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bNyEcNXe" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD2C117C60; Sat, 20 Apr 2024 09:09:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713604171; cv=none; b=ciW9hghnJr+7C96d0/p5ipJKLDPYaeqtJH3rIFK+D04WS7s29CkmtimZtLZQIEQSE/nxM1K81yX3yqpnt6shmPAorEhTo70cgTcSa17dRbnv+H11AbQbQAv3MwV9yK7ywAgBlMEts/JeDQKd5tqNaNmVi15X5aTlw/lCoIY0Ftk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713604171; c=relaxed/simple; bh=59KtNj1Z9oWC6Bqy+6sHLI46UUOTL01CuulATd92Sss=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SQUJmiQZpnYuTuWtuOSpZ9n6R30O23wCrkjaG728HxA1bjQhP0+k3brHfGXzRNSBm5DPudvS8JRDUnZ0VpoOGTXqGr4fuLe47O+VxyXLBLVhRp9Qr/8bkZfMeLftv2oRNEhucONcHic2CIC2VAZcK1EaqBPXjnZCV1qKWjEpKIY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bNyEcNXe; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 923E6C072AA; Sat, 20 Apr 2024 09:09:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1713604170; bh=59KtNj1Z9oWC6Bqy+6sHLI46UUOTL01CuulATd92Sss=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bNyEcNXeFAN3E7hw9/ra2DbRD1JGO5/pydY+R5MaPL6wyfCVoMDOepRip6tVkwGFC MafMPNY+eGJfuMk50/bdL9HL4TKDfA3Ld3+8sHk8nyL8v7+PEuCoelaB5uEhZsqcS9 3nUCP7AvVriBcnAcgGFNCvmIedQQPMHI6E2ECLpT8EVO3/Hlis3NSZ2tgFGjOr99Zq w2A05dh+M51O0vLro76kmRq2gn2GeS8hiryt/5pYJHvlWsRTssxJswJE6BqV50Acw/ 1Tr0UNBXEfZssj0Lj1nrBQnXKTS8clVlwYDWiSTDKPuuh1wvbEIJbJjMB2lEFioJT1 YZquXeUy+Ausw== From: Benjamin Tissoires Date: Sat, 20 Apr 2024 11:09:02 +0200 Subject: [PATCH bpf-next v2 02/16] bpf: replace bpf_timer_init with a generic helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20240420-bpf_wq-v2-2-6c986a5a741f@kernel.org> References: <20240420-bpf_wq-v2-0-6c986a5a741f@kernel.org> In-Reply-To: <20240420-bpf_wq-v2-0-6c986a5a741f@kernel.org> To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Mykola Lysenko , Shuah Khan Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1713604159; l=5049; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=59KtNj1Z9oWC6Bqy+6sHLI46UUOTL01CuulATd92Sss=; b=+wj+6UmnjzexCHrhm+msHv1ZdcKWkFsbjvNItmDkpkrXfbW7Z1T3FxV76O8N5sPrubhzGMwxH 97TbWKi5BH3DwR6jP+L2Fh7y5uvaIT7nRV9OSEWeNzqnskvL+f0Z+2x X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= No code change except for the new flags argument being stored in the local data struct. Signed-off-by: Benjamin Tissoires --- no changes in v2 --- kernel/bpf/helpers.c | 91 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 5a069c70b5e6..1e6d1011303b 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1111,7 +1111,10 @@ struct bpf_hrtimer { /* the actual struct hidden inside uapi struct bpf_timer */ struct bpf_async_kern { - struct bpf_hrtimer *timer; + union { + struct bpf_async_cb *cb; + struct bpf_hrtimer *timer; + }; /* bpf_spin_lock is used here instead of spinlock_t to make * sure that it always fits into space reserved by struct bpf_timer * regardless of LOCKDEP and spinlock debug flags. @@ -1119,6 +1122,10 @@ struct bpf_async_kern { struct bpf_spin_lock lock; } __attribute__((aligned(8))); +enum bpf_async_type { + BPF_ASYNC_TYPE_TIMER = 0, +}; + static DEFINE_PER_CPU(struct bpf_hrtimer *, hrtimer_running); static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer) @@ -1160,46 +1167,55 @@ static enum hrtimer_restart bpf_timer_cb(struct hrtimer *hrtimer) return HRTIMER_NORESTART; } -BPF_CALL_3(bpf_timer_init, struct bpf_async_kern *, timer, struct bpf_map *, map, - u64, flags) +static int __bpf_async_init(struct bpf_async_kern *async, struct bpf_map *map, u64 flags, + enum bpf_async_type type) { - clockid_t clockid = flags & (MAX_CLOCKS - 1); + struct bpf_async_cb *cb; struct bpf_hrtimer *t; + clockid_t clockid; + size_t size; int ret = 0; - BUILD_BUG_ON(MAX_CLOCKS != 16); - BUILD_BUG_ON(sizeof(struct bpf_async_kern) > sizeof(struct bpf_timer)); - BUILD_BUG_ON(__alignof__(struct bpf_async_kern) != __alignof__(struct bpf_timer)); - if (in_nmi()) return -EOPNOTSUPP; - if (flags >= MAX_CLOCKS || - /* similar to timerfd except _ALARM variants are not supported */ - (clockid != CLOCK_MONOTONIC && - clockid != CLOCK_REALTIME && - clockid != CLOCK_BOOTTIME)) + switch (type) { + case BPF_ASYNC_TYPE_TIMER: + size = sizeof(struct bpf_hrtimer); + break; + default: return -EINVAL; - __bpf_spin_lock_irqsave(&timer->lock); - t = timer->timer; + } + + __bpf_spin_lock_irqsave(&async->lock); + t = async->timer; if (t) { ret = -EBUSY; goto out; } + /* allocate hrtimer via map_kmalloc to use memcg accounting */ - t = bpf_map_kmalloc_node(map, sizeof(*t), GFP_ATOMIC, map->numa_node); - if (!t) { + cb = bpf_map_kmalloc_node(map, size, GFP_ATOMIC, map->numa_node); + if (!cb) { ret = -ENOMEM; goto out; } - t->cb.value = (void *)timer - map->record->timer_off; - t->cb.map = map; - t->cb.prog = NULL; - rcu_assign_pointer(t->cb.callback_fn, NULL); - hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT); - t->timer.function = bpf_timer_cb; - WRITE_ONCE(timer->timer, t); - /* Guarantee the order between timer->timer and map->usercnt. So + + if (type == BPF_ASYNC_TYPE_TIMER) { + clockid = flags & (MAX_CLOCKS - 1); + t = (struct bpf_hrtimer *)cb; + + hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT); + t->timer.function = bpf_timer_cb; + cb->value = (void *)async - map->record->timer_off; + } + cb->map = map; + cb->prog = NULL; + cb->flags = flags; + rcu_assign_pointer(cb->callback_fn, NULL); + + WRITE_ONCE(async->cb, cb); + /* Guarantee the order between async->cb and map->usercnt. So * when there are concurrent uref release and bpf timer init, either * bpf_timer_cancel_and_free() called by uref release reads a no-NULL * timer or atomic64_read() below returns a zero usercnt. @@ -1209,15 +1225,34 @@ BPF_CALL_3(bpf_timer_init, struct bpf_async_kern *, timer, struct bpf_map *, map /* maps with timers must be either held by user space * or pinned in bpffs. */ - WRITE_ONCE(timer->timer, NULL); - kfree(t); + WRITE_ONCE(async->cb, NULL); + kfree(cb); ret = -EPERM; } out: - __bpf_spin_unlock_irqrestore(&timer->lock); + __bpf_spin_unlock_irqrestore(&async->lock); return ret; } +BPF_CALL_3(bpf_timer_init, struct bpf_async_kern *, timer, struct bpf_map *, map, + u64, flags) +{ + clock_t clockid = flags & (MAX_CLOCKS - 1); + + BUILD_BUG_ON(MAX_CLOCKS != 16); + BUILD_BUG_ON(sizeof(struct bpf_async_kern) > sizeof(struct bpf_timer)); + BUILD_BUG_ON(__alignof__(struct bpf_async_kern) != __alignof__(struct bpf_timer)); + + if (flags >= MAX_CLOCKS || + /* similar to timerfd except _ALARM variants are not supported */ + (clockid != CLOCK_MONOTONIC && + clockid != CLOCK_REALTIME && + clockid != CLOCK_BOOTTIME)) + return -EINVAL; + + return __bpf_async_init(timer, map, flags, BPF_ASYNC_TYPE_TIMER); +} + static const struct bpf_func_proto bpf_timer_init_proto = { .func = bpf_timer_init, .gpl_only = true, -- 2.44.0