Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp48655rdb; Mon, 4 Dec 2023 20:04:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IEkJIbXPTW6UvANw2tLS1KG9hKc94dbJywWLBDGRII71CUZOWMzETTktwapFmCEoxSVI/+M X-Received: by 2002:a05:6808:1820:b0:3b8:5c79:93d5 with SMTP id bh32-20020a056808182000b003b85c7993d5mr6085309oib.11.1701749066569; Mon, 04 Dec 2023 20:04:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701749066; cv=none; d=google.com; s=arc-20160816; b=M08VwVyiPX+JIANKsMBjBgR74D2F3+klhsFVjUiw70rM1GbI/U1XA1i125gIy4UV56 s1p8MxLbRILYK0018rk7UbQP967XkROweZLjpmqFyoUTNrBjK7NhE6gtgv+5bDmgjAWY IwK8FxzTvxvlI7ZjjKL3+kA58p58AZbY+g7VZXTmR0/Ga5AlikW1Ei4GQEnvI9TT5aVi iRu35jwAfERvNzTzNq6miGM6r/FnTa/4zuSDL++sD03vv4klK8BT+YfQKlvETeVLJzU9 CvgqRuMuR/vLHn6/rEPkLLXxxSHQMxep6nWNSbitUVIxgvGaBYvilFNosrhBhehxBJKR SXLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=uFi1KzwR2YOrUv7jhd8tU8M3SbznND0IRUD4tj9oA8M=; fh=SW19DI++J+PBkvNA/OISQswQDfDJ89uzLZGSYbHOVww=; b=wIRyxvlBRGr6te7x8UxqonBoDqLjs83Ngx0b9PnO4jdTxvwucwkh97wmLqfp/7vN+O 3/0qlfBj+V2lxhLjV1frOM5Q5j6TeW4K2YVDWoZTFK5KWbieazMOjfnLNuDD5aZhl5oL M7i0YBeU7RZXDK/2UMCPY8fcnTmuRzTD/py3VlugWN9Krf4ucofC+Wi5UE2A+0ars2A6 ANomib7gL+C0y4stf2Xx4msMwgpmqHqNw+UF2oKbs28KDxUSnVy7u3LFBkXKTHrJpO0a 5KY6OFAdH+JuLCpF0GmPn+e/DXDUC3lJyoCKmscsJmgtRWnhqgDKY3Tm1WruY4G/UJxi KvcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=P0+zuR9m; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from fry.vger.email (fry.vger.email. [23.128.96.38]) by mx.google.com with ESMTPS id r21-20020a62e415000000b006ce66363ce0si132934pfh.285.2023.12.04.20.04.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 20:04:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) client-ip=23.128.96.38; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=P0+zuR9m; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.38 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id 0665580785C9; Mon, 4 Dec 2023 20:04:23 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231639AbjLEEEF (ORCPT + 99 others); Mon, 4 Dec 2023 23:04:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229611AbjLEEED (ORCPT ); Mon, 4 Dec 2023 23:04:03 -0500 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1818EC6; Mon, 4 Dec 2023 20:04:09 -0800 (PST) Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-54bf9a54fe3so6598862a12.3; Mon, 04 Dec 2023 20:04:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701749047; x=1702353847; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=uFi1KzwR2YOrUv7jhd8tU8M3SbznND0IRUD4tj9oA8M=; b=P0+zuR9mhOIQhnB7yq+1BNIAdWArnUf7N2hGX6BAVSGHIAY0Znd+eNE/R0285ALnlm Du322hMnyD/Qqc8IjsLTGsEnwIXe+gR9aJGZ7cOrW3Rvr+bQEB6W2NNpMIp21VnhoS4K AsT3q7qLSjUlx46HAOZ7mY5iPuLewUoTKKW/iVNk7iSbzl2aEsPBhmM7y5tICx8gqVqN Hog4GKFunVNuExCqnOQpSmLUB5a7Flvrw+8WwQih2KLsJMxhV2gUTnsq8N1Bv0KZ04BM RmaTTKRbIt1xxm6J7IgYK/5ToKnILTxOsPHGw7ogxqz33svnQKTaaWYXMIhcG6yKssVO xRHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701749047; x=1702353847; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uFi1KzwR2YOrUv7jhd8tU8M3SbznND0IRUD4tj9oA8M=; b=RO9YJwTKT0X9LMgggRwddgUv2DgEZz232yW/T5jSUyL9ExfkPLffEkQ5R+AADRjgSL NXE4VKb1Vo81/Iiu6fZ9pADpYgmPqlgyYOMX487rJczLwqh4ThTdVQrngBgiG9p801Aa AiF2RQEVEOcLabrKJjMD+SeuM+K/PJAax1VeZXeXF3xb6aKa7wjhjEkR8kQTtzyMLVg1 iNkLLR5Ry/d9uocXa9HM/J1bgN/jNzZ9uBUDOre8M6jDgbnlhNlTNQ9hjH8ioVLs3hMM bmfehZUiSmO2TzFMo8udaiBgrGY9atmo33VLqlFC/ykmrL9/hL+cj1OvRCMVxsHLna6l HOPg== X-Gm-Message-State: AOJu0YwAaq+BruUtqAgR6WmenRkeccKcYfIcpe0B1yf3+NqLMGPU58rm wBLjFEFfPBiOUbC+0mxPwQDZ70XrGLNRiYlF5P0= X-Received: by 2002:a17:906:f196:b0:a19:a1ba:8cf1 with SMTP id gs22-20020a170906f19600b00a19a1ba8cf1mr3189378ejb.143.1701749047390; Mon, 04 Dec 2023 20:04:07 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Andrii Nakryiko Date: Mon, 4 Dec 2023 20:03:55 -0800 Message-ID: Subject: Re: [PATCH bpf-next v4 04/10] libbpf: Add BPF_CORE_WRITE_BITFIELD() macro To: Daniel Xu Cc: daniel@iogearbox.net, ast@kernel.org, nathan@kernel.org, andrii@kernel.org, ndesaulniers@google.com, steffen.klassert@secunet.com, antony.antony@secunet.com, alexei.starovoitov@gmail.com, yonghong.song@linux.dev, eddyz87@gmail.com, martin.lau@linux.dev, song@kernel.org, john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com, haoluo@google.com, jolsa@kernel.org, trix@redhat.com, bpf@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev, devel@linux-ipsec.org, netdev@vger.kernel.org, Jonathan Lemon Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Mon, 04 Dec 2023 20:04:23 -0800 (PST) On Mon, Dec 4, 2023 at 12:57=E2=80=AFPM Daniel Xu wrote: > > =3D=3D=3D Motivation =3D=3D=3D > > Similar to reading from CO-RE bitfields, we need a CO-RE aware bitfield > writing wrapper to make the verifier happy. > > Two alternatives to this approach are: > > 1. Use the upcoming `preserve_static_offset` [0] attribute to disable > CO-RE on specific structs. > 2. Use broader byte-sized writes to write to bitfields. > > (1) is a bit hard to use. It requires specific and not-very-obvious > annotations to bpftool generated vmlinux.h. It's also not generally > available in released LLVM versions yet. > > (2) makes the code quite hard to read and write. And especially if > BPF_CORE_READ_BITFIELD() is already being used, it makes more sense to > to have an inverse helper for writing. > > =3D=3D=3D Implementation details =3D=3D=3D > > Since the logic is a bit non-obvious, I thought it would be helpful > to explain exactly what's going on. > > To start, it helps by explaining what LSHIFT_U64 (lshift) and RSHIFT_U64 > (rshift) is designed to mean. Consider the core of the > BPF_CORE_READ_BITFIELD() algorithm: > > val <<=3D __CORE_RELO(s, field, LSHIFT_U64); > val =3D val >> __CORE_RELO(s, field, RSHIFT_U64); > > Basically what happens is we lshift to clear the non-relevant (blank) > higher order bits. Then we rshift to bring the relevant bits (bitfield) > down to LSB position (while also clearing blank lower order bits). To > illustrate: > > Start: ........XXX...... > Lshift: XXX......00000000 > Rshift: 00000000000000XXX > > where `.` means blank bit, `0` means 0 bit, and `X` means bitfield bit. > > After the two operations, the bitfield is ready to be interpreted as a > regular integer. > > Next, we want to build an alternative (but more helpful) mental model > on lshift and rshift. That is, to consider: > > * rshift as the total number of blank bits in the u64 > * lshift as number of blank bits left of the bitfield in the u64 > > Take a moment to consider why that is true by consulting the above > diagram. > > With this insight, we can now define the following relationship: > > bitfield > _ > | | > 0.....00XXX0...00 > | | | | > |______| | | > lshift | | > |____| > (rshift - lshift) > > That is, we know the number of higher order blank bits is just lshift. > And the number of lower order blank bits is (rshift - lshift). > > Finally, we can examine the core of the write side algorithm: > > mask =3D (~0ULL << rshift) >> lshift; // 1 > val =3D (val & ~mask) | ((nval << rpad) & mask); // 2 > > 1. Compute a mask where the set bits are the bitfield bits. The first > left shift zeros out exactly the number of blank bits, leaving a > bitfield sized set of 1s. The subsequent right shift inserts the > correct amount of higher order blank bits. > > 2. On the left of the `|`, mask out the bitfield bits. This creates > 0s where the new bitfield bits will go. On the right of the `|`, > bring nval into the correct bit position and mask out any bits > that fall outside of the bitfield. Finally, by bor'ing the two > halves, we get the final set of bits to write back. > > [0]: https://reviews.llvm.org/D133361 > Co-developed-by: Eduard Zingerman > Signed-off-by: Eduard Zingerman > Co-developed-by: Jonathan Lemon > Signed-off-by: Jonathan Lemon > Signed-off-by: Daniel Xu > --- > tools/lib/bpf/bpf_core_read.h | 32 ++++++++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) > LGTM Acked-by: Andrii Nakryiko > diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.= h > index 1ac57bb7ac55..7325a12692a3 100644 > --- a/tools/lib/bpf/bpf_core_read.h > +++ b/tools/lib/bpf/bpf_core_read.h > @@ -111,6 +111,38 @@ enum bpf_enum_value_kind { > val; = \ > }) > > +/* > + * Write to a bitfield, identified by s->field. > + * This is the inverse of BPF_CORE_WRITE_BITFIELD(). > + */ > +#define BPF_CORE_WRITE_BITFIELD(s, field, new_val) ({ \ > + void *p =3D (void *)s + __CORE_RELO(s, field, BYTE_OFFSET); = \ > + unsigned int byte_size =3D __CORE_RELO(s, field, BYTE_SIZE); = \ > + unsigned int lshift =3D __CORE_RELO(s, field, LSHIFT_U64); = \ > + unsigned int rshift =3D __CORE_RELO(s, field, RSHIFT_U64); = \ > + unsigned long long mask, val, nval =3D new_val; = \ > + unsigned int rpad =3D rshift - lshift; = \ > + \ > + asm volatile("" : "+r"(p)); \ > + \ > + switch (byte_size) { \ > + case 1: val =3D *(unsigned char *)p; break; = \ > + case 2: val =3D *(unsigned short *)p; break; = \ > + case 4: val =3D *(unsigned int *)p; break; = \ > + case 8: val =3D *(unsigned long long *)p; break; = \ > + } \ > + \ > + mask =3D (~0ULL << rshift) >> lshift; = \ > + val =3D (val & ~mask) | ((nval << rpad) & mask); = \ > + \ > + switch (byte_size) { \ > + case 1: *(unsigned char *)p =3D val; break; = \ > + case 2: *(unsigned short *)p =3D val; break; = \ > + case 4: *(unsigned int *)p =3D val; break; = \ > + case 8: *(unsigned long long *)p =3D val; break; = \ > + } \ > +}) > + > #define ___bpf_field_ref1(field) (field) > #define ___bpf_field_ref2(type, field) (((typeof(type) *)0)->field) > #define ___bpf_field_ref(args...) = \ > -- > 2.42.1 >