From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8BD944237B; Mon, 9 Jan 2023 08:37:29 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 76C1540687; Mon, 9 Jan 2023 08:37:29 +0100 (CET) Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2074.outbound.protection.outlook.com [40.107.7.74]) by mails.dpdk.org (Postfix) with ESMTP id 1248C4067C for ; Mon, 9 Jan 2023 08:37:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6wUr1RujRQvokitjeHACoyZthfvv2sIJqry22RKFrbg=; b=NkQXUzcsCFQkePMROpWGAuByGhNP8g6vsV0Q5PGLriALJOSr0byno3V7r6vXqfWru/83Ux2o7MLVMUiM5WSiqJn6NY++jls9sipLWOvbreKrhCoFxhla2XtZYUceF9HDGmDAbfmjHaz0B+c93ShFNOU5yDIPjWY430Lka2Q1zQ8= Received: from FR3P281CA0171.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a0::7) by AM8PR08MB6530.eurprd08.prod.outlook.com (2603:10a6:20b:315::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.18; Mon, 9 Jan 2023 07:37:23 +0000 Received: from VI1EUR03FT016.eop-EUR03.prod.protection.outlook.com (2603:10a6:d10:a0:cafe::f4) by FR3P281CA0171.outlook.office365.com (2603:10a6:d10:a0::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6002.11 via Frontend Transport; Mon, 9 Jan 2023 07:37:23 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VI1EUR03FT016.mail.protection.outlook.com (100.127.144.158) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.18 via Frontend Transport; Mon, 9 Jan 2023 07:37:22 +0000 Received: ("Tessian outbound 3ad958cd7492:v132"); Mon, 09 Jan 2023 07:37:22 +0000 X-CR-MTA-TID: 64aa7808 Received: from c4ff7724bd3d.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 79DC5294-4D27-42EA-A42A-834776BDE100.1; Mon, 09 Jan 2023 07:37:16 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id c4ff7724bd3d.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 09 Jan 2023 07:37:16 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CbcUlbDj/9v2Og+7SKfXPI55vPbIUfUVPrks/e1u9wsLW0vCi26tL9AHI6k7VckK/S9BODvY9xk3/ZPWbB/Z2s49gZkavGyaQiriYJZcdZpfYAeES/RnHw/p/hFbmMfNXUmKuVtyW31iY+pgaHwq6J2Pya0LHGyW392qA/LXwNFrq7CUM5w/07goHLMxROjJlCT3CEaV6iSaiB/v3bbCR3QsWoPlo9Jj6gqgXgml6TH5LeLwgL6oqmR0IOz8aJlVazG2yQn8BnfRAbL2xZLHQPxZ5IQs9BJarX0ICN1bdVn+nX4JemCJtQ+5Z84kTNIeOSozb6aHDgoMih3U6QRgNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6wUr1RujRQvokitjeHACoyZthfvv2sIJqry22RKFrbg=; b=eWrnOzYLwB+Xyhh6MmG7S3V/lBwzwvYnCIB0VPRdCISEV1Cw+D3l+Ao64ZxPY64CLOt680shXmRDefZDLb22i4wIYQYjqx0UCdVM1KBUK5595uzgBi6Y090n9tJobiiJI19gMJ/Gc6C9LvrRPhVYrWqkwk2OrmGaNzlXqxu6krtPhh355Pmm/9naEsZT5b+3u6OPfv/sLlIlqJVMel5qrUp7KmOCnF0wV88k5dkzila4YWANm3vpSymqH7dPukBkq0fgl57VNaC08k6CaivZxzJBY4DQ8Ng2iYhrurC20GsW4qsou1Lp6Dn9Qr1qS6lZQqMWmnVRaxvf9/s8eVw7dg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6wUr1RujRQvokitjeHACoyZthfvv2sIJqry22RKFrbg=; b=NkQXUzcsCFQkePMROpWGAuByGhNP8g6vsV0Q5PGLriALJOSr0byno3V7r6vXqfWru/83Ux2o7MLVMUiM5WSiqJn6NY++jls9sipLWOvbreKrhCoFxhla2XtZYUceF9HDGmDAbfmjHaz0B+c93ShFNOU5yDIPjWY430Lka2Q1zQ8= Received: from AS8PR08MB7080.eurprd08.prod.outlook.com (2603:10a6:20b:401::19) by AS2PR08MB9785.eurprd08.prod.outlook.com (2603:10a6:20b:606::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.18; Mon, 9 Jan 2023 07:37:11 +0000 Received: from AS8PR08MB7080.eurprd08.prod.outlook.com ([fe80::b7e3:d3a8:698e:cc0c]) by AS8PR08MB7080.eurprd08.prod.outlook.com ([fe80::b7e3:d3a8:698e:cc0c%6]) with mapi id 15.20.5986.018; Mon, 9 Jan 2023 07:37:11 +0000 From: Ruifeng Wang To: Tomasz Duszynski , "dev@dpdk.org" CC: "thomas@monjalon.net" , "jerinj@marvell.com" , "mb@smartsharesystems.com" , "zhoumin@loongson.cn" , nd Subject: RE: [PATCH v4 1/4] eal: add generic support for reading PMU events Thread-Topic: [PATCH v4 1/4] eal: add generic support for reading PMU events Thread-Index: AQHZDt/c/Hf2e/mpmkiDvA3Lnwj7Nq6V2aEA Date: Mon, 9 Jan 2023 07:37:11 +0000 Message-ID: References: <20221129092821.1304853-1-tduszynski@marvell.com> <20221213104350.3218167-1-tduszynski@marvell.com> <20221213104350.3218167-2-tduszynski@marvell.com> In-Reply-To: <20221213104350.3218167-2-tduszynski@marvell.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ts-tracking-id: 7E6EAA3C3E0F37428ED5D3AA3BE5E64B.0 x-checkrecipientchecked: true Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; x-ms-traffictypediagnostic: AS8PR08MB7080:EE_|AS2PR08MB9785:EE_|VI1EUR03FT016:EE_|AM8PR08MB6530:EE_ X-MS-Office365-Filtering-Correlation-Id: 6f6ca081-1ff4-4c42-1910-08daf21458bb x-ld-processed: f34e5979-57d9-4aaa-ad4d-b122a662184d,ExtAddr x-checkrecipientrouted: true nodisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: mZvgG3LpFmVOo1Dgx3PWsWdKrnP9Ae3e6xIzTL7y9sAKc+j8ssV+dmt5LVr0u4SkQ7mJwCB8cAGASc2TJrC0xqaPvS/l2uDWO7eUy/tOQHRFjfgpjXCng1Dy/MS0gAOjmFRW/982PsAn4b3nKyu5K4f0cUWy+ju/oxvvW5hb7Iuja8gAccvM3A/FEDx22Y1z15s6Kvi+1uXX+GQRNRC/SzJa/jygjbo+Ujezra/rpgFJSrNMjTusjbCJyerPhCmqgvgvOrmrpYWNy3haktctFgd70qnMgLEZasUpj06kBQAN6HYSzzRPZnQHI7xXxGxM+fRhieHifvQ/jBFsujRiWhnEjasSmY354ltPhM2gDZj3QeNLvpaO8Ey9MLP3kfHW6km+cSVwNZvJO4oA7E0dR3dZcbcI/kUk3+02A0VLaOdCLrYglfDKnEiIUJhDhe5SbpE42dsYSqcVRJXQT3ivWFcoGELA5msxw0j+hWVvbdQJ9X1o02xSd/e/thWYSU/cDXhNVvl+haURcUA4rVD8otSTJ4rPS/KAXGuwybe6UmUBAH273IxQmMJ2bAz/a6mCkrLI0POPtEL93sKEr3si3qT3vcC+80y+Kwhn1A3ihQJVyEfkSlzgqh/Onlrpzmo97xbIN31U5TnVPtfPcs0aB79KargI9nVUabeGn0EhRU+eBuaCHT8s51dovnTcIpZ725DncMXW+k2SKq6uzEhPQV7Cu4YUJZqNle+lcEjMO1o= X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AS8PR08MB7080.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(4636009)(346002)(376002)(136003)(396003)(39860400002)(366004)(451199015)(54906003)(76116006)(86362001)(110136005)(41300700001)(66556008)(66476007)(4326008)(66946007)(66446008)(64756008)(8676002)(38100700002)(33656002)(122000001)(38070700005)(26005)(6506007)(478600001)(186003)(7696005)(71200400001)(53546011)(2906002)(5660300002)(8936002)(52536014)(316002)(55016003)(83380400001)(30864003)(9686003)(41533002); DIR:OUT; SFP:1101; Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS2PR08MB9785 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: VI1EUR03FT016.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: c893a1c0-5655-4683-2a47-08daf21451d5 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 5uVx76WdPKsPma5mMMVU/ezyCJ2g1MOdo9xDEcd6xEjBIksTmpO73RJidRgthtcukyu/3KahNnf3fuEQ/T8plJJaP/ArGHrsAo9Jy4kYY7q+IQMRZjepZuVJjZxaEpBPcjk9CbrPoWlXjx8weMifg3RwbHSCECUhBB7nhQSa6//gfVSLqZybkHuCkD1x6vL4z4xkzZW31db7t+qdO1JcLSgZ/DdVHYdoY4WR+BkxC1sVbCwLcRzmDWQfR1OTB+g33CnSCZQVy+skE3yGBF6G+PbPIDHpeGpJROZSJAUpekPXjl/s3Ng0A9TjqKkbqEy+soHPCbjClhaYqIufHfOLP7Qg6tD8ZeJ4ngU5zJvM3pS1bW3hkDMZ9kVpf6TNgNJ5vzIO3vTOB4Rv1HVBX72wfUzlrYnHHk/ZVtTqjZ/y5YtTPMXLhrPO/GoS7PAZ/0sASs5oeb5a/l401sJZg9lHbs6BLq81COghJPEuOXIc3UYLwrvj1ttlAM4LGL+p8hMuMCnP2Tz11GnyII+BYamCYAYLeRnXzXbitfblLexYnKzQiKMlJU4x2u9pup9SXwAVcvdUANktQGDCLZ+tK2HbDUNzQETak0tbMyGyz2AMRWUWR82wzRpmfxVP3yvZ/AG9KVhmo6bGROfHb4ihJXnsRnfHZdR9400sFMqJw0iNwoCd2if4hdPDokKzrMzfJERvifqKVyTBxkoyhII1xqp1zj3R5bolbL0QwMoZ7ecYhjA= X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230022)(4636009)(396003)(39860400002)(376002)(136003)(346002)(451199015)(40470700004)(36840700001)(46966006)(33656002)(4326008)(8676002)(83380400001)(70586007)(70206006)(30864003)(52536014)(5660300002)(8936002)(41300700001)(7696005)(356005)(186003)(53546011)(478600001)(40480700001)(26005)(110136005)(9686003)(55016003)(81166007)(82740400003)(6506007)(54906003)(47076005)(316002)(86362001)(40460700003)(82310400005)(336012)(36860700001)(2906002)(41533002); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Jan 2023 07:37:22.6864 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6f6ca081-1ff4-4c42-1910-08daf21458bb X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: VI1EUR03FT016.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8PR08MB6530 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org > -----Original Message----- > From: Tomasz Duszynski > Sent: Tuesday, December 13, 2022 6:44 PM > To: dev@dpdk.org > Cc: thomas@monjalon.net; jerinj@marvell.com; mb@smartsharesystems.com; zh= oumin@loongson.cn; > Tomasz Duszynski > Subject: [PATCH v4 1/4] eal: add generic support for reading PMU events >=20 > Add support for programming PMU counters and reading their values in runt= ime bypassing > kernel completely. >=20 > This is especially useful in cases where CPU cores are isolated > (nohz_full) i.e run dedicated tasks. In such cases one cannot use standar= d perf utility > without sacrificing latency and performance. >=20 > Signed-off-by: Tomasz Duszynski > --- > app/test/meson.build | 1 + > app/test/test_pmu.c | 41 +++ > doc/guides/prog_guide/profile_app.rst | 8 + > lib/eal/common/meson.build | 3 + > lib/eal/common/pmu_private.h | 41 +++ > lib/eal/common/rte_pmu.c | 456 ++++++++++++++++++++++++++ > lib/eal/include/meson.build | 1 + > lib/eal/include/rte_pmu.h | 204 ++++++++++++ > lib/eal/linux/eal.c | 4 + > lib/eal/version.map | 6 + > 10 files changed, 765 insertions(+) > create mode 100644 app/test/test_pmu.c > create mode 100644 lib/eal/common/pmu_private.h create mode 100644 > lib/eal/common/rte_pmu.c create mode 100644 lib/eal/include/rte_pmu.h >=20 > diff --git a/lib/eal/common/rte_pmu.c b/lib/eal/common/rte_pmu.c new file= mode 100644 > index 0000000000..049fe19fe3 > --- /dev/null > +++ b/lib/eal/common/rte_pmu.c > @@ -0,0 +1,456 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(C) 2022 Marvell International Ltd. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include "pmu_private.h" > + > +#define EVENT_SOURCE_DEVICES_PATH "/sys/bus/event_source/devices" > + > +#ifndef GENMASK_ULL > +#define GENMASK_ULL(h, l) ((~0ULL - (1ULL << (l)) + 1) & (~0ULL >> ((64 > +- 1 - (h))))) #endif > + > +#ifndef FIELD_PREP > +#define FIELD_PREP(m, v) (((uint64_t)(v) << (__builtin_ffsll(m) - 1)) & > +(m)) #endif > + > +struct rte_pmu *rte_pmu; > + > +/* > + * Following __rte_weak functions provide default no-op. Architectures > +should override them if > + * necessary. > + */ > + > +int > +__rte_weak pmu_arch_init(void) > +{ > + return 0; > +} > + > +void > +__rte_weak pmu_arch_fini(void) > +{ > +} > + > +void > +__rte_weak pmu_arch_fixup_config(uint64_t config[3]) { > + RTE_SET_USED(config); > +} > + > +static int > +get_term_format(const char *name, int *num, uint64_t *mask) { > + char *config =3D NULL; > + char path[PATH_MAX]; > + int high, low, ret; > + FILE *fp; > + > + /* quiesce -Wmaybe-uninitialized warning */ > + *num =3D 0; > + *mask =3D 0; > + > + snprintf(path, sizeof(path), EVENT_SOURCE_DEVICES_PATH "/%s/format/%s",= rte_pmu->name, > name); > + fp =3D fopen(path, "r"); > + if (!fp) > + return -errno; > + > + errno =3D 0; > + ret =3D fscanf(fp, "%m[^:]:%d-%d", &config, &low, &high); > + if (ret < 2) { > + ret =3D -ENODATA; > + goto out; > + } > + if (errno) { > + ret =3D -errno; > + goto out; > + } > + > + if (ret =3D=3D 2) > + high =3D low; > + > + *mask =3D GENMASK_ULL(high, low); > + /* Last digit should be [012]. If last digit is missing 0 is implied. *= / > + *num =3D config[strlen(config) - 1]; > + *num =3D isdigit(*num) ? *num - '0' : 0; > + > + ret =3D 0; > +out: > + free(config); > + fclose(fp); > + > + return ret; > +} > + > +static int > +parse_event(char *buf, uint64_t config[3]) { > + char *token, *term; > + int num, ret, val; > + uint64_t mask; > + > + config[0] =3D config[1] =3D config[2] =3D 0; > + > + token =3D strtok(buf, ","); > + while (token) { > + errno =3D 0; > + /* =3D */ > + ret =3D sscanf(token, "%m[^=3D]=3D%i", &term, &val); > + if (ret < 1) > + return -ENODATA; > + if (errno) > + return -errno; > + if (ret =3D=3D 1) > + val =3D 1; > + > + ret =3D get_term_format(term, &num, &mask); > + free(term); > + if (ret) > + return ret; > + > + config[num] |=3D FIELD_PREP(mask, val); > + token =3D strtok(NULL, ","); > + } > + > + return 0; > +} > + > +static int > +get_event_config(const char *name, uint64_t config[3]) { > + char path[PATH_MAX], buf[BUFSIZ]; > + FILE *fp; > + int ret; > + > + snprintf(path, sizeof(path), EVENT_SOURCE_DEVICES_PATH "/%s/events/%s",= rte_pmu->name, > name); > + fp =3D fopen(path, "r"); > + if (!fp) > + return -errno; > + > + ret =3D fread(buf, 1, sizeof(buf), fp); > + if (ret =3D=3D 0) { > + fclose(fp); > + > + return -EINVAL; > + } > + fclose(fp); > + buf[ret] =3D '\0'; > + > + return parse_event(buf, config); > +} > + > +static int > +do_perf_event_open(uint64_t config[3], int lcore_id, int group_fd) { > + struct perf_event_attr attr =3D { > + .size =3D sizeof(struct perf_event_attr), > + .type =3D PERF_TYPE_RAW, > + .exclude_kernel =3D 1, > + .exclude_hv =3D 1, > + .disabled =3D 1, > + }; > + > + pmu_arch_fixup_config(config); > + > + attr.config =3D config[0]; > + attr.config1 =3D config[1]; > + attr.config2 =3D config[2]; > + > + return syscall(SYS_perf_event_open, &attr, rte_gettid(), Looks like using '0' instead of rte_gettid() takes the same effect. A small= optimization. > rte_lcore_to_cpu_id(lcore_id), > + group_fd, 0); > +} > + > +static int > +open_events(int lcore_id) > +{ > + struct rte_pmu_event_group *group =3D &rte_pmu->group[lcore_id]; > + struct rte_pmu_event *event; > + uint64_t config[3]; > + int num =3D 0, ret; > + > + /* group leader gets created first, with fd =3D -1 */ > + group->fds[0] =3D -1; > + > + TAILQ_FOREACH(event, &rte_pmu->event_list, next) { > + ret =3D get_event_config(event->name, config); > + if (ret) { > + RTE_LOG(ERR, EAL, "failed to get %s event config\n", event->name); > + continue; > + } > + > + ret =3D do_perf_event_open(config, lcore_id, group->fds[0]); > + if (ret =3D=3D -1) { > + if (errno =3D=3D EOPNOTSUPP) > + RTE_LOG(ERR, EAL, "64 bit counters not supported\n"); > + > + ret =3D -errno; > + goto out; > + } > + > + group->fds[event->index] =3D ret; > + num++; > + } > + > + return 0; > +out: > + for (--num; num >=3D 0; num--) { > + close(group->fds[num]); > + group->fds[num] =3D -1; > + } > + > + > + return ret; > +} > + > +static int > +mmap_events(int lcore_id) > +{ > + struct rte_pmu_event_group *group =3D &rte_pmu->group[lcore_id]; > + void *addr; > + int ret, i; > + > + for (i =3D 0; i < rte_pmu->num_group_events; i++) { > + addr =3D mmap(0, rte_mem_page_size(), PROT_READ, MAP_SHARED, group->fd= s[i], 0); > + if (addr =3D=3D MAP_FAILED) { > + ret =3D -errno; > + goto out; > + } > + > + group->mmap_pages[i] =3D addr; > + } > + > + return 0; > +out: > + for (; i; i--) { > + munmap(group->mmap_pages[i - 1], rte_mem_page_size()); > + group->mmap_pages[i - 1] =3D NULL; > + } > + > + return ret; > +} > + > +static void > +cleanup_events(int lcore_id) > +{ > + struct rte_pmu_event_group *group =3D &rte_pmu->group[lcore_id]; > + int i; > + > + if (!group->fds) > + return; > + > + if (group->fds[0] !=3D -1) > + ioctl(group->fds[0], PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP); > + > + for (i =3D 0; i < rte_pmu->num_group_events; i++) { > + if (group->mmap_pages[i]) { > + munmap(group->mmap_pages[i], rte_mem_page_size()); > + group->mmap_pages[i] =3D NULL; > + } > + > + if (group->fds[i] !=3D -1) { > + close(group->fds[i]); > + group->fds[i] =3D -1; > + } > + } > + > + free(group->mmap_pages); > + free(group->fds); > + > + group->mmap_pages =3D NULL; > + group->fds =3D NULL; > + group->enabled =3D false; > +} > + > +int __rte_noinline > +rte_pmu_enable_group(int lcore_id) > +{ > + struct rte_pmu_event_group *group =3D &rte_pmu->group[lcore_id]; > + int ret; > + > + if (rte_pmu->num_group_events =3D=3D 0) { > + RTE_LOG(DEBUG, EAL, "no matching PMU events\n"); > + > + return 0; > + } > + > + group->fds =3D calloc(rte_pmu->num_group_events, sizeof(*group->fds)); > + if (!group->fds) { > + RTE_LOG(ERR, EAL, "failed to alloc descriptor memory\n"); > + > + return -ENOMEM; > + } > + > + group->mmap_pages =3D calloc(rte_pmu->num_group_events, sizeof(*group->= mmap_pages)); > + if (!group->mmap_pages) { > + RTE_LOG(ERR, EAL, "failed to alloc userpage memory\n"); > + > + ret =3D -ENOMEM; > + goto out; > + } > + > + ret =3D open_events(lcore_id); > + if (ret) { > + RTE_LOG(ERR, EAL, "failed to open events on lcore-worker-%d\n", lcore_= id); > + goto out; > + } > + > + ret =3D mmap_events(lcore_id); > + if (ret) { > + RTE_LOG(ERR, EAL, "failed to map events on lcore-worker-%d\n", lcore_i= d); > + goto out; > + } > + > + if (ioctl(group->fds[0], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP) = =3D=3D -1) { > + RTE_LOG(ERR, EAL, "failed to enable events on lcore-worker-%d\n", > +lcore_id); > + > + ret =3D -errno; > + goto out; > + } > + > + return 0; > + > +out: > + cleanup_events(lcore_id); > + > + return ret; > +} > + > +static int > +scan_pmus(void) > +{ > + char path[PATH_MAX]; > + struct dirent *dent; > + const char *name; > + DIR *dirp; > + > + dirp =3D opendir(EVENT_SOURCE_DEVICES_PATH); > + if (!dirp) > + return -errno; > + > + while ((dent =3D readdir(dirp))) { > + name =3D dent->d_name; > + if (name[0] =3D=3D '.') > + continue; > + > + /* sysfs entry should either contain cpus or be a cpu */ > + if (!strcmp(name, "cpu")) > + break; > + > + snprintf(path, sizeof(path), EVENT_SOURCE_DEVICES_PATH "/%s/cpus", nam= e); > + if (access(path, F_OK) =3D=3D 0) > + break; > + } > + > + closedir(dirp); > + > + if (dent) { > + rte_pmu->name =3D strdup(name); > + if (!rte_pmu->name) > + return -ENOMEM; > + } > + > + return rte_pmu->name ? 0 : -ENODEV; > +} > + > +int > +rte_pmu_add_event(const char *name) > +{ > + struct rte_pmu_event *event; > + char path[PATH_MAX]; > + > + snprintf(path, sizeof(path), EVENT_SOURCE_DEVICES_PATH "/%s/events/%s",= rte_pmu->name, > name); Better to check if rte_pmu is available. See below. > + if (access(path, R_OK)) > + return -ENODEV; > + > + TAILQ_FOREACH(event, &rte_pmu->event_list, next) { > + if (!strcmp(event->name, name)) > + return event->index; > + continue; > + } > + > + event =3D calloc(1, sizeof(*event)); > + if (!event) > + return -ENOMEM; > + > + event->name =3D strdup(name); > + if (!event->name) { > + free(event); > + > + return -ENOMEM; > + } > + > + event->index =3D rte_pmu->num_group_events++; > + TAILQ_INSERT_TAIL(&rte_pmu->event_list, event, next); > + > + RTE_LOG(DEBUG, EAL, "%s even added at index %d\n", name, > +event->index); > + > + return event->index; > +} > + > +void > +eal_pmu_init(void) > +{ > + int ret; > + > + rte_pmu =3D calloc(1, sizeof(*rte_pmu)); > + if (!rte_pmu) { > + RTE_LOG(ERR, EAL, "failed to alloc PMU\n"); > + > + return; > + } > + > + TAILQ_INIT(&rte_pmu->event_list); > + > + ret =3D scan_pmus(); > + if (ret) { > + RTE_LOG(ERR, EAL, "failed to find core pmu\n"); > + goto out; > + } > + > + ret =3D pmu_arch_init(); > + if (ret) { > + RTE_LOG(ERR, EAL, "failed to setup arch for PMU\n"); > + goto out; > + } > + > + return; > +out: > + free(rte_pmu->name); > + free(rte_pmu); Set rte_pmu to NULL to prevent unintentional use? > +} > + > +void > +eal_pmu_fini(void) > +{ > + struct rte_pmu_event *event, *tmp; > + int lcore_id; > + > + RTE_TAILQ_FOREACH_SAFE(event, &rte_pmu->event_list, next, tmp) { rte_pmu can be unavailable if init fails. Better to check before accessing. > + TAILQ_REMOVE(&rte_pmu->event_list, event, next); > + free(event->name); > + free(event); > + } > + > + RTE_LCORE_FOREACH_WORKER(lcore_id) > + cleanup_events(lcore_id); > + > + pmu_arch_fini(); > + free(rte_pmu->name); > + free(rte_pmu); > +}