From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
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 <dev@dpdk.org>; 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 <Ruifeng.Wang@arm.com>
To: Tomasz Duszynski <tduszynski@marvell.com>, "dev@dpdk.org" <dev@dpdk.org>
CC: "thomas@monjalon.net" <thomas@monjalon.net>, "jerinj@marvell.com"
 <jerinj@marvell.com>, "mb@smartsharesystems.com" <mb@smartsharesystems.com>,
 "zhoumin@loongson.cn" <zhoumin@loongson.cn>, nd <nd@arm.com>
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: <AS8PR08MB7080132EB8B56AD5BE02A87B9EFE9@AS8PR08MB7080.eurprd08.prod.outlook.com>
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 <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

> -----Original Message-----
> From: Tomasz Duszynski <tduszynski@marvell.com>
> 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 <tduszynski@marvell.com>
> 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 <tduszynski@marvell.com>
> ---
>  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
<snip>
> 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 <ctype.h>
> +#include <dirent.h>
> +#include <errno.h>
> +#include <regex.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/ioctl.h>
> +#include <sys/mman.h>
> +#include <sys/queue.h>
> +#include <sys/syscall.h>
> +#include <unistd.h>
> +
> +#include <rte_eal_paging.h>
> +#include <rte_pmu.h>
> +#include <rte_tailq.h>
> +
> +#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;
> +		/* <term>=3D<value> */
> +		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);
> +}
<snip>