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 C328042380; Mon, 9 Jan 2023 16:40:54 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 79BE940687; Mon, 9 Jan 2023 16:40:54 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 2C62F4067C for ; Mon, 9 Jan 2023 16:40:53 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3099aHrA014570; Mon, 9 Jan 2023 07:40:49 -0800 Received: from nam11-bn8-obe.outbound.protection.outlook.com (mail-bn8nam11lp2169.outbound.protection.outlook.com [104.47.58.169]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3my94tpb06-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 09 Jan 2023 07:40:49 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cZoxVCAKECoxdvUFE+E5mHivUFRUQb34lEadOun2eN1NLBFZGbFlTvdq17swxOzqyGJrkQkcq03M6MYsOvvlDkaQlrspRJF0WWWxKX96cQ7vOjSBVjL9NzpWuhUuObX2pauVqmaYJnt2HwesmzyBYBuQ3mLrq3NvzHtpNJpXdEYpe81zzAAZuBOKCVfn4TBow/c1olVXcM1RqOi0Pn1seaJOg9GaW4ZQ6fWsYOLKVq2zDpidsM12OrQ9p6duOHVlJIV9hVxx98jzuA5H1hSSVUrqyvBFvTllTzOXW7KrGq8kRbRyIP3S/LbHmAQPHAXc1E9G8dgdzz2JljuGO1srEQ== 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=wQ5ZqfLXxSZvFNoGhvoJy5+/4cibJgUUksflnxFLVIU=; b=Jqp4O97EOMeibMmVVNNJzzm8KJTknsV4Ujw+j/9xBxnkNFaNOF/3SRIYYCCpAq5qUc33smwBt6k0QOovMfnoikGBU+azK7yZpbp+sdoSwoTsxWV5iBg5v0RTc5d5WsMN2kl4YsF8lfjxEx+QGO6JPitic5imzits63lR6WUJ2zflEvhjZAy36uDsvo7S7wx6MzMbkqaDLcXXihV6UcdYP0u6hu7Q4tn5zKVMZFbtHdSIfs0yWHwU4IemNhNR14WT1RPitey8kn6OmPgYMpNRk/mnqNv+WMZJ4P3CcVIRYyk1d8tTZcE/Wtgr05d0fz3m4jFZXQZMaB8sNxldo9YNww== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=marvell.com; dmarc=pass action=none header.from=marvell.com; dkim=pass header.d=marvell.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.onmicrosoft.com; s=selector1-marvell-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=wQ5ZqfLXxSZvFNoGhvoJy5+/4cibJgUUksflnxFLVIU=; b=QRp9n2A6dZ23N3e1usUbHlRkDnw759hMmZ9RRVEMa773xDAIz44VG4oqDhf2IZV8Zjpj8Zq6i0XxLTl7DRiM/iTmZ8K0p1LLaKKxd7RIvdx4nmxc77YD0NjrKFh6TX57pB6EGIZgrk+HpgatzAYrx2pTDzLy1NsAGTRdnr6duho= Received: from DM4PR18MB4368.namprd18.prod.outlook.com (2603:10b6:5:39d::6) by PH0PR18MB4906.namprd18.prod.outlook.com (2603:10b6:510:121::7) 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 15:40:46 +0000 Received: from DM4PR18MB4368.namprd18.prod.outlook.com ([fe80::3117:f51c:37c2:fa05]) by DM4PR18MB4368.namprd18.prod.outlook.com ([fe80::3117:f51c:37c2:fa05%9]) with mapi id 15.20.5986.018; Mon, 9 Jan 2023 15:40:45 +0000 From: Tomasz Duszynski To: Ruifeng Wang , "dev@dpdk.org" CC: "thomas@monjalon.net" , Jerin Jacob Kollanukkaran , "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/QEhRtFHSga0yHSOMIy5Zzs66V3J6AgACFIpA= Date: Mon, 9 Jan 2023 15:40:45 +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: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: DM4PR18MB4368:EE_|PH0PR18MB4906:EE_ x-ms-office365-filtering-correlation-id: 3d48ab32-0395-4941-86ff-08daf257dfd6 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: gLIHdFDnUlkKE1mf9gkySsyXNB0OEjZ6EhpWqxnHFIFWamxKaqJj0RE/YtjAWlFi97dMMx+RgrXEF5JwDXmHOlQuBrpdkKCg/i1EKfU660MdrOKy0YGsAh+pVzXF06raryG8KyKKw5Ggn6FdWVd0ZE7oyLgN5caUhPI2uzOpNJaccNw//NNJGKyx7werG5jJcjdAkViUqsBd3pL6SQtOeV1BgFpEolfIy0RAIxWIeD6S8nwgkWfL97qtG36nkqF14ZFGuXONPXGNSRv7G8pVN9afVBZA5hCf8Eu107XE5weXWSzdzdJWIzbikbUOhbwk73VrgPKwPXAwrhg7HhBdiLLZPY1kWlMYmlxQL7vgsOphPQ5NHxfyCUyLVHBgqjvP7t/IrvIZp2SwTggRqs8UUHmUNEd/+SP9P0q7mB6/V5FTs7tUG7WnIlagp3vHWSOX9ItBiUSalpV4xi5x+v7Qwcf40IydYycqiqLflBKG6+Q67ZGo474wn8f7g90dlsiSprwETP0YsHvm82jQ34f1hy71Aj2W8lGBBV9fkoDe0o5h2LCdFI2k2Mt14uEikWqlVjc51BNwg3A2TtFfPWsJqhWbMk2R+PNOAGkA7Q+b5iKOEI51tkyX3wFgW2X2/5BCzrtVQ8rpXAP7881beeTUtw+UCBWkCiJiuZxKQcqRmVy3FzIrTowNx4fHK5fdICsRyqv6uT3oXBnBeToK3hyuOUsKr/nRTG0sUFx8SGk1iaI= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM4PR18MB4368.namprd18.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(4636009)(376002)(366004)(136003)(39860400002)(346002)(396003)(451199015)(38070700005)(33656002)(30864003)(5660300002)(316002)(71200400001)(9686003)(26005)(186003)(7696005)(478600001)(55016003)(41300700001)(8676002)(54906003)(110136005)(66946007)(64756008)(4326008)(66446008)(66476007)(66556008)(76116006)(83380400001)(52536014)(8936002)(86362001)(53546011)(6506007)(122000001)(38100700002)(2906002)(41533002); DIR:OUT; SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?tuVCJEewVL8YuYDiFEwrzuCCPallpGjjwViUPNzP+I75hFls1HdOE+xcAFwz?= =?us-ascii?Q?xSfN7iyM+moDHi4fRohb/49gKmFuHYM/+Rpn1UJx7jMD3uHmzOQTK1eHocVX?= =?us-ascii?Q?6XTWmWjuv3wGYXJR/8x7pAlIAER2e066o2ApXqMIJN2bTDluY57oAalCZCR9?= =?us-ascii?Q?mf42krvGP+SfOCwBHptWuBBeLLf/PZcQy43EcaWCdN4GoaCwKdc4SC+6vDT9?= =?us-ascii?Q?ndnjd2HK0AGOJt7vyw3zLCjEKXog9l+6MxRUBll9i9qHmnGTyWvJwoijRJq4?= =?us-ascii?Q?yTukbEMW9uzmOeigVlVlBeNJEwl3Isr1mtP5ELWWbzaQ1o/nlXkLi59fBmL8?= =?us-ascii?Q?t5qCiwPeuMBxpYYdhdCl1aNi/Hb2twO02TxvtOi3R6dB/Lpdyq5mRod/JU51?= =?us-ascii?Q?p04mxzFJDY64rFsB3qlo/W6c1jhqA0kJuykOhYrgt9qE8zqqDG4WJ9cR5w91?= =?us-ascii?Q?sE83F9WDnuYnv5DYqeuP/N+yfkLZ2fyPyTJe0iT52nFoC5YPeUHiodI5gB0B?= =?us-ascii?Q?R1O3KbLmSiJah5jKXdYfy9RfeATKbs1bcVzT1cJf28MRtAW7bvZ0gMCTgF/P?= =?us-ascii?Q?Kt3VBC6VOjxsg0tXqap/bm2eGcnKLmecUypgmzdhTMAGvei4xIUOIcxoN4TU?= =?us-ascii?Q?tfKMr268/u8P9hIu6ixPCyzkOudd2k+7rrpswK/Qz8onJu0kVdqdhV9lU3JN?= =?us-ascii?Q?wwc7KqjfiyeO1ArLnDTAejjfn3pcgV5dQYN6/1ZCK1R30LTXMh3BEA0SJNIw?= =?us-ascii?Q?WTVhMKKvyI7a7R+2ggs1Qksq87D7XKEDKeDNlEM+g3Z6eud2FZ16BvJGcvif?= =?us-ascii?Q?gLGzsg4kfJtOSQwVa612YqEBoJhRfWENFGadKKCXIrzI7d6xik5BgGR9aKWG?= =?us-ascii?Q?xVwaV5YuXHU9M/2tlSrzyiZe5IdMvNwzODUADDqszsoSer6ArwClLwhBq7I0?= =?us-ascii?Q?Pmw94OE24h4/hJIMINPMabSC7aEglqGZ3W9MctZsxhv7Uttvk6VOoSckO8AT?= =?us-ascii?Q?Vg/1SZwbjeNw83SRXW/MmpWSKnF39t8CxWzkqDVBPaitsKN/tjcHrmupWXrr?= =?us-ascii?Q?r8tiMyMQ/3Vn9RGPeUA+gTOgms8CKJmL8la5ktsCw8poR1J6uYZFC3BhJxyj?= =?us-ascii?Q?2rfdwtzFAPk1bzsQn+xpbEah7AyOat+4VhF1c2qCSFUKBp3z+ZW3rOKCnhRb?= =?us-ascii?Q?fKFDIGjV31TMkMLoKPt2wYyQBVM2xQrX+9fDZ9Cp5ybGATpTtMGlHzjGPoKb?= =?us-ascii?Q?6zdoCwPRjkHhM316HBIWMexV3sdt8cOYqszevoMUXsTL/sQzTVs9VezOMgUu?= =?us-ascii?Q?veTsPHsdJSzv4U1EXZVtptFrQcAcS/M5KujDDNfp+N1CmYXGHUom0LpgSzLF?= =?us-ascii?Q?BexujzlQ59ztjmVpMj5dApplgl8L29dik8pUT/e1vYb0xUyJBO4/4XMQSWgN?= =?us-ascii?Q?jBg8XSbRQaKk17J6OiCI4WeE7/1A1d/732FLBpI2Ki/ohEjF7rFJ3HCGEarx?= =?us-ascii?Q?n+1QgqsUfmNofyDKLU7GXU8qRP6VdIfs77Pv3F/21YIhdG1vzDimBLYG82vq?= =?us-ascii?Q?SaeGhJJQCSKRLnNhswXuWwsVm3D+uJmRhO/D7vVn?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: marvell.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DM4PR18MB4368.namprd18.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3d48ab32-0395-4941-86ff-08daf257dfd6 X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Jan 2023 15:40:45.7332 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 70e1fb47-1155-421d-87fc-2e58f638b6e0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: ug000jf4yCKXzrUh7vShilO5eiMjslx+j10dNwV0J22BQgzhbR+TmQgYZBZEWufOxTx0tLvkLkJnF+cNMgoQCw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR18MB4906 X-Proofpoint-ORIG-GUID: UnDfd-S90AuvGCS9jur_UC4zt9w1fsVH X-Proofpoint-GUID: UnDfd-S90AuvGCS9jur_UC4zt9w1fsVH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.923,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2023-01-09_09,2023-01-09_01,2022-06-22_01 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 Hi Ruifeng,=20 >-----Original Message----- >From: Ruifeng Wang >Sent: Monday, January 9, 2023 8:37 AM >To: Tomasz Duszynski ; dev@dpdk.org >Cc: thomas@monjalon.net; Jerin Jacob Kollanukkaran ; m= b@smartsharesystems.com; >zhoumin@loongson.cn; nd >Subject: [EXT] RE: [PATCH v4 1/4] eal: add generic support for reading PMU= events > >External Email > >---------------------------------------------------------------------- >> -----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; >> zhoumin@loongson.cn; Tomasz Duszynski >> Subject: [PATCH v4 1/4] eal: add generic support for reading PMU >> events >> >> Add support for programming PMU counters and reading their values in >> runtime bypassing kernel completely. >> >> This is especially useful in cases where CPU cores are isolated >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use >> standard perf utility without sacrificing latency and performance. >> >> 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 >> > >> 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 smal= l 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->f= ds[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_= id); >> + 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", na= me); >> + 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? > Next series will take use of global pmu instance so this will no longer be required though your suggestions may be applied to other pointers around. = =20 >> +} >> + >> +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= . > Yep.=20 >> + 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); >> +} >