From patchwork Fri Apr 28 22:27:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JP Kobryn X-Patchwork-Id: 13226858 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0838FC77B61 for ; Fri, 28 Apr 2023 22:28:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346495AbjD1W2N (ORCPT ); Fri, 28 Apr 2023 18:28:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230158AbjD1W2M (ORCPT ); Fri, 28 Apr 2023 18:28:12 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 221EA3584 for ; Fri, 28 Apr 2023 15:28:11 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1a5197f00e9so4032695ad.1 for ; Fri, 28 Apr 2023 15:28:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682720890; x=1685312890; 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=amKhIgBsjaTREOkegPKlL8n2EOYyZZTYliZAVqjO+DM=; b=aGAaUw8j/39O76gOXZSTIFzHH+6zvkbgrI4tFr5cYsHtEvf3GYSEMrtxm1GtS/dGL+ 0d7LHxDi25DHthv0wB6atXY22IpELvixW3PfZc+AhNpNh3422A8Zuym0VsxDYE1H/nDq dgacyWtzf+XOYrcmnKjYBtw3YXtYbrhBge/Y2rKa3qBWXD7Ei+fwNZzXigQ2aHS+H5Bb Wc8PYJQw5GUR6GNPVbF/W6O44mB1LQV6o4Wy+FTaa9DXE26qeR6Wthl9NJ3ggPCQxQXm AJ3TmrNDWkGBK4ORul6qsW1ijRtRA+WTnblv2lfS4ROpSTCJBsgdwbHQv/BjphGBwSal rxyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682720890; x=1685312890; 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=amKhIgBsjaTREOkegPKlL8n2EOYyZZTYliZAVqjO+DM=; b=fX8ZyJXABqTYTVQBdU6iW0az5yu4c2YBIkQxH5AB5V0PNw93aDjvVrC68+sHxXVk4G 79qGBHsmZxcQF3iB1N8iXz4X6X/WrsanZcrTde3q67vdgd3ZIxSvnY4VQLBSwok9lD6i WLLZh+2XMPYvjtXTfxhRdY8zJ+5caBs5TLfvgI14XALg5XgH0hlYYfvFcTs4XG4pe8jw kqVGgEEHwdrlxdcoyrPBVsx+tpzpi5uiwgWl5HGdsri37Q892t0mrbSq2O9WcsOaZHSv dwnnJgWW7f8fPCBLbMR6Jv4FfsKwPWSuHzv4vAs5Sn0DeOyAyeGR+tLdI9ChocTHSlt1 jOLQ== X-Gm-Message-State: AC+VfDz/0SmfmzaGyqQH7wTPqIM0+Hf3HkMBk/ymVqH7y847yocvg/VK JBss2iUIrv7vbylT9CSW9rg2AEuq3oE= X-Google-Smtp-Source: ACHHUZ745YFCDnWFK1WlDcVcUNftqxJjR0T/caAYdQubWXCv+Bl6ZAaaTYsx42XSPXGt/8COhWWYHQ== X-Received: by 2002:a17:902:db03:b0:1a6:e1ac:ecb8 with SMTP id m3-20020a170902db0300b001a6e1acecb8mr8684403plx.43.1682720890447; Fri, 28 Apr 2023 15:28:10 -0700 (PDT) Received: from toolbox.. ([98.42.16.172]) by smtp.gmail.com with ESMTPSA id ba11-20020a170902720b00b001a63ba28052sm10465738plb.69.2023.04.28.15.28.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Apr 2023 15:28:09 -0700 (PDT) From: JP Kobryn To: bpf@vger.kernel.org, andrii@kernel.org Cc: kernel-team@meta.com, inwardvessel@gmail.com Subject: [PATCH bpf-next 1/2] libbpf: add capability for resizing datasec maps Date: Fri, 28 Apr 2023 15:27:53 -0700 Message-Id: <20230428222754.183432-2-inwardvessel@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230428222754.183432-1-inwardvessel@gmail.com> References: <20230428222754.183432-1-inwardvessel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This patch updates bpf_map__set_value_size() so that if the given map is a datasec, it will attempt to resize it. If the following criteria is met, the resizing can be performed: - BTF info is present - the map is a datasec - the datasec contains a single variable - the single variable is an array The new map_datasec_resize() function is used to perform the resizing of the associated memory mapped region and adjust BTF so that the original array variable points to a new BTF array that is sized to cover the requested size. The new array size will be rounded up to a multiple of the element size. Signed-off-by: JP Kobryn Acked-by: Stanislav Fomichev --- tools/lib/bpf/libbpf.c | 138 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 1cbacf9e71f3..991649cacc10 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -9412,12 +9412,150 @@ __u32 bpf_map__value_size(const struct bpf_map *map) return map->def.value_size; } +static bool map_is_datasec(struct bpf_map *map) +{ + struct btf *btf; + struct btf_type *map_type; + + btf = bpf_object__btf(map->obj); + if (!btf) + return false; + + map_type = btf_type_by_id(btf, bpf_map__btf_value_type_id(map)); + + return btf_is_datasec(map_type); +} + +static int map_datasec_resize(struct bpf_map *map, __u32 size) +{ + int err; + struct btf *btf; + struct btf_type *datasec_type, *var_type, *resolved_type, *array_element_type; + struct btf_var_secinfo *var; + struct btf_array *array; + __u32 resolved_id, new_array_id; + __u32 rounded_sz; + __u32 nr_elements; + __u32 old_value_sz = map->def.value_size; + size_t old_mmap_sz, new_mmap_sz; + + /* btf is required and datasec map must be memory mapped */ + btf = bpf_object__btf(map->obj); + if (!btf) { + pr_warn("cannot resize datasec map '%s' while btf info is not present\n", + bpf_map__name(map)); + + return -EINVAL; + } + + datasec_type = btf_type_by_id(btf, bpf_map__btf_value_type_id(map)); + if (!btf_is_datasec(datasec_type)) { + pr_warn("attempted to resize datasec map '%s' but map is not a datasec\n", + bpf_map__name(map)); + + return -EINVAL; + } + + if (!map->mmaped) { + pr_warn("cannot resize datasec map '%s' while map is unexpectedly not memory mapped\n", + bpf_map__name(map)); + + return -EINVAL; + } + + /* datasec must only have a single variable */ + if (btf_vlen(datasec_type) != 1) { + pr_warn("cannot resize datasec map '%s' that does not consist of a single var\n", + bpf_map__name(map)); + + return -EINVAL; + } + + /* the single variable has to be an array */ + var = btf_var_secinfos(datasec_type); + resolved_id = btf__resolve_type(btf, var->type); + resolved_type = btf_type_by_id(btf, resolved_id); + if (!btf_is_array(resolved_type)) { + pr_warn("cannot resize datasec map '%s' whose single var is not an array\n", + bpf_map__name(map)); + + return -EINVAL; + } + + /* create a new array based on the existing array but with new length, + * rounding up the requested size for alignment + */ + array = btf_array(resolved_type); + array_element_type = btf_type_by_id(btf, array->type); + rounded_sz = roundup(size, array_element_type->size); + nr_elements = rounded_sz / array_element_type->size; + new_array_id = btf__add_array(btf, array->index_type, array->type, + nr_elements); + if (new_array_id < 0) { + pr_warn("failed to resize datasec map '%s' due to failure in creating new array\n", + bpf_map__name(map)); + err = new_array_id; + + goto fail_array; + } + + /* adding a new btf type invalidates existing pointers to btf objects. + * refresh pointers before proceeding + */ + datasec_type = btf_type_by_id(btf, map->btf_value_type_id); + var = btf_var_secinfos(datasec_type); + var_type = btf_type_by_id(btf, var->type); + + /* remap the associated memory */ + old_value_sz = map->def.value_size; + old_mmap_sz = bpf_map_mmap_sz(map); + map->def.value_size = rounded_sz; + new_mmap_sz = bpf_map_mmap_sz(map); + + if (munmap(map->mmaped, old_mmap_sz)) { + err = -errno; + pr_warn("failed to resize datasec map '%s' due to failure in munmap(), err:%d\n", + bpf_map__name(map), err); + + goto fail_mmap; + } + + map->mmaped = mmap(NULL, new_mmap_sz, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (map->mmaped == MAP_FAILED) { + err = -errno; + map->mmaped = NULL; + pr_warn("failed to resize datasec map '%s' due to failure in mmap(), err:%d\n", + bpf_map__name(map), err); + + goto fail_mmap; + } + + /* finally update btf info */ + datasec_type->size = var->size = rounded_sz; + var_type->type = new_array_id; + + return 0; + +fail_mmap: + map->def.value_size = old_value_sz; + +fail_array: + return err; +} + int bpf_map__set_value_size(struct bpf_map *map, __u32 size) { if (map->fd >= 0) return libbpf_err(-EBUSY); + + if (map_is_datasec(map)) + return map_datasec_resize(map, size); + map->def.value_size = size; + return 0; + } __u32 bpf_map__btf_key_type_id(const struct bpf_map *map) From patchwork Fri Apr 28 22:27:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: JP Kobryn X-Patchwork-Id: 13226859 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5151C77B7C for ; Fri, 28 Apr 2023 22:28:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230158AbjD1W2O (ORCPT ); Fri, 28 Apr 2023 18:28:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346479AbjD1W2N (ORCPT ); Fri, 28 Apr 2023 18:28:13 -0400 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 042462137 for ; Fri, 28 Apr 2023 15:28:12 -0700 (PDT) Received: by mail-pg1-x52a.google.com with SMTP id 41be03b00d2f7-52867360efcso229546a12.2 for ; Fri, 28 Apr 2023 15:28:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682720891; x=1685312891; 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=QhIr1P69QSyWe27YC0q38BmAGGLs2hivsqE/0X9WQSU=; b=ikhxAzd/oJU4L3CU9ynZFJsGjFsJLogXw3S1JLGpat/zYYSSNSMC+ZKdCkEGWXPaIY E5gUVSK8FxDPJ9fSYiUwIyDRomuWxt3N3JEe+9wRMUvRTYiz66uXoFckQdbsvsEpFMkf jEGKxjgSykLf+U28NvJO9wglOZSGvTfRQEVE4FZq1EKVtVZ4sALdXwu185rFa86dag7l 1qCGwsRhd6jTYjjCY3YRDdgesUTKOtXLwOph3IWcLpRR7AlixiUX3GeIWudDEREPrg2L TYTM/zCs6aTRDrUworwewSR5nuH2NnKARTkdo1Pezd6eDB9jVq9TJ3UkDf8ABvfuG0Un xWdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682720891; x=1685312891; 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=QhIr1P69QSyWe27YC0q38BmAGGLs2hivsqE/0X9WQSU=; b=jaLjHjbkkVMVIjVLGxikH/LFgRnvw5tB6MtA6dg2RWz1x8b1pGG0Lhe/18l8bwJeRn kodPdvTwyn/SV08r698j0/C3mSk5qCJL3zdthI8dTTc4np9nPCzeJ+3biDoQnlsqBGMS 4Ia4xnAPJ3caLifm71Y19Z8PJdoEjiOcrTAsnQJKfIG/hyk1uX8opnfxUitpUNM6QoiE ug6hwJeG+FApNZ55CMcgVZYzGAdyWn01m7G/xs8GUxwyv8AC4IOYHLao0O8y1Jo2+IJb 17nRVz90eZxaQJw5bacffdXphxltXHteQ+u510NNmCibr5XLxzU1DaRrnZAKD93gra2B INJw== X-Gm-Message-State: AC+VfDxoZBFfJIcY39bD902BY4jPhefykk64l2AB1LO5sFXD/JV+CNEK pPfj0WmkEl++UppsWw4yoEN/jgzpnhg= X-Google-Smtp-Source: ACHHUZ47AULuUh4auLUNcKA+VTmDj9kYEQ9noIEdLupc5Uu4boXBkks2A6Bba1LdRh2fXA1Md0aftQ== X-Received: by 2002:a17:902:f68b:b0:1aa:ce4d:c776 with SMTP id l11-20020a170902f68b00b001aace4dc776mr1406159plg.41.1682720891484; Fri, 28 Apr 2023 15:28:11 -0700 (PDT) Received: from toolbox.. ([98.42.16.172]) by smtp.gmail.com with ESMTPSA id ba11-20020a170902720b00b001a63ba28052sm10465738plb.69.2023.04.28.15.28.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Apr 2023 15:28:10 -0700 (PDT) From: JP Kobryn To: bpf@vger.kernel.org, andrii@kernel.org Cc: kernel-team@meta.com, inwardvessel@gmail.com Subject: [PATCH bpf-next 2/2] libbpf: selftests for resizing datasec maps Date: Fri, 28 Apr 2023 15:27:54 -0700 Message-Id: <20230428222754.183432-3-inwardvessel@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230428222754.183432-1-inwardvessel@gmail.com> References: <20230428222754.183432-1-inwardvessel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net This patch adds test coverage for resizing datasec maps. There are two tests which run a bpf program that sums the elements in the datasec array. After the datasec array is resized, each elements is assigned a value of 1 so that the sum will be equal to the length of the array. Assertions are done to verify this. The first test attempts to resize to an aligned length while the second attempts to resize to a mis-aligned length where rounding up is expected to occur. The third test attempts to resize maps that do not meet the necessary criteria and assertions are done to confirm error codes are returned. Signed-off-by: JP Kobryn Acked-by: Stanislav Fomichev --- .../bpf/prog_tests/global_map_resize.c | 187 ++++++++++++++++++ .../bpf/progs/test_global_map_resize.c | 33 ++++ 2 files changed, 220 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/global_map_resize.c create mode 100644 tools/testing/selftests/bpf/progs/test_global_map_resize.c diff --git a/tools/testing/selftests/bpf/prog_tests/global_map_resize.c b/tools/testing/selftests/bpf/prog_tests/global_map_resize.c new file mode 100644 index 000000000000..f38df37664a7 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/global_map_resize.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ + +#include +#include +#include + +#include "test_global_map_resize.skel.h" +#include "test_progs.h" + +static void run_program(void) +{ + (void)syscall(__NR_getpid); +} + +static int setup(struct test_global_map_resize **skel) +{ + if (!skel) + return -1; + + *skel = test_global_map_resize__open(); + if (!ASSERT_OK_PTR(skel, "test_global_map_resize__open")) + return -1; + + (*skel)->rodata->pid = getpid(); + + return 0; +} + +static void teardown(struct test_global_map_resize **skel) +{ + if (skel && *skel) + test_global_map_resize__destroy(*skel); +} + +static int resize_test(struct test_global_map_resize *skel, + __u32 element_sz, __u32 desired_sz) +{ + int ret = 0; + struct bpf_map *map; + __u32 initial_sz, actual_sz; + size_t nr_elements; + int *initial_val; + size_t initial_val_sz; + + map = skel->maps.data_my_array; + + initial_sz = bpf_map__value_size(map); + ASSERT_EQ(initial_sz, element_sz, "initial size"); + + /* round up desired size to align with element size */ + desired_sz = roundup(desired_sz, element_sz); + ret = bpf_map__set_value_size(map, desired_sz); + if (!ASSERT_OK(ret, "bpf_map__set_value_size")) + return ret; + + /* refresh map pointer to avoid invalidation issues */ + map = skel->maps.data_my_array; + + actual_sz = bpf_map__value_size(map); + ASSERT_EQ(actual_sz, desired_sz, "resize"); + + /* set the expected number of elements based on the resized array */ + nr_elements = roundup(actual_sz, element_sz) / element_sz; + skel->rodata->n = nr_elements; + + /* create array for initial map value */ + initial_val_sz = element_sz * nr_elements; + initial_val = malloc(initial_val_sz); + if (!ASSERT_OK_PTR(initial_val, "malloc initial_val")) { + ret = -ENOMEM; + + goto cleanup; + } + + /* fill array with ones */ + for (int i = 0; i < nr_elements; ++i) + initial_val[i] = 1; + + /* set initial value */ + ASSERT_EQ(initial_val_sz, actual_sz, "initial value size"); + + ret = bpf_map__set_initial_value(map, initial_val, initial_val_sz); + if (!ASSERT_OK(ret, "bpf_map__set_initial_val")) + goto cleanup; + + ret = test_global_map_resize__load(skel); + if (!ASSERT_OK(ret, "test_global_map_resize__load")) + goto cleanup; + + ret = test_global_map_resize__attach(skel); + if (!ASSERT_OK(ret, "test_global_map_resize__attach")) + goto cleanup; + + /* run the bpf program which will sum the contents of the array */ + run_program(); + + if (!ASSERT_EQ(skel->bss->sum, nr_elements, "sum")) + goto cleanup; + +cleanup: + if (initial_val) + free(initial_val); + + return ret; +} + +static void global_map_resize_aligned_subtest(void) +{ + struct test_global_map_resize *skel; + const __u32 element_sz = (__u32)sizeof(int); + const __u32 desired_sz = (__u32)sysconf(_SC_PAGE_SIZE) * 2; + + /* preliminary check that desired_sz aligns with element_sz */ + if (!ASSERT_EQ(desired_sz % element_sz, 0, "alignment")) + return; + + if (setup(&skel)) + goto teardown; + + if (resize_test(skel, element_sz, desired_sz)) + goto teardown; + +teardown: + teardown(&skel); +} + +static void global_map_resize_roundup_subtest(void) +{ + struct test_global_map_resize *skel; + const __u32 element_sz = (__u32)sizeof(int); + /* set desired size a fraction of element size beyond an aligned size */ + const __u32 desired_sz = (__u32)sysconf(_SC_PAGE_SIZE) * 2 + element_sz / 2; + + /* preliminary check that desired_sz does NOT align with element_sz */ + if (!ASSERT_NEQ(desired_sz % element_sz, 0, "alignment")) + return; + + if (setup(&skel)) + goto teardown; + + if (resize_test(skel, element_sz, desired_sz)) + goto teardown; + +teardown: + teardown(&skel); +} + +static void global_map_resize_invalid_subtest(void) +{ + int err; + struct test_global_map_resize *skel; + struct bpf_map *map; + const __u32 desired_sz = 8192; + + if (setup(&skel)) + goto teardown; + + /* attempt to resize a global datasec map which is an array + * BUT is with a var in same datasec + */ + map = skel->maps.data_my_array_and_var; + err = bpf_map__set_value_size(map, desired_sz); + if (!ASSERT_EQ(err, -EINVAL, "bpf_map__set_value_size")) + goto teardown; + + /* attempt to resize a global datasec map which is NOT an array */ + map = skel->maps.data_my_non_array; + err = bpf_map__set_value_size(map, desired_sz); + if (!ASSERT_EQ(err, -EINVAL, "bpf_map__set_value_size")) + goto teardown; + +teardown: + teardown(&skel); +} + +void test_global_map_resize(void) +{ + if (test__start_subtest("global_map_resize_aligned")) + global_map_resize_aligned_subtest(); + + if (test__start_subtest("global_map_resize_roundup")) + global_map_resize_roundup_subtest(); + + if (test__start_subtest("global_map_resize_invalid")) + global_map_resize_invalid_subtest(); +} diff --git a/tools/testing/selftests/bpf/progs/test_global_map_resize.c b/tools/testing/selftests/bpf/progs/test_global_map_resize.c new file mode 100644 index 000000000000..cffbba1b6020 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_global_map_resize.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ + +#include "vmlinux.h" +#include + +char _license[] SEC("license") = "GPL"; + +const volatile pid_t pid; +const volatile size_t n; + +int my_array[1] SEC(".data.my_array"); + +int my_array_with_neighbor[1] SEC(".data.my_array_and_var"); +int my_var_with_neighbor SEC(".data.my_array_and_var"); + +int my_non_array SEC(".data.my_non_array"); + +int sum = 0; + +SEC("tp/syscalls/sys_enter_getpid") +int array_sum(void *ctx) +{ + if (pid != (bpf_get_current_pid_tgid() >> 32)) + return 0; + + sum = 0; + + for (size_t i = 0; i < n; ++i) + sum += my_array[i]; + + return 0; +}