From patchwork Wed Nov 1 20:45:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13443045 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (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 3D3218485 for ; Wed, 1 Nov 2023 20:45:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="F/L4TVPc" Received: from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com [IPv6:2607:f8b0:4864:20::b34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20FCD10C for ; Wed, 1 Nov 2023 13:45:25 -0700 (PDT) Received: by mail-yb1-xb34.google.com with SMTP id 3f1490d57ef6-d84c24a810dso197623276.2 for ; Wed, 01 Nov 2023 13:45:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1698871524; x=1699476324; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=owILXVem+6iaTL415I1LGD+NR0U7LX8g13zpZ68zgdQ=; b=F/L4TVPcVIzxkBiXc91LD7aVW+bKI8s38t4LtZEvhhG4qUSFLNz1uQc13qCsMIyoVN D1BEoazsoqmRqKk6ommjRXlymvgvBCM8qhECgOajiDf656VBtIScmtTwR9CWbKspeUY7 yndKINY9rLGt5i87J0g6ubD2sUzg5FJdsTfex7cjJYO/KuFVBUQLfJDjL+Ad8qH77dwy atB3flNRABa66SrfCma5mM8vFynkkuKUY3kye3HOO2JIpryPn7yGCauw0Dq9H8YxxzuZ kBsViQIa7l+51EbRTAgraLr4CblKnc6AhBY2KCDR+z/0C6MRj5AgvGRGuxrAdCcNNVVL gw7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698871524; x=1699476324; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=owILXVem+6iaTL415I1LGD+NR0U7LX8g13zpZ68zgdQ=; b=LX9uKz22yQ/QSeWLCv4VRHxgHU6vbM7BgruDlf7NHWtFztjLuS7vzGrv6erF4M8j2e QUzh1SJ85Uw79RyQ8Ix7LEjX9qhYEX4JU8jPJcr9QByjNYDJIc8kOqlp7OXqPiLH19C7 Yx1pABtXWvqOSn7mTwajlxH708lpg+KPcnNgvyqV0DimLWTKtCOA5GPg9F6bJK/E1fsq ylCDdaGzfTwfM4CxLrTwkNgRugo7WQC48O4GZB1mhy5z48Redd3k9KUyFJiL8gL2UTR4 ZudIVJGeLaH8ui9DsSi3Vte6wdB2fGmttsh9nj9I8ewtYOwn52QeOK1Mgup+gkpmWXZQ 3tPA== X-Gm-Message-State: AOJu0YzSNf7fzcwlm7KgxjlgmWy1tTX/fuwb7xUz6SMyKQwoFXGF6Nx0 eGlL3VxKxd6zT4g0opnfeKFveJdbmL0= X-Google-Smtp-Source: AGHT+IGRpRI02r1lWsRxjsBcZYfwqER2yZNYbQd5Qau3kVXX5OvblX+ThFJJOVegcwGcRZSE2R0FyA== X-Received: by 2002:a25:2f8e:0:b0:da0:47d8:4659 with SMTP id v136-20020a252f8e000000b00da047d84659mr13716185ybv.52.1698871523463; Wed, 01 Nov 2023 13:45:23 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:eea0:6f66:c57d:6b7c]) by smtp.gmail.com with ESMTPSA id o83-20020a25d756000000b00da086d6921fsm342386ybg.50.2023.11.01.13.45.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Nov 2023 13:45:22 -0700 (PDT) From: thinker.li@gmail.com To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org, drosen@google.com Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v9 00/12] Registrating struct_ops types from modules Date: Wed, 1 Nov 2023 13:45:07 -0700 Message-Id: <20231101204519.677870-1-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 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 From: Kui-Feng Lee Given the current constraints of the current implementation, struct_ops cannot be registered dynamically. This presents a significant limitation for modules like coming fuse-bpf, which seeks to implement a new struct_ops type. To address this issue, a new API is introduced that allows the registration of new struct_ops types from modules. Previously, struct_ops types were defined in bpf_struct_ops_types.h and collected as a static array. The new API lets callers add new struct_ops types dynamically. The static array has been removed and replaced by the per-btf struct_ops_tab. The struct_ops subsystem relies on BTF to determine the layout of values in a struct_ops map and identify the subsystem that the struct_ops map registers to. However, the kernel BTF does not include the type information of struct_ops types defined by a module. The struct_ops subsystem requires knowledge of the corresponding module for a given struct_ops map and the utilization of BTF information from that module. We empower libbpf to determine the correct module for accessing the BTF information and pass an identity (FD) of the module btf to the kernel. The kernel looks up type information and registered struct_ops types directly from the given btf. If a module exits while one or more struct_ops maps still refer to a struct_ops type defined by the module, it can lead to unforeseen complications. Therefore, it is crucial to ensure that a module remains intact as long as any struct_ops map is still linked to a struct_ops type defined by the module. To achieve this, every struct_ops map holds a reference to the module while being registered. Change from v8: - Rename bpf_struct_ops_init_one() to bpf_struct_ops_desc_init(). - Move code that using BTF_ID_LIST to the newly added patch 2. - Move code that lookup struct_ops types from a given module to the newly added patch 5. - Store the pointers of btf at st_maps. - Add test cases for the cases of modules being unload. - Call bpf_struct_ops_init() in btf_add_struct_ops() to fix an inconsistent issue. Changes from v7: - Fix check_struct_ops_btf_id() to use attach btf if there is instead of btf_vmlinux. Changes from v6: - Change returned error code to -EINVAL for the case of bpf_try_get_module(). - Return an error code from bpf_struct_ops_init(). - Fix the dependency issue of testing_helpers.c and rcu_tasks_trace_gp.skel.h. Changes from v5: - As the 2nd patch, we introduce "bpf_struct_ops_desc". This change involves moving certain members of "bpf_struct_ops" to "bpf_struct_ops_desc", which becomes a part of "btf_struct_ops_tab". This ensures that these members remain accessible even when the owner module of a "bpf_struct_ops" is unloaded. - Correct the order of arguments when calling in the 3rd patch. - Remove the owner argument from bpf_struct_ops_init_one(). Instead, callers should fill in st_ops->owner. - Make sure to hold the owner module when calling bpf_struct_ops_find() and bpf_struct_ops_find_value() in the 6th patch. - Merge the functions register_bpf_struct_ops_btf() and register_bpf_struct_ops() into a single function and relocate it to btf.c for better organization and clarity. - Undo the name modifications made to find_kernel_btf_id() and find_ksym_btf_id() in the 8th patch. Changes from v4: - Fix the dependency between testing_helpers.o and rcu_tasks_trace_gp.skel.h. Changes from v3: - Fix according to the feedback for v3. - Change of the order of arguments to make btf as the first argument. - Use btf_try_get_module() instead of try_get_module() since the module pointed by st_ops->owner can gone while some one is still holding its btf. - Move variables defined by BPF_STRUCT_OPS_COMMON_VALUE to struct bpf_struct_ops_common_value to validation easier. - Register the struct_ops type defined by bpf_testmod in its init function. - Rename field name to 'value_type_btf_obj_fd' to make it explicit. - Fix leaking of btf objects on error. - st_maps hold their modules to keep modules alive and prevent they from unloading. - bpf_map of libbpf keeps mod_btf_fd instead of a pointer to module_btf. - Do call_rcu_tasks_trace() in kern_sync_rcu() to ensure the bpf_testmod is unloaded properly. It uses rcu_tasks_trace_gp to trigger call_rcu_tasks_trace() in the kernel. - Merge and reorder patches in a reasonable order. Changes from v2: - Remove struct_ops array, and add a per-btf (module) struct_ops_tab to collect registered struct_ops types. - Validate value_type by checking member names and types. --- v7: https://lore.kernel.org/all/20231027211702.1374597-1-thinker.li@gmail.com/ v6: https://lore.kernel.org/all/20231022050335.2579051-11-thinker.li@gmail.com/ v5: https://lore.kernel.org/all/20231017162306.176586-1-thinker.li@gmail.com/ v4: https://lore.kernel.org/all/20231013224304.187218-1-thinker.li@gmail.com/ v3: https://lore.kernel.org/all/20230920155923.151136-1-thinker.li@gmail.com/ v2: https://lore.kernel.org/all/20230913061449.1918219-1-thinker.li@gmail.com/ Kui-Feng Lee (12): bpf: refactory struct_ops type initialization to a function. bpf: get type information with BPF_ID_LIST bpf, net: introduce bpf_struct_ops_desc. bpf: add struct_ops_tab to btf. bpf: lookup struct_ops types from a given module BTF. bpf: hold module for bpf_struct_ops_map. bpf: validate value_type bpf: pass attached BTF to the bpf_struct_ops subsystem bpf, net: switch to dynamic registration libbpf: Find correct module BTFs for struct_ops maps and progs. bpf: export btf_ctx_access to modules. selftests/bpf: test case for register_bpf_struct_ops(). include/linux/bpf.h | 50 +- include/linux/bpf_verifier.h | 1 + include/linux/btf.h | 7 + include/uapi/linux/bpf.h | 5 + kernel/bpf/bpf_struct_ops.c | 437 ++++++++++-------- kernel/bpf/bpf_struct_ops_types.h | 12 - kernel/bpf/btf.c | 109 ++++- kernel/bpf/syscall.c | 2 +- kernel/bpf/verifier.c | 25 +- net/bpf/bpf_dummy_struct_ops.c | 23 +- net/ipv4/bpf_tcp_ca.c | 24 +- tools/include/uapi/linux/bpf.h | 5 + tools/lib/bpf/bpf.c | 4 +- tools/lib/bpf/bpf.h | 5 +- tools/lib/bpf/libbpf.c | 38 +- tools/testing/selftests/bpf/Makefile | 4 +- .../selftests/bpf/bpf_testmod/bpf_testmod.c | 59 +++ .../selftests/bpf/bpf_testmod/bpf_testmod.h | 5 + .../bpf/prog_tests/test_struct_ops_module.c | 91 ++++ .../selftests/bpf/progs/struct_ops_module.c | 30 ++ tools/testing/selftests/bpf/testing_helpers.c | 35 ++ 21 files changed, 739 insertions(+), 232 deletions(-) delete mode 100644 kernel/bpf/bpf_struct_ops_types.h create mode 100644 tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c create mode 100644 tools/testing/selftests/bpf/progs/struct_ops_module.c