From patchwork Mon Jul 17 12:00:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Changbin Du X-Patchwork-Id: 121266 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1078926vqt; Mon, 17 Jul 2023 05:30:24 -0700 (PDT) X-Google-Smtp-Source: APBJJlFRtk6WqMc8/Lmfu7ssNHNM1Gx6zxFBoXnAzRfflG3rNuT+skefyfdoVffVCkM7TTgOt1Mf X-Received: by 2002:a05:6a20:841a:b0:132:ff57:7fab with SMTP id c26-20020a056a20841a00b00132ff577fabmr15639939pzd.2.1689597024026; Mon, 17 Jul 2023 05:30:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689597024; cv=none; d=google.com; s=arc-20160816; b=qzLnoFTn+9EqDDUeWVpOTwkE/v/iL7htbkOsh551/eonfYh196NUfHzF798gaolXZc KFFbFDwnGO/FBLJv5sRioozwQrIIEFzjfzh1ALu12LOj1k+TSMvRrDhwsm376GNYVR3/ /QrNCwvvCW+Jn3g5s6GwcZGRTi2lPIV8WvadYTKI7/iUdhe42+EzDxFHSgjU0fueIZtR kSqAX8haFZnWT1ZO2sBvB7MwQvvbnmzj0mR0fYeFJmy6FsFIHhIeTwdMqmZ9N8n88+8B 9nv9DmYdANj0H5VAruEITCOTpkJIK4XudNw/crgar+QtXFKJ5erjTO2OhUsQrwT6qz81 SizQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=JtPKwbr8IZDRtg40KdII/9Dux1QeaDaYdfokqPxzVu4=; fh=ApeLdK2xurAeWAFDrmxfomKJVPpeLi5+JFM/i5kBxGg=; b=flx/zZWQIfc4q37qV7FS86Z6cuatgxDO9PDVWvxKepGQiJp+Y/H/AouCFvbgtYsI4V Kr6WKUmHmDTneQzPSKxzClQuTjgmvCJZI/2kMFOw10Clh45vXItlbQvgsZmYS7GPyEhx G6cPlTf2nNStCmW8kRWzK3PoIPI1O5LNKIeQXmfEBX3bbkhctkGrPpuK4qxBJc3XcNbM 089eEE6oynfpEgaqpETVyY7o0+/CwWMPlFEdAw2mubyrrkXJ+pnmYPmbueQWob6XmQ2y A4zLZkwet3QKuJDmL5MPtWv4X0bmb0jo3KvaFjfBjTs0xWYVg5j4FYPerU2M1Zx0PE9W A2LQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o30-20020a637e5e000000b00553ce421356si11587451pgn.56.2023.07.17.05.30.10; Mon, 17 Jul 2023 05:30:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230419AbjGQMBD (ORCPT + 99 others); Mon, 17 Jul 2023 08:01:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230269AbjGQMA5 (ORCPT ); Mon, 17 Jul 2023 08:00:57 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1EB310CF; Mon, 17 Jul 2023 05:00:44 -0700 (PDT) Received: from kwepemi500013.china.huawei.com (unknown [172.30.72.53]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4R4LDM4hR8zNmS5; Mon, 17 Jul 2023 19:57:23 +0800 (CST) Received: from M910t.huawei.com (10.110.54.157) by kwepemi500013.china.huawei.com (7.221.188.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 17 Jul 2023 20:00:41 +0800 From: Changbin Du To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo CC: Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , , , Hui Wang , Changbin Du Subject: [PATCH v2 1/2] perf cpumap: Add __perf_cpu_map__new and perf_cpu_map__2_cpuset Date: Mon, 17 Jul 2023 20:00:02 +0800 Message-ID: <20230717120003.2391329-2-changbin.du@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230717120003.2391329-1-changbin.du@huawei.com> References: <20230717120003.2391329-1-changbin.du@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.110.54.157] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemi500013.china.huawei.com (7.221.188.120) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771670889086076405 X-GMAIL-MSGID: 1771670889086076405 This adds two new api which will be used later. - __perf_cpu_map__new: accept a specified separator instead of ','. - perf_cpu_map__2_cpuset: convert perf_cpu_map to cpu_set_t. Signed-off-by: Changbin Du --- tools/lib/perf/cpumap.c | 45 ++++++++++++++++++++++++++-- tools/lib/perf/include/perf/cpumap.h | 4 +++ tools/lib/perf/libperf.map | 2 ++ tools/perf/tests/cpumap.c | 22 ++++++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index 2a5a29217374..23e907078b28 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only +#define _GNU_SOURCE #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include #include #include @@ -201,7 +203,7 @@ static struct perf_cpu_map *cpu_map__read_all_cpu_map(void) return cpus; } -struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) +struct perf_cpu_map *__perf_cpu_map__new(const char *cpu_list, char sep) { struct perf_cpu_map *cpus = NULL; unsigned long start_cpu, end_cpu = 0; @@ -225,7 +227,7 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) p = NULL; start_cpu = strtoul(cpu_list, &p, 0); if (start_cpu >= INT_MAX - || (*p != '\0' && *p != ',' && *p != '-')) + || (*p != '\0' && *p != sep && *p != '-')) goto invalid; if (*p == '-') { @@ -233,7 +235,7 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) p = NULL; end_cpu = strtoul(cpu_list, &p, 0); - if (end_cpu >= INT_MAX || (*p != '\0' && *p != ',')) + if (end_cpu >= INT_MAX || (*p != '\0' && *p != sep)) goto invalid; if (end_cpu < start_cpu) @@ -278,6 +280,11 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) return cpus; } +struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list) +{ + return __perf_cpu_map__new(cpu_list, ','); +} + static int __perf_cpu_map__nr(const struct perf_cpu_map *cpus) { return RC_CHK_ACCESS(cpus)->nr; @@ -479,3 +486,35 @@ struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig, free(tmp_cpus); return merged; } + +/* The caller is responsible for freeing returned cpu_set_t with CPU_FREE(). */ +cpu_set_t *perf_cpu_map__2_cpuset(struct perf_cpu_map *cpus, size_t *cpuset_size) +{ + cpu_set_t *cpusetp; + int max_cpu; + struct perf_cpu cpu; + int idx; + + if (perf_cpu_map__has_any_cpu(cpus)) + return NULL; + + max_cpu = perf_cpu_map__max(cpus).cpu; + if (max_cpu < 0) + return NULL; + + cpusetp = CPU_ALLOC(max_cpu + 1); + if (cpusetp == NULL) + return NULL; + + *cpuset_size = CPU_ALLOC_SIZE(max_cpu + 1); + CPU_ZERO_S(*cpuset_size, cpusetp); + + perf_cpu_map__for_each_cpu(cpu, idx, cpus) { + if (cpu.cpu == -1) + continue; + + CPU_SET_S(cpu.cpu, *cpuset_size, cpusetp); + } + + return cpusetp; +} diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h index e38d859a384d..1a0498f92dbe 100644 --- a/tools/lib/perf/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h @@ -3,6 +3,7 @@ #define __LIBPERF_CPUMAP_H #include +#include #include #include @@ -23,6 +24,7 @@ struct perf_cpu_map; */ LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); LIBPERF_API struct perf_cpu_map *perf_cpu_map__default_new(void); +LIBPERF_API struct perf_cpu_map *__perf_cpu_map__new(const char *cpu_list, char sep); LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file); LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); @@ -46,6 +48,8 @@ LIBPERF_API bool perf_cpu_map__equal(const struct perf_cpu_map *lhs, */ LIBPERF_API bool perf_cpu_map__has_any_cpu(const struct perf_cpu_map *map); +LIBPERF_API cpu_set_t *perf_cpu_map__2_cpuset(struct perf_cpu_map *cpus, size_t *cpuset_size); + #define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \ (idx) < perf_cpu_map__nr(cpus); \ diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map index 190b56ae923a..fe0946e34471 100644 --- a/tools/lib/perf/libperf.map +++ b/tools/lib/perf/libperf.map @@ -5,6 +5,7 @@ LIBPERF_0.0.1 { perf_cpu_map__default_new; perf_cpu_map__get; perf_cpu_map__put; + __perf_cpu_map__new; perf_cpu_map__new; perf_cpu_map__read; perf_cpu_map__nr; @@ -12,6 +13,7 @@ LIBPERF_0.0.1 { perf_cpu_map__empty; perf_cpu_map__max; perf_cpu_map__has; + perf_cpu_map__2_cpuset; perf_thread_map__new_array; perf_thread_map__new_dummy; perf_thread_map__set_pid; diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 7730fc2ab40b..0661bdfbb252 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "tests.h" +#include #include #include "cpumap.h" #include "event.h" @@ -247,12 +248,33 @@ static int test__cpu_map_equal(struct test_suite *test __maybe_unused, int subte return TEST_OK; } +static int test__cpu_map_convert(struct test_suite *test __maybe_unused, int subtest __maybe_unused) +{ + struct perf_cpu_map *any = perf_cpu_map__dummy_new(); + struct perf_cpu_map *cpus = perf_cpu_map__new("1-2"); + cpu_set_t *cpu_set; + size_t setsize; + + cpu_set = perf_cpu_map__2_cpuset(any, &setsize); + TEST_ASSERT_VAL("not equal", cpu_set == NULL); + CPU_FREE(cpu_set); + + cpu_set = perf_cpu_map__2_cpuset(cpus, &setsize); + TEST_ASSERT_VAL("cpus", cpu_set != NULL); + TEST_ASSERT_VAL("bad cpuset", !CPU_ISSET_S(0, setsize, cpu_set)); + TEST_ASSERT_VAL("bad cpuset", CPU_ISSET_S(1, setsize, cpu_set)); + TEST_ASSERT_VAL("bad cpuset", CPU_ISSET_S(2, setsize, cpu_set)); + + return TEST_OK; +} + static struct test_case tests__cpu_map[] = { TEST_CASE("Synthesize cpu map", cpu_map_synthesize), TEST_CASE("Print cpu map", cpu_map_print), TEST_CASE("Merge cpu map", cpu_map_merge), TEST_CASE("Intersect cpu map", cpu_map_intersect), TEST_CASE("Equal cpu map", cpu_map_equal), + TEST_CASE("Convert cpu map", cpu_map_convert), { .name = NULL, } };