From patchwork Thu Feb 29 06:45:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13576602 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f178.google.com (mail-yw1-f178.google.com [209.85.128.178]) (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 A1E1D47F78 for ; Thu, 29 Feb 2024 06:45:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189131; cv=none; b=Wc3/3g4rzJwHLWvXQ0w7YAHdky86OR/XtpWyNvc2mbjPdtH2fp+/dVN/NGbVa48xhy0f9Awfc/S9i/A46Fpk6C7UwHdvni/5/lZ+TpzVOSM15SikfAqnEqCH1hNZQVYMw6nFun5qDYn4xJYMseMYJWBfQkZoyRGqzqBe0NQ0rCk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189131; c=relaxed/simple; bh=DFX+ihDo2Zn7mJTEEux7j4QOeT4Apcu3M8CrgxfyqvU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RqmVkfg5jGUBkdGqJR8llouLIIi+PNbg9Vzq5WP+j21sJohKMzXvKzWCyxYuO4GedRNR2armV9E6R9HNWBYyX4I4vLVKx4EsQHNj5XgSrdd/GTxk/WjgidqtSn8rmUkQSoDJWTD1fO5qyL97LPoGuz9blpH4+z6lLtPFaw0+ekU= 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=ALSIISQi; arc=none smtp.client-ip=209.85.128.178 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="ALSIISQi" Received: by mail-yw1-f178.google.com with SMTP id 00721157ae682-608c40666e0so5804227b3.2 for ; Wed, 28 Feb 2024 22:45:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709189128; x=1709793928; 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=8oo5m2I2ifSRO9gRtoJHToYuPS7HsymoHDVePc8UJK8=; b=ALSIISQihyHv8sAKkqzVj6WgHwqY7xL6pwtfzrAwr01torl+nv3u4FvHhrtSoFKTcA mcJmftA+23Qpfyp99cqkMgpoSnEWuzHJZPP6tthR79PnhDaV7HoClZwKGPXuWOr0aRbg ESDNoOOhnKXnSUPsDX198OfLVwpI/avn9O4v0/augMm3dm2lZhd1PCvEV5nqSYVU4s7w v/6XLKXuHSCsEy3MPrGH+jc1jjEwoZyAC0eo5jteUpQy59jKOxU5EVu5Fc1tDdo95kJi jWZFK9bb6ZdzowS4mubJXW0JlrhWQmN0e6JimD53+JBBniVprD8QBt5NAq0/TsaXccJd d96Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709189128; x=1709793928; 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=8oo5m2I2ifSRO9gRtoJHToYuPS7HsymoHDVePc8UJK8=; b=BiK3A+TpU/E0wDWl3Y2Qag1iPPWj6oT8UKR9ECo3PPmPeyT4sbqYEmZ39FH47JyFuc FJdK0EP4/z7TqrpECnl2eakliKB12aqS77mEuKQcKPz2sGO+z+ZZ42wh6BkF+G9f6ugp OG4mQiwV+QzRwWO4vGMFyI1odi57vxXn5dOh3wEjX/vU8bEpcmNG0L7Mgr8tXZWhdR+i LmHmcH1wKHbbCsjEvW4hfpDLXW42/3NQ3B4i/VM0l0IqPipQm22WhB+IvH1b2jKmahg3 YD89tLyMhYXKuV9t45HCc8Fs8fUQgGf5Gj4BsHqzuQPE/jrxE/tILbHOS+eOFpXCnGk5 setA== X-Gm-Message-State: AOJu0YzW1fo2zMaHV/9q6k/SyRa/TvuYTBExdzWsSkvqUlf+7TbZ9zBg ZSnG1l7rq5pn66HVHz93XpkJsHENWiA40u6bYzQzUYMUYWOfXnUE5hW6jPK9 X-Google-Smtp-Source: AGHT+IGThTmpWDRxbQ6edvGWfj9YVn5S0BvOiH/vAV6gQkQuMmxlXS+zVmzz8TjU0FLQnfkwj3H1xA== X-Received: by 2002:a0d:dd97:0:b0:608:b2b4:9b13 with SMTP id g145-20020a0ddd97000000b00608b2b49b13mr1391729ywe.27.1709189127954; Wed, 28 Feb 2024 22:45:27 -0800 (PST) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:bc86:35de:12f4:eec9]) by smtp.gmail.com with ESMTPSA id p14-20020a817e4e000000b006048e2331fcsm208581ywn.91.2024.02.28.22.45.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:45:27 -0800 (PST) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org, quentin@isovalent.com Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v6 1/5] libbpf: set btf_value_type_id of struct bpf_map for struct_ops. Date: Wed, 28 Feb 2024 22:45:19 -0800 Message-Id: <20240229064523.2091270-2-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240229064523.2091270-1-thinker.li@gmail.com> References: <20240229064523.2091270-1-thinker.li@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 For a struct_ops map, btf_value_type_id is the type ID of it's struct type. This value is required by bpftool to generate skeleton including pointers of shadow types. The code generator gets the type ID from bpf_map__btf_value_type_id() in order to get the type information of the struct type of a map. Signed-off-by: Kui-Feng Lee --- tools/lib/bpf/libbpf.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 01f407591a92..4c322dd65e10 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1229,6 +1229,7 @@ static int init_struct_ops_maps(struct bpf_object *obj, const char *sec_name, map->name = strdup(var_name); if (!map->name) return -ENOMEM; + map->btf_value_type_id = type_id; map->def.type = BPF_MAP_TYPE_STRUCT_OPS; map->def.key_size = sizeof(int); @@ -4857,6 +4858,12 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b create_attr.btf_value_type_id = 0; map->btf_key_type_id = 0; map->btf_value_type_id = 0; + break; + + case BPF_MAP_TYPE_STRUCT_OPS: + create_attr.btf_value_type_id = 0; + break; + default: break; } From patchwork Thu Feb 29 06:45:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13576603 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f172.google.com (mail-yw1-f172.google.com [209.85.128.172]) (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 684BA481A0 for ; Thu, 29 Feb 2024 06:45:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189132; cv=none; b=t5Wz7gSKHJgfZjbe2Eyf4XapZUPN3HyciGqFdBtvQcUR0PaLKow+1u5NXKEx578mrmvOonTp/omwsDMUaa+WeHxY4E22IdWMD7AIaNcSpBb8DyMlvoZj8sIyiPhSZpvKe7hnHhm3aQVW/vDnO2V6eMZeiLVQDkKL5YAkvsVdpUg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189132; c=relaxed/simple; bh=nPn55oAoL7+0rpULCknJS7AjUVTcbbK5Iv1HeQI6JBk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QyPn9E/Uu8akcJ8aNCr3SfPbUQzFKdw+F3DWGGzOAHUztvO/ns7yQKHVUkQVwLUzSFI6oNg+afaIm6lhSkvnxX3Z90r0sT5g7xrBGubbEjJJGj3XIy+YuohB3s1XhEe9HKOa88LaKO783NCvjNLqA8zsQ7drJuF5zBeaZKYjB5U= 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=WYTmztCZ; arc=none smtp.client-ip=209.85.128.172 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="WYTmztCZ" Received: by mail-yw1-f172.google.com with SMTP id 00721157ae682-608ed07bdc5so6050907b3.3 for ; Wed, 28 Feb 2024 22:45:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709189129; x=1709793929; 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=J9HLAxJ9U4qLmljhg3LCA6GZlLz21K/lGZs0G8MOVVs=; b=WYTmztCZlyL3W46gBJ3SLWRGlWPNVv+x6ZvNXTzvHXS0b+IC+G8zP3x5B/7CZrvQpw /BKgDCw39bQYFGZNADebETxsaoHnI2FtLMt8b/tl/vYY8cgsB3i3vnhNzOKcpkfXfazP KSHqYrv0RppiV8jKEaKfsSX+VSTLcb4tjZ4U8OQMDl8/Xuqo7fLxhUzPQw1LE/+zmyLz 7TDK74EwX8XplyGkmAhOrp75V5urcf1sGBU6rmKDfxJx0AU75vO5PC9iSoMgZUlKJDTA 7KGSiFyxjUulmlZ4xUbFiOlF2hwQBMDn4ejlkg7e0G1xmrDXBU9+xnRv+gLGMHjHNqwK 047Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709189129; x=1709793929; 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=J9HLAxJ9U4qLmljhg3LCA6GZlLz21K/lGZs0G8MOVVs=; b=t3pMIUJVJ4aynJc1h7R92+izgoLE/66T+EyIAIBaPndSq0w98wvRk2zmw1r6BQcET/ YnQPj8X5HSEL7jhgrF1G/YCmvspcqc+fXO0OZYhfEki0qGHjZJdGOW4+YBrk9GWIaSqG LjM4dEEa1Uz6iCJVXGUdEGjzSVJfzewSqqmNsR7WUstu5maeo9BCmx4ndY/lQqnSYCo1 M0WcqIfZ0xDcLNhIOXGfzbTgmAuGsRmAoU8eOe8LrRJiBv6FZDPFtuUHnOhe81noN0pL 6/7OoGoqdDwqnf27ijkj3cqfe9ClItHmDsnJ9emWS0Ef/HxOUoNGg/MVi69NAYnf2CQy 8iyA== X-Gm-Message-State: AOJu0YwuoNTC/uZUCQ5LYVE7nuS1tWm4d6epQRU4ThaXwSaDADLm/h08 hOyfhafg3RyBl+nGuh+37slXbaaN6cxxzvLDa3ljxopTBr22MJ/vv6f7ca8b X-Google-Smtp-Source: AGHT+IG0zJeP8Niex6DQ3bKzrxpoLYw2coepgw7oT8H8jLHzDY8NbWoRT+zC3Zra2rgZgm1dElXO0w== X-Received: by 2002:a81:7341:0:b0:608:d188:6fd9 with SMTP id o62-20020a817341000000b00608d1886fd9mr1258898ywc.33.1709189129179; Wed, 28 Feb 2024 22:45:29 -0800 (PST) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:bc86:35de:12f4:eec9]) by smtp.gmail.com with ESMTPSA id p14-20020a817e4e000000b006048e2331fcsm208581ywn.91.2024.02.28.22.45.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:45:28 -0800 (PST) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org, quentin@isovalent.com Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v6 2/5] libbpf: Convert st_ops->data to shadow type. Date: Wed, 28 Feb 2024 22:45:20 -0800 Message-Id: <20240229064523.2091270-3-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240229064523.2091270-1-thinker.li@gmail.com> References: <20240229064523.2091270-1-thinker.li@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 Convert st_ops->data to the shadow type of the struct_ops map. The shadow type of a struct_ops type is a variant of the original struct type providing a way to access/change the values in the maps of the struct_ops type. bpf_map__initial_value() will return st_ops->data for struct_ops types. The skeleton is going to use it as the pointer to the shadow type of the original struct type. One of the main differences between the original struct type and the shadow type is that all function pointers of the shadow type are converted to pointers of struct bpf_program. Users can replace these bpf_program pointers with other BPF programs. The st_ops->progs[] will be updated before updating the value of a map to reflect the changes made by users. Signed-off-by: Kui-Feng Lee --- tools/lib/bpf/libbpf.c | 43 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 4c322dd65e10..65d23a9d3e50 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1014,6 +1014,22 @@ static bool bpf_map__is_struct_ops(const struct bpf_map *map) return map->def.type == BPF_MAP_TYPE_STRUCT_OPS; } +static bool is_valid_st_ops_program(struct bpf_object *obj, + const struct bpf_program *prog) +{ + int i; + + if (!obj->nr_programs) + return false; + + for (i = 0; i < obj->nr_programs; i++) { + if (&obj->programs[i] == prog) + return prog->type == BPF_PROG_TYPE_STRUCT_OPS; + } + + return false; +} + /* Init the map's fields that depend on kern_btf */ static int bpf_map__init_kern_struct_ops(struct bpf_map *map) { @@ -1102,9 +1118,16 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map) if (btf_is_ptr(mtype)) { struct bpf_program *prog; - prog = st_ops->progs[i]; + /* Update the value from the shadow type */ + prog = *(void **)mdata; + st_ops->progs[i] = prog; if (!prog) continue; + if (!is_valid_st_ops_program(obj, prog)) { + pr_warn("struct_ops init_kern %s: member %s is not a struct_ops program\n", + map->name, mname); + return -ENOTSUP; + } kern_mtype = skip_mods_and_typedefs(kern_btf, kern_mtype->type, @@ -9312,7 +9335,9 @@ static struct bpf_map *find_struct_ops_map_by_offset(struct bpf_object *obj, return NULL; } -/* Collect the reloc from ELF and populate the st_ops->progs[] */ +/* Collect the reloc from ELF, populate the st_ops->progs[], and update + * st_ops->data for shadow type. + */ static int bpf_object__collect_st_ops_relos(struct bpf_object *obj, Elf64_Shdr *shdr, Elf_Data *data) { @@ -9426,6 +9451,14 @@ static int bpf_object__collect_st_ops_relos(struct bpf_object *obj, } st_ops->progs[member_idx] = prog; + + /* st_ops->data will be exposed to users, being returned by + * bpf_map__initial_value() as a pointer to the shadow + * type. All function pointers in the original struct type + * should be converted to a pointer to struct bpf_program + * in the shadow type. + */ + *((struct bpf_program **)(st_ops->data + moff)) = prog; } return 0; @@ -9884,6 +9917,12 @@ int bpf_map__set_initial_value(struct bpf_map *map, void *bpf_map__initial_value(struct bpf_map *map, size_t *psize) { + if (bpf_map__is_struct_ops(map)) { + if (psize) + *psize = map->def.value_size; + return map->st_ops->data; + } + if (!map->mmaped) return NULL; *psize = map->def.value_size; From patchwork Thu Feb 29 06:45:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13576604 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f179.google.com (mail-yw1-f179.google.com [209.85.128.179]) (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 C8847481BB for ; Thu, 29 Feb 2024 06:45:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189133; cv=none; b=drA1ngsNfv59os0fyzdJvC8KVqZLCH8gdwOjI/NwYWIavIlHBkAo+Co5pMzcJDk64/rT/yRmczroDBlqoPMwotqYeQLwXPSksfPa19R2LW+q+U7BTUKr/JWkqexGFC3TbW4AuPYqsNOrw7f5pbzI2Fb3C8EjcgOVz6i0ny6g3lQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189133; c=relaxed/simple; bh=FBubj1N8kexbqkDeiWnkIx30gLcAEf+zPc0vtxhR1Es=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=M0lNLiZRGOMja5AO20DlDX2N7JEW6ljIGczPbftLz7T/ZmXRZnVwDjG/LMQozXJ2fqABQ9AqZwAKcWQ+wj2G6KP02F1+UddjQ8EJI8W4MRMzZn95D9lZRaorxp8MuYT5tGsS2uSYYzl6XJC6+6f7IKqRD6y10pN3QYLprHfiKR0= 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=l4QJnVMa; arc=none smtp.client-ip=209.85.128.179 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="l4QJnVMa" Received: by mail-yw1-f179.google.com with SMTP id 00721157ae682-608841dfcafso6020077b3.2 for ; Wed, 28 Feb 2024 22:45:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709189130; x=1709793930; 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=v7NhmdOncoZuyPyxBwwRW1uQd/+CtHn8Eb6IapsaTlA=; b=l4QJnVMal2oJYXtC+x2zG1WJXaeUYHoE5zxFLTQM467ztYPwDEgYkPGvglZcG7k6bt uS4AiIHBR+vr9bTCc7Inikq2TEE7JdBb2kndQNY/MkwPYRe1PBwnSGUH0exDwN3u4NcE fw6ZSuyQCdzwBYyffRUVT6bLix/iVg9qNIvqIn1LxJq46nE+hNO4nlKDQMgAE9cJSKZS gGiqiN6r3WY4sEYYoOK916OVawNP8QGGl3HT5JSmbg62eKxHnya/ipjudTTNGe2sIZ2/ H3n8J+NGDhMa2ynd0M+s9HbdI6ehbUzeMpF63Youp8n4W8aUrx00QF6eyDoKNjFDNqZx T/IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709189130; x=1709793930; 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=v7NhmdOncoZuyPyxBwwRW1uQd/+CtHn8Eb6IapsaTlA=; b=sTQNocfNls7Y/RRm+ulexnNKQLj697T4jjleZ2zA4n2VRAlAocTlJ1ilEIYlyOcR1Q OpTWfSEQfYdIq/ydbcUgr+OabIZ07Do0xhKgB11M7dIgjn/JiyofgL9NmjeHXj65eJ37 hmenMhMidS+xCnfuudwnugo/9ihNZZdTMkZCHiY5clsCCAwMGxnlJisWy6Q/cwEtcb32 Ce98+8SZqNshaCJglnUczahEzfWvf6i0/lmXvgsXcKrxVMnAq07fMPfW0lIOtNamtP07 QYFCzVYvFSYhKLkzOWgRDjPDSbtPFGZoGv1FtN9/41pPXb9RF/Mtz/2LOWv5wkXgCu1s aRPA== X-Gm-Message-State: AOJu0YwxWk7B21mDiY4CZGwbM8NCTDkd4SDdGJ26OQy10NLV5I+TiAlN 5aoqx0lVQGziLGlTN1nzH6txNLtJLw2C9D84mOEj8xb5Zm3DLnLtScDQdztq X-Google-Smtp-Source: AGHT+IEGwBhm9Bv0m2RAXhbdCxgrQ72YD19KJ0u3RxBwvubRzXme8R4XokFmSS1nEvyS6+npf2QEFw== X-Received: by 2002:a81:a542:0:b0:609:4c74:5cc0 with SMTP id v2-20020a81a542000000b006094c745cc0mr1336194ywg.18.1709189130353; Wed, 28 Feb 2024 22:45:30 -0800 (PST) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:bc86:35de:12f4:eec9]) by smtp.gmail.com with ESMTPSA id p14-20020a817e4e000000b006048e2331fcsm208581ywn.91.2024.02.28.22.45.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:45:30 -0800 (PST) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org, quentin@isovalent.com Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v6 3/5] bpftool: generated shadow variables for struct_ops maps. Date: Wed, 28 Feb 2024 22:45:21 -0800 Message-Id: <20240229064523.2091270-4-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240229064523.2091270-1-thinker.li@gmail.com> References: <20240229064523.2091270-1-thinker.li@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 Declares and defines a pointer of the shadow type for each struct_ops map. The code generator will create an anonymous struct type as the shadow type for each struct_ops map. The shadow type is translated from the original struct type of the map. The user of the skeleton use pointers of them to access the values of struct_ops maps. However, shadow types only supports certain types of fields, including scalar types and function pointers. Any fields of unsupported types are translated into an array of characters to occupy the space of the original field. Function pointers are translated into pointers of the struct bpf_program. Additionally, padding fields are generated to occupy the space between two consecutive fields. The pointers of shadow types of struct_osp maps are initialized when *__open_opts() in skeletons are called. For a map called FOO, the user can access it through the pointer at skel->struct_ops.FOO. Reviewed-by: Quentin Monnet Signed-off-by: Kui-Feng Lee --- tools/bpf/bpftool/gen.c | 237 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 236 insertions(+), 1 deletion(-) diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index a9334c57e859..da8ae75eb6cb 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -55,6 +55,20 @@ static bool str_has_suffix(const char *str, const char *suffix) return true; } +static const struct btf_type * +resolve_func_ptr(const struct btf *btf, __u32 id, __u32 *res_id) +{ + const struct btf_type *t; + + t = skip_mods_and_typedefs(btf, id, NULL); + if (!btf_is_ptr(t)) + return NULL; + + t = skip_mods_and_typedefs(btf, t->type, res_id); + + return btf_is_func_proto(t) ? t : NULL; +} + static void get_obj_name(char *name, const char *file) { char file_copy[PATH_MAX]; @@ -909,6 +923,206 @@ codegen_progs_skeleton(struct bpf_object *obj, size_t prog_cnt, bool populate_li } } +static int walk_st_ops_shadow_vars(struct btf *btf, const char *ident, + const struct btf_type *map_type, __u32 map_type_id) +{ + LIBBPF_OPTS(btf_dump_emit_type_decl_opts, opts, .indent_level = 3); + const struct btf_type *member_type; + __u32 offset, next_offset = 0; + const struct btf_member *m; + struct btf_dump *d = NULL; + const char *member_name; + __u32 member_type_id; + int i, err = 0, n; + int size; + + d = btf_dump__new(btf, codegen_btf_dump_printf, NULL, NULL); + if (!d) + return -errno; + + n = btf_vlen(map_type); + for (i = 0, m = btf_members(map_type); i < n; i++, m++) { + member_type = skip_mods_and_typedefs(btf, m->type, &member_type_id); + member_name = btf__name_by_offset(btf, m->name_off); + + offset = m->offset / 8; + if (next_offset < offset) + printf("\t\t\tchar __padding_%d[%d];\n", i, offset - next_offset); + + switch (btf_kind(member_type)) { + case BTF_KIND_INT: + case BTF_KIND_FLOAT: + case BTF_KIND_ENUM: + case BTF_KIND_ENUM64: + /* scalar type */ + printf("\t\t\t"); + opts.field_name = member_name; + err = btf_dump__emit_type_decl(d, member_type_id, &opts); + if (err) { + p_err("Failed to emit type declaration for %s: %d", member_name, err); + goto out; + } + printf(";\n"); + + size = btf__resolve_size(btf, member_type_id); + if (size < 0) { + p_err("Failed to resolve size of %s: %d\n", member_name, size); + err = size; + goto out; + } + + next_offset = offset + size; + break; + + case BTF_KIND_PTR: + if (resolve_func_ptr(btf, m->type, NULL)) { + /* Function pointer */ + printf("\t\t\tstruct bpf_program *%s;\n", member_name); + + next_offset = offset + sizeof(void *); + break; + } + /* All pointer types are unsupported except for + * function pointers. + */ + fallthrough; + + default: + /* Unsupported types + * + * Types other than scalar types and function + * pointers are currently not supported in order to + * prevent conflicts in the generated code caused + * by multiple definitions. For instance, if the + * struct type FOO is used in a struct_ops map, + * bpftool has to generate definitions for FOO, + * which may result in conflicts if FOO is defined + * in different skeleton files. + */ + size = btf__resolve_size(btf, member_type_id); + if (size < 0) { + p_err("Failed to resolve size of %s: %d\n", member_name, size); + err = size; + goto out; + } + printf("\t\t\tchar __unsupported_%d[%d];\n", i, size); + + next_offset = offset + size; + break; + } + } + + /* Can not fail since it must be a struct type */ + size = btf__resolve_size(btf, map_type_id); + if (next_offset < (__u32)size) + printf("\t\t\tchar __padding_end[%d];\n", size - next_offset); + +out: + btf_dump__free(d); + + return err; +} + +/* Generate the pointer of the shadow type for a struct_ops map. + * + * This function adds a pointer of the shadow type for a struct_ops map. + * The members of a struct_ops map can be exported through a pointer to a + * shadow type. The user can access these members through the pointer. + * + * A shadow type includes not all members, only members of some types. + * They are scalar types and function pointers. The function pointers are + * translated to the pointer of the struct bpf_program. The scalar types + * are translated to the original type without any modifiers. + * + * Unsupported types will be translated to a char array to occupy the same + * space as the original field, being renamed as __unsupported_*. The user + * should treat these fields as opaque data. + */ +static int gen_st_ops_shadow_type(const char *obj_name, struct btf *btf, const char *ident, + const struct bpf_map *map) +{ + const struct btf_type *map_type; + const char *type_name; + __u32 map_type_id; + int err; + + map_type_id = bpf_map__btf_value_type_id(map); + if (map_type_id == 0) + return -EINVAL; + map_type = btf__type_by_id(btf, map_type_id); + if (!map_type) + return -EINVAL; + + type_name = btf__name_by_offset(btf, map_type->name_off); + + printf("\t\tstruct %s_%s_%s {\n", obj_name, ident, type_name); + + err = walk_st_ops_shadow_vars(btf, ident, map_type, map_type_id); + if (err) + return err; + + printf("\t\t} *%s;\n", ident); + + return 0; +} + +static int gen_st_ops_shadow(const char *obj_name, struct btf *btf, struct bpf_object *obj) +{ + int err, st_ops_cnt = 0; + struct bpf_map *map; + char ident[256]; + + if (!btf) + return 0; + + /* Generate the pointers to shadow types of + * struct_ops maps. + */ + bpf_object__for_each_map(map, obj) { + if (bpf_map__type(map) != BPF_MAP_TYPE_STRUCT_OPS) + continue; + if (!get_map_ident(map, ident, sizeof(ident))) + continue; + + if (!st_ops_cnt++) + printf("\tstruct {\n"); + + err = gen_st_ops_shadow_type(obj_name, btf, ident, map); + if (err) + return err; + } + + if (st_ops_cnt) + printf("\t} struct_ops;\n"); + + return 0; +} + +/* Generate the code to initialize the pointers of shadow types. */ +static void gen_st_ops_shadow_init(struct btf *btf, struct bpf_object *obj) +{ + struct bpf_map *map; + char ident[256]; + + if (!btf) + return; + + /* Initialize the pointers to_ops shadow types of + * struct_ops maps. + */ + bpf_object__for_each_map(map, obj) { + if (bpf_map__type(map) != BPF_MAP_TYPE_STRUCT_OPS) + continue; + if (!get_map_ident(map, ident, sizeof(ident))) + continue; + codegen("\ + \n\ + obj->struct_ops.%1$s = bpf_map__initial_value(obj->maps.%1$s, NULL);\n\ + \n\ + ", ident); + } +} + static int do_skeleton(int argc, char **argv) { char header_guard[MAX_OBJ_NAME_LEN + sizeof("__SKEL_H__")]; @@ -1039,6 +1253,8 @@ static int do_skeleton(int argc, char **argv) ); } + btf = bpf_object__btf(obj); + if (map_cnt) { printf("\tstruct {\n"); bpf_object__for_each_map(map, obj) { @@ -1052,6 +1268,10 @@ static int do_skeleton(int argc, char **argv) printf("\t} maps;\n"); } + err = gen_st_ops_shadow(obj_name, btf, obj); + if (err) + goto out; + if (prog_cnt) { printf("\tstruct {\n"); bpf_object__for_each_program(prog, obj) { @@ -1075,7 +1295,6 @@ static int do_skeleton(int argc, char **argv) printf("\t} links;\n"); } - btf = bpf_object__btf(obj); if (btf) { err = codegen_datasecs(obj, obj_name); if (err) @@ -1133,6 +1352,12 @@ static int do_skeleton(int argc, char **argv) if (err) \n\ goto err_out; \n\ \n\ + ", obj_name); + + gen_st_ops_shadow_init(btf, obj); + + codegen("\ + \n\ return obj; \n\ err_out: \n\ %1$s__destroy(obj); \n\ @@ -1442,6 +1667,10 @@ static int do_subskeleton(int argc, char **argv) printf("\t} maps;\n"); } + err = gen_st_ops_shadow(obj_name, btf, obj); + if (err) + goto out; + if (prog_cnt) { printf("\tstruct {\n"); bpf_object__for_each_program(prog, obj) { @@ -1553,6 +1782,12 @@ static int do_subskeleton(int argc, char **argv) if (err) \n\ goto err; \n\ \n\ + "); + + gen_st_ops_shadow_init(btf, obj); + + codegen("\ + \n\ return obj; \n\ err: \n\ %1$s__destroy(obj); \n\ From patchwork Thu Feb 29 06:45:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13576605 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f172.google.com (mail-yw1-f172.google.com [209.85.128.172]) (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 C0408481A0 for ; Thu, 29 Feb 2024 06:45:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189134; cv=none; b=K+anqtb3FVBE/Vrkw5cj6vY4CJ6l1zRPG890/NLrjxet1r8NmEoJ/zEkhuzS7CK3n8D6co0+b9rUkiMaT7jdSTOcV0z5MV0WDoCx0a/uXJSzrmF5trtKOcyEXKhs3KiGHj5WaaGBDWKMlrtDWkNgO8Yr1qFxS9KtMEnwvqjqYX4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189134; c=relaxed/simple; bh=cmRQcz/NrVVLiapjTGgEKF340eeUFufHN1Irw+TvAfA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WxRSN7pksuIEAzNZ38CW8wpOCjerkOQ+NTJrBpJXP6sfWn8iMB0XN5NcLSf3dmX9s9e3Wjf4jEzTZxIUVOlg4qKNdpyUqopSjm+E0L9+S8d8pg7LUAvSpfqNxEOzHxBkhAHK0SfE+aWNVtEUOU5LSxjSA9rWRgK56vWU2kAPcMo= 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=DIeZHYeE; arc=none smtp.client-ip=209.85.128.172 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="DIeZHYeE" Received: by mail-yw1-f172.google.com with SMTP id 00721157ae682-608ccac1899so5796797b3.1 for ; Wed, 28 Feb 2024 22:45:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709189131; x=1709793931; 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=53uBi+79WZX4490gC7mkCpwPxzEhwaxmyoZGGLwLwZg=; b=DIeZHYeEVHKWamXjGY8Pc9Pcalk35lH8PRm6rGlC2DR1f6fHEbML1apT7GrWQsnGik xpfLetmmfvxswE9YrkbzfYJtKxda4jpqYHkqkMy8tLgZkPptVnJMv+TuSbnjKMKHs6fZ iLUCZOHVbhc/1LSdCjiBU6Soq6pUh/A8z/y3GdYSmu1HMGoLJekQhL/94TD4V5sENBp5 Ky8EKgiU6TUEGUXV+N0Noh+vrREqwjpKtYWljpImPRB/slCFy8IenRrEQuTuyX5n2lN9 5G+RSp2pdx+p9gI7lTFQ5qmTnPG1rnqy77g/OMLLvWh3NwYvNfWcMGQptia7b+Hpggjm TI6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709189131; x=1709793931; 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=53uBi+79WZX4490gC7mkCpwPxzEhwaxmyoZGGLwLwZg=; b=PyVqfj8+lTM3yFnAq+57pSWFaA3mc/9q3DIk7H9MncfT02300EFjNPNM/3mI6NnBL8 z27NeBsgUnWEFJhG9sQFbIc667ZopMCfeXM9sGXGlIivRFssA36Ol8ZqxSGWA9X90aUD swhpV15zzSwkvhjP7kY9jSuSwxrFzmd35WwONAn+1+HdsdbS8tIPSARr8scIIXJtImC0 O4mvKEnRPq+2+e5kyyw7g3gm7QNbcNJSs0C5vvOfy5oHz9PO5jcMSt6U9pBLS6Swx6LL 3Tf0hcQ881gGxuuRoV5x8o0usMjlGSBEZVoBvp2lgMc8wXEQUcZ8/lSrRlEkAPycq6br XQ8w== X-Gm-Message-State: AOJu0YzJBS0jqJ+lkQjgzs4SDBI+V7UX80lNqdNySw/87VJoj7rFpO3w pKHo1fHNY38wsUV6Fo8ySLW7N+X5rHP+IsKhNlVNBcglOI54KekhmDhj+Cit X-Google-Smtp-Source: AGHT+IFK89hDyUBYwCOFTpupOlVFZ/X3MioVE7sSV86pLZBRP03AbuBnZEoeZ+0oF0WrG0Ik7VCNyQ== X-Received: by 2002:a0d:e9c1:0:b0:609:7576:586b with SMTP id s184-20020a0de9c1000000b006097576586bmr138988ywe.37.1709189131503; Wed, 28 Feb 2024 22:45:31 -0800 (PST) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:bc86:35de:12f4:eec9]) by smtp.gmail.com with ESMTPSA id p14-20020a817e4e000000b006048e2331fcsm208581ywn.91.2024.02.28.22.45.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:45:31 -0800 (PST) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org, quentin@isovalent.com Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v6 4/5] bpftool: Add an example for struct_ops map and shadow type. Date: Wed, 28 Feb 2024 22:45:22 -0800 Message-Id: <20240229064523.2091270-5-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240229064523.2091270-1-thinker.li@gmail.com> References: <20240229064523.2091270-1-thinker.li@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 The example in bpftool-gen.8 explains how to use the pointer of the shadow type to change the value of a field of a struct_ops map. Reviewed-by: Quentin Monnet Signed-off-by: Kui-Feng Lee --- .../bpf/bpftool/Documentation/bpftool-gen.rst | 58 +++++++++++++++++-- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst index 5006e724d1bc..62572f5beed9 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst @@ -257,18 +257,48 @@ EXAMPLES return 0; } -This is example BPF application with two BPF programs and a mix of BPF maps -and global variables. Source code is split across two source code files. +**$ cat example3.bpf.c** + +:: + + #include + #include + #include + /* This header file is provided by the bpf_testmod module. */ + #include "bpf_testmod.h" + + int test_2_result = 0; + + /* bpf_Testmod.ko calls this function, passing a "4" + * and testmod_map->data. + */ + SEC("struct_ops/test_2") + void BPF_PROG(test_2, int a, int b) + { + test_2_result = a + b; + } + + SEC(".struct_ops") + struct bpf_testmod_ops testmod_map = { + .test_2 = (void *)test_2, + .data = 0x1, + }; + +This is example BPF application with three BPF programs and a mix of BPF +maps and global variables. Source code is split across three source code +files. **$ clang --target=bpf -g example1.bpf.c -o example1.bpf.o** **$ clang --target=bpf -g example2.bpf.c -o example2.bpf.o** -**$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o** +**$ clang --target=bpf -g example3.bpf.c -o example3.bpf.o** + +**$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o example3.bpf.o** -This set of commands compiles *example1.bpf.c* and *example2.bpf.c* -individually and then statically links respective object files into the final -BPF ELF object file *example.bpf.o*. +This set of commands compiles *example1.bpf.c*, *example2.bpf.c* and +*example3.bpf.c* individually and then statically links respective object +files into the final BPF ELF object file *example.bpf.o*. **$ bpftool gen skeleton example.bpf.o name example | tee example.skel.h** @@ -291,7 +321,15 @@ BPF ELF object file *example.bpf.o*. struct bpf_map *data; struct bpf_map *bss; struct bpf_map *my_map; + struct bpf_map *testmod_map; } maps; + struct { + struct { + const struct bpf_program *test_1; + const struct bpf_program *test_2; + int data; + } *testmod_map; + } struct_ops; struct { struct bpf_program *handle_sys_enter; struct bpf_program *handle_sys_exit; @@ -304,6 +342,7 @@ BPF ELF object file *example.bpf.o*. struct { int x; } data; + int test_2_result; } *bss; struct example__data { _Bool global_flag; @@ -342,10 +381,16 @@ BPF ELF object file *example.bpf.o*. skel->rodata->param1 = 128; + /* Change the value through the pointer of shadow type */ + skel->struct_ops.testmod_map->data = 13; + err = example__load(skel); if (err) goto cleanup; + /* The result of the function test_2() */ + printf("test_2_result: %d\n", skel->bss->test_2_result); + err = example__attach(skel); if (err) goto cleanup; @@ -372,6 +417,7 @@ BPF ELF object file *example.bpf.o*. :: + test_2_result: 17 my_map name: my_map sys_enter prog FD: 8 my_static_var: 7 From patchwork Thu Feb 29 06:45:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13576606 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f181.google.com (mail-yw1-f181.google.com [209.85.128.181]) (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 E0871481D8 for ; Thu, 29 Feb 2024 06:45:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189135; cv=none; b=TBcHhsEI+hMcnTyehuKHBe2ZsdMTG3kBwgj7G33sedJQ/YtvZzgaxoS3GSJK0BihecpicAY1q8Am7jXBIxeRGBCmiwWdGjr23hzcBWMoou3ALlmK5N2llsE3vqGgQ1ilgijzDFSfy8QxjxUTZU9GzAFI5pfbVnTAnilnozTpkuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709189135; c=relaxed/simple; bh=kn6v7KWUs2y1IgJecF+yvFbM27olTQ2TFVTijy4UfYA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LpKf6suvnSZgKyZTdnI6VCjZ9DkSAijTsgWEhtwRO0hGCwiqAws2bOUvqHc22slgRPw/qh22zxsiEFzJULXLpiiEfAuxngEFURiAbJ0K1TpdF2vLcDt7M408jyAC0cPKNKEF9lm64MFL9Ng8YlTHDsljAzms8X/tcl6Y/8ae5tA= 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=g6V1lVw9; arc=none smtp.client-ip=209.85.128.181 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="g6V1lVw9" Received: by mail-yw1-f181.google.com with SMTP id 00721157ae682-60822b444c9so3781877b3.2 for ; Wed, 28 Feb 2024 22:45:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709189133; x=1709793933; 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=uD8m4gd8/Bnjn5MvoeiCe8GexY6YWfPcvCxDml5btb8=; b=g6V1lVw9qnkU7KuFdrrcvIRqAqP3V8rRdV4vHHy+a2RizYkf4tFlfNSEk9LlFXVP2Q 6fKR7PHj5sy1kssvvPjcp16oRoI6rIMBRa6lWy4yyhntLIEV+ceKIjN2aUapplwDn9hn Nz2o0bwKd19b/jjAXCVLBPzphxiAxUOi/sz7Vu2Ziwa+qIDaeum8f3n1CrsoaE1GQsl/ EZsCKVvXUi6yzhI5yszFp4crnUBVor3cjb0w8KiG1NWLcxJQbj7CU5NviCdnXKQDVVmC t8cf103QG87fpdmeMmJH/qcUX+88x27Guj9Wy5Irsd6vlotPx1Q94yBKdjAVelGxIe6p 6uoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709189133; x=1709793933; 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=uD8m4gd8/Bnjn5MvoeiCe8GexY6YWfPcvCxDml5btb8=; b=WodwWXeUwii9H8olp/FpcDdONd88CrQF0yuIUTXrLA3Tu93wOrpoB6ViRVwSCBirNT UvyAFvJBLEajyqfBG5+wFFMpXHjsnme2gj2JWClpLCC1deXgYQ+w+PDL2oR69z2TlxMI ySHW0FhYIlD0QrNfD+q5zWh55kpcwKcLrBAL9AKhOzpF/fTNwXKWGw31ONJSqUOIfZmI I9iRj8k/Q3jNEzpXzGfTKTknzBh4S7N3nGa6n/T3AWbGlhsNODpaFcK25KjpdQ1YxkA1 PgEJCxL6S0gJOxSox9JjJoUytc5QzPJotP8I/fYR/aK+rRXWrl/JNQ66xpMdBDla+CIm dBeQ== X-Gm-Message-State: AOJu0Yxyb86XLYYzWprQl/kaiZsKECO/xaQvsqEnCivKKhXz71u5YTtT rMtH0jguTn9gT6NMExgYgbnXUz/+ESM4fUyMmfsxSXDZ3TPJu86JwrtvtnVY X-Google-Smtp-Source: AGHT+IFwHwH7cc3U3e/5Xdh36rPMr3lzlbBY7mMFAjzJ9R2sUtR0/4DtHaCtf8GRjlaT0B7obSodjA== X-Received: by 2002:a0d:f5c1:0:b0:608:aee8:32a8 with SMTP id e184-20020a0df5c1000000b00608aee832a8mr1297511ywf.5.1709189132637; Wed, 28 Feb 2024 22:45:32 -0800 (PST) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:bc86:35de:12f4:eec9]) by smtp.gmail.com with ESMTPSA id p14-20020a817e4e000000b006048e2331fcsm208581ywn.91.2024.02.28.22.45.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:45:32 -0800 (PST) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org, quentin@isovalent.com Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v6 5/5] selftests/bpf: Test if shadow types work correctly. Date: Wed, 28 Feb 2024 22:45:23 -0800 Message-Id: <20240229064523.2091270-6-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240229064523.2091270-1-thinker.li@gmail.com> References: <20240229064523.2091270-1-thinker.li@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 Change the values of fields, including scalar types and function pointers, and check if the struct_ops map works as expected. The test changes the field "test_2" of "testmod_1" from the pointer to test_2() to pointer to test_3() and the field "data" to 13. The function test_2() and test_3() both compute a new value for "test_2_result", but in different way. By checking the value of "test_2_result", it ensures the struct_ops map works as expected with changes through shadow types. Signed-off-by: Kui-Feng Lee --- .../selftests/bpf/bpf_testmod/bpf_testmod.c | 11 ++++++++++- .../selftests/bpf/bpf_testmod/bpf_testmod.h | 8 ++++++++ .../bpf/prog_tests/test_struct_ops_module.c | 19 +++++++++++++++---- .../selftests/bpf/progs/struct_ops_module.c | 8 ++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c index 66787e99ba1b..098ddd067224 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c @@ -539,6 +539,15 @@ static int bpf_testmod_ops_init_member(const struct btf_type *t, const struct btf_member *member, void *kdata, const void *udata) { + if (member->offset == offsetof(struct bpf_testmod_ops, data) * 8) { + /* For data fields, this function has to copy it and return + * 1 to indicate that the data has been handled by the + * struct_ops type, or the verifier will reject the map if + * the value of the data field is not zero. + */ + ((struct bpf_testmod_ops *)kdata)->data = ((struct bpf_testmod_ops *)udata)->data; + return 1; + } return 0; } @@ -559,7 +568,7 @@ static int bpf_dummy_reg(void *kdata) * initialized, so we need to check for NULL. */ if (ops->test_2) - ops->test_2(4, 3); + ops->test_2(4, ops->data); return 0; } diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h index c3b0cf788f9f..971458acfac3 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h @@ -35,6 +35,14 @@ struct bpf_testmod_ops { void (*test_2)(int a, int b); /* Used to test nullable arguments. */ int (*test_maybe_null)(int dummy, struct task_struct *task); + + /* The following fields are used to test shadow copies. */ + char onebyte; + struct { + int a; + int b; + } unsupported; + int data; }; #endif /* _BPF_TESTMOD_H */ diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c index 8d833f0c7580..7d6facf46ebb 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c +++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c @@ -32,17 +32,23 @@ static void check_map_info(struct bpf_map_info *info) static void test_struct_ops_load(void) { - DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); struct struct_ops_module *skel; struct bpf_map_info info = {}; struct bpf_link *link; int err; u32 len; - skel = struct_ops_module__open_opts(&opts); + skel = struct_ops_module__open(); if (!ASSERT_OK_PTR(skel, "struct_ops_module_open")) return; + skel->struct_ops.testmod_1->data = 13; + skel->struct_ops.testmod_1->test_2 = skel->progs.test_3; + /* Since test_2() is not being used, it should be disabled from + * auto-loading, or it will fail to load. + */ + bpf_program__set_autoload(skel->progs.test_2, false); + err = struct_ops_module__load(skel); if (!ASSERT_OK(err, "struct_ops_module_load")) goto cleanup; @@ -56,8 +62,13 @@ static void test_struct_ops_load(void) link = bpf_map__attach_struct_ops(skel->maps.testmod_1); ASSERT_OK_PTR(link, "attach_test_mod_1"); - /* test_2() will be called from bpf_dummy_reg() in bpf_testmod.c */ - ASSERT_EQ(skel->bss->test_2_result, 7, "test_2_result"); + /* test_3() will be called from bpf_dummy_reg() in bpf_testmod.c + * + * In bpf_testmod.c it will pass 4 and 13 (the value of data) to + * .test_2. So, the value of test_2_result should be 20 (4 + 13 + + * 3). + */ + ASSERT_EQ(skel->bss->test_2_result, 20, "check_shadow_variables"); bpf_link__destroy(link); diff --git a/tools/testing/selftests/bpf/progs/struct_ops_module.c b/tools/testing/selftests/bpf/progs/struct_ops_module.c index b78746b3cef3..25952fa09348 100644 --- a/tools/testing/selftests/bpf/progs/struct_ops_module.c +++ b/tools/testing/selftests/bpf/progs/struct_ops_module.c @@ -21,9 +21,17 @@ void BPF_PROG(test_2, int a, int b) test_2_result = a + b; } +SEC("struct_ops/test_3") +int BPF_PROG(test_3, int a, int b) +{ + test_2_result = a + b + 3; + return a + b + 3; +} + SEC(".struct_ops.link") struct bpf_testmod_ops testmod_1 = { .test_1 = (void *)test_1, .test_2 = (void *)test_2, + .data = 0x1, };