Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp798405pxp; Fri, 11 Mar 2022 15:26:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJwlMC6kxOrAQ9JcthcggT54GpB3CxkMxeE2QRRv0kAegIpoVH1+tRkG/UF7RZUEjkqRVnzK X-Received: by 2002:a17:902:a3cb:b0:151:e52e:fa0c with SMTP id q11-20020a170902a3cb00b00151e52efa0cmr12485825plb.70.1647041170308; Fri, 11 Mar 2022 15:26:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1647041170; cv=none; d=google.com; s=arc-20160816; b=dS7lqwVIQbxcd+ykg6NAfn9/95CUNfoXQOU0okxtRQwidsJEZBsbjcy3vOzYmdgxeo JOH2QOjGI5XtX7GmYeJC1cjRj+U75qYAadlEgywtj4U5GWjknqnEU105sqdBwl8RQa80 OyxjkDDIhATG4Xev/g1gtvsTqNidASinnolEzThaX7qoRIlIYreKXn4u6JA40Uxh2RP9 2rje5H9wQmLcAu8TLfv8yolaSY/MYKpY2YtVaxCcFzbe7RgIVTGIPN2IHcVWBsCtWRvt 8vZtqanA4ODFrpWCLI2q3f4N8AYqNRA2acrFI3aVPfTCfeSQvDbxuOMP0z4K/sFwGJg5 qGaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=frwFvW2tLrfwUW5MlUItxAYVS1OlBuCXSXlaKG/ZWrY=; b=EVe3bYKv2jsoHKlCzzbpz3tlmSHufywsvo7tnQndnXB1BuyMXsVxp7++1N6WixhK7S 8HtvPYKvjh0EC7q5UYZGsOhapUC2FrgUX+nZ67+TSV9SuyBkqhYZaM+X9JkV9L4ZeoUF E6xve+T4DKyeA4aoHchPviVus+gtDcrKfb+eWjJhIEyvfcp3RHPJNQTTF5Eiu+Igg+wK iMiBWIs79QOeVgLQ6mHKrkAnet6H1QHqfUbaGHqXxjfQ6ITy3PYpSHJK5fKzhvI8Cl3T bK2A0w44t8eecKFFCfyL6XPCaPQn4YGj2Tn5G+jeF33lCuFS2wtjOyL3PDOpUJP2XgJv GIqQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=D7t2NDgI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id q15-20020a056a00150f00b004f7948d14e2si2371889pfu.253.2022.03.11.15.26.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Mar 2022 15:26:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=D7t2NDgI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C93CC2C569D; Fri, 11 Mar 2022 14:12:49 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350617AbiCKRSH (ORCPT + 99 others); Fri, 11 Mar 2022 12:18:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43134 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350728AbiCKRSC (ORCPT ); Fri, 11 Mar 2022 12:18:02 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A0F0A1CC7F6 for ; Fri, 11 Mar 2022 09:16:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1647019016; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=frwFvW2tLrfwUW5MlUItxAYVS1OlBuCXSXlaKG/ZWrY=; b=D7t2NDgIwBAscg9E+P9qzcalwvUCekev5uGdlObxChDQ73PO67yZz8qJWomVE/CYFG0Jdq OEXxyMvlw7ZYadqwxXZ3I/87+gOIUTNXcQIu762KbH6H/H/0CRWEUH0/cBxPfPoNhoJmim DpQgBgLRfSUrkA7mt/UTEqSvsq0e3G0= Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-675-Vy3Ya4X5P2aEWojiBOv-Xg-1; Fri, 11 Mar 2022 12:16:55 -0500 X-MC-Unique: Vy3Ya4X5P2aEWojiBOv-Xg-1 Received: by mail-pf1-f199.google.com with SMTP id 16-20020a621910000000b004f783aad863so2523562pfz.15 for ; Fri, 11 Mar 2022 09:16:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=frwFvW2tLrfwUW5MlUItxAYVS1OlBuCXSXlaKG/ZWrY=; b=LTpzmx7Cb2CKu8fyrAZV4rqqxhparhaoalSrcKneUwEeUnY0xDQFMROSd0ns845lIX edy1ed1IIQfOJX4UN2NZDwrtfpbsjDMypw/EiVYzTzF6B3juoDtBvOTY5u1a1zYG9QNs vYwdLoyicePgjJQMZrMxARIxPX6ObtNrNe4OlIeXEF2iSI/OAyOrC8xlBukUIdjTrBAv l5/K+lGBTweNk2WRfPveI4tmzN9iYUZxGRfA7rD3IMB8DP6v77R+StXecgSuvlR+JEu7 gBQ8pTllNmujVIarQmnVM/0ARiMGMaFZtiiaQ5D0HQLpYZEypoxT2tjigv+PkY9LzGb3 TquQ== X-Gm-Message-State: AOAM532EDnYjZ745MqhtkWTzN/Ig0ioK7IrTHqERFZoEDvw7mC5GV3oK wbdrAzjD5K3WS2Kfq1o24cIEZp6VNwes4HIF6IhrI//LFCcajfYBhF4oCRMz+KZBY3Rg/MgORET HpYtvuyja2d/kA//szZevvMALHemiqFzx9E3KJ3Rq X-Received: by 2002:a05:6a00:781:b0:4f4:2a:2d89 with SMTP id g1-20020a056a00078100b004f4002a2d89mr11163652pfu.13.1647019014168; Fri, 11 Mar 2022 09:16:54 -0800 (PST) X-Received: by 2002:a05:6a00:781:b0:4f4:2a:2d89 with SMTP id g1-20020a056a00078100b004f4002a2d89mr11163607pfu.13.1647019013797; Fri, 11 Mar 2022 09:16:53 -0800 (PST) MIME-Version: 1.0 References: <20220304172852.274126-1-benjamin.tissoires@redhat.com> <20220304172852.274126-3-benjamin.tissoires@redhat.com> In-Reply-To: From: Benjamin Tissoires Date: Fri, 11 Mar 2022 18:16:42 +0100 Message-ID: Subject: Re: [PATCH bpf-next v2 02/28] bpf: introduce hid program type To: Song Liu Cc: Greg KH , Jiri Kosina , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Shuah Khan , Dave Marchevsky , Joe Stringer , Tero Kristo , open list , "open list:HID CORE LAYER" , Networking , bpf , linux-kselftest@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,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 lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Mar 8, 2022 at 10:20 AM Benjamin Tissoires wrote: > > On Tue, Mar 8, 2022 at 1:57 AM Song Liu wrote: > > > > On Mon, Mar 7, 2022 at 10:39 AM Benjamin Tissoires > > wrote: > > > > > > On Sat, Mar 5, 2022 at 1:03 AM Song Liu wrote: > > > > > > > > On Fri, Mar 4, 2022 at 9:31 AM Benjamin Tissoires > > > > wrote: > > > > > [...] > > > > > +struct hid_bpf_ctx { > > > > > + enum hid_bpf_event type; /* read-only */ > > > > > + __u16 allocated_size; /* the allocated size of data below (RO) */ > > > > > > > > There is a (6-byte?) hole here. > > > > > > > > > + struct hid_device *hdev; /* read-only */ > > > > > + > > > > > + __u16 size; /* used size in data (RW) */ > > > > > + __u8 data[]; /* data buffer (RW) */ > > > > > +}; > > > > > > > > Do we really need hit_bpf_ctx in uapi? Maybe we can just use it > > > > from vmlinuxh? > > > > > > I had a thought at this context today, and I think I am getting to the > > > limit of what I understand. > > > > > > My first worry is that the way I wrote it there, with a variable data > > > field length is that this is not forward compatible. Unless BTF and > > > CORE are making magic, this will bite me in the long run IMO. > > > > > > But then, you are talking about not using uapi, and I am starting to > > > wonder: am I doing the things correctly? > > > > > > To solve my first issue (and the weird API I had to introduce in the > > > bpf_hid_get/set_data), I came up to the following: > > > instead of exporting the data directly in the context, I could create > > > a helper bpf_hid_get_data_buf(ctx, const uint size) that returns a > > > RET_PTR_TO_ALLOC_MEM_OR_NULL in the same way bpf_ringbuf_reserve() > > > does. > > > > > > This way, I can directly access the fields within the bpf program > > > without having to worry about the size. > > > > > > But now, I am wondering whether the uapi I defined here is correct in > > > the way CORE works. > > > > > > My goal is to have HID-BPF programs to be CORE compatible, and not > > > have to recompile them depending on the underlying kernel. > > > > > > I can not understand right now if I need to add some other BTF helpers > > > in the same way the access to struct xdp_md and struct xdp_buff are > > > converted between one and other, or if defining a forward compatible > > > struct hid_bpf_ctx is enough. > > > As far as I understand, .convert_ctx_access allows to export a stable > > > uapi to the bpf prog users with the verifier doing the conversion > > > between the structs for me. But is this really required for all the > > > BPF programs if we want them to be CORE? > > > > > > Also, I am starting to wonder if I should not hide fields in the > > > context to the users. The .data field could be a pointer and only > > > accessed through the helper I mentioned above. This would be forward > > > compatible, and also allows to use whatever available memory in the > > > kernel to be forwarded to the BPF program. This way I can skip the > > > memcpy part and work directly with the incoming dma data buffer from > > > the IRQ. > > > > > > But is it best practice to do such a thing? > > > > I think .convert_ctx_access is the way to go if we want to access the data > > buffer without memcpy. I am not sure how much work is needed to make > > it compatible with CORE though. I spent the week working on that, and I am really amazed at how smart and simple the .convert_ctx_access is working. With that in place, I can hide the internal fields and export "virtual" public fields that are remapped on the fly by the kernel at load time :) > > > > To make sure I understand the case, do we want something like > > > > bpf_prog(struct hid_bpf_ctx *ctx) > > { > > /* makes sure n < ctx->size */ > > x = ctx->data[n]; /* read data */ > > ctx->data[n] = ; /* write data */ > > ctx->size = ; /* change data size */ > > } > > > > We also need it to be CORE, so that we may modify hid_bpf_ctx by > > inserting more members to it before data. > > > > Is this accurate? > > I have been trying to implement that, based on the PTR_TO_PACKET implementation. It works, but is kind of verbose while using it because we need to teach the verifier about the size of the arrays. For instance, I have the following: int bpf_prog(struct hid_bpf_ctx *ctx) { /* we need to store a pointer on the stack to store its accessible size */ __u8 *data = ctx->data; if (data + 3 > ctx->data_end) return 0; /* EPERM, bounds check */ data[1] = data[0] + 3; return 0; } This is OK, but it gets worse if I want to access a random offset: __s64 offset = 0; int bpf_prog(struct hid_bpf_ctx *ctx) { __u8 *data = ctx->data; __u16 *x; /* first assign the size of data */ if (data + 4 > ctx->data_end) return 0; /* EPERM, bounds check */ /* teach the verifier the range of offset (needs to be a s64) */ if (offset >= 0 && offset < 2) { x = (__u16 *)&data[offset]; /* now store the size of x in its register */ if (x + 2 > ctx->data_end) return 0; /* finally we can read/write the data */ *x += 1; } return 0; } OTOH, I managed to define a simpler helper that allows me to return a pointer to the internal data: BPF_CALL_3(bpf_hid_get_data, struct hid_bpf_ctx_kern*, ctx, u64, offset, u64, size) { if (!size) return (unsigned long)0; if (offset + size > ctx->data_end - ctx->data) return (unsigned long)0; return (unsigned long)(ctx->data + offset); } static const struct bpf_func_proto bpf_hid_get_data_proto = { .func = bpf_hid_get_data, .gpl_only = true, .ret_type = RET_PTR_TO_ALLOC_MEM_OR_NULL, .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_ANYTHING, .arg3_type = ARG_CONST_ALLOC_SIZE_OR_ZERO, }; Which makes the previous bpf code into: __u64 offset = 0; int bpf_prog(struct hid_bpf_ctx *ctx) { __u16 *x = bpf_hid_get_data(ctx, offset, 2); if (!x) return 0; /* EPERM, bounds check */ *x += 1; return 0; } The advantage of both of those solutions is that they are removing the need for bpf_hid_{get|set}_bytes(). The second solution is much simpler in terms of usage, but it doesn't feel "right" to have to reimplement the wheel when we should have direct array accesses. OTOH, the first solution with the packet implementation is bulky and requiring users to do that for every single access of the data is IMO way too much... Any thoughts? Cheers, Benjamin