From nobody Sat Jul 25 00:01:55 2026 Received: from DM1PR04CU001.outbound.protection.outlook.com (mail-centralusazon11010025.outbound.protection.outlook.com [52.101.61.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEAAC3290D9; Wed, 22 Jul 2026 02:13:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.61.25 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686408; cv=fail; b=MqxVKFZ+EMzE5L/dgh4XJ0a+cXrbHyxUrwNiEhwoRt6eIsTDXMCFJ3F+OOOnX62EnzBjJn6Uqjktvzw0jf4aI0zwcyE2RmgNpIx9ptFQMnPONDjmwjX0YJYDam7FWo4AcN45ZMQDw9wHcpHLd0JKyi59CSE//2iu875AxTu5iGo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686408; c=relaxed/simple; bh=6CSbNCRh3YDm72pI6OEgqfuKeQNHzSqmmEDQ7mKq38k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=DRYCmkzhEkm4tEAJKdso4IdCo7MZMlGs/lq0sEA/KTjfNYrvaca/YUEjHrU6IX0D4iBPWrqidcslA0rRr9tAqJydOuaRzsFb1dD123nDmIZ2yMnfVWr9RXJnD4YRl+9nBOVJpl/VXAVuUx1d70C6AUJrhENpyfe8jgC7l4bIGCk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=csEluHRA; arc=fail smtp.client-ip=52.101.61.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="csEluHRA" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Lz1WbZp1J1jQmTkLZUYv9MzzE9tRBWgirkz/RQhzFOE8WxU7AZwoINRt5cz5JaiJDKihuetIE3/tZuF/2drjFnQ5BwnA8hSwmNIm4AyOEGPEL/4pnZHipt8InO0xUdSv5BMoPfJ7xenZQwSgE+38KCap3fJnVKk8UdP69//XpKJ8E+StwQPCDSIuQzhB7FkYSEiguE0+n1Ck5elBV1BbxYL4phea6OaSVuEts6eAwT4tb97CuKQQ1Gx7hyfrQz5BHbxbyo7TB44Cx3ZJEE6oEQ/+1PWKnGMh0JnUdmaIhxGJAsZYRg+mGMSNoBMpDkaLL+mAC+GcmwJRTtXG+ZvH/w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=++CKLm2v85L/K6DtqpbZ7tzklr9oVdC+KaxGpZnsyTc=; b=QDx2WpY7XpAn7VyM3bWqnRlToKHx9mHPMxoaMlMoZphwSLW/S96jHDngozYN0SRklUb6YtC2KQra7RC+E7XRxwpNttk0pok2yy/mpK0dJfEX0muaU0MfliOiO0KBq1+lpurEj2uLibR8Ck5e7DbB+mRfR/erTOgYPZGC9kmvaCDgLu/BJwQkbQFB0Qq8BA1Go+FKWx8lFnha4jyHWq+3Eu5QZoPvXfpLnimmBuspA4xzKdyq1M240QR/ILCNFA267s8OPWJ/HdiZZ+rxHoBPAWbGT0JI80cwUg7pI+uo3+EvQfbKrfxSDd+GgFLfBhpAzDpZ1Oyvs/JumfW+/Fz+Hw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=++CKLm2v85L/K6DtqpbZ7tzklr9oVdC+KaxGpZnsyTc=; b=csEluHRA6WrSq53h8+zWZ9ZxiAXRuoAo8tvw3hvr2TlFdA8J869hYvcUxXGvO3o+ItE6Vk0Ht5dyJXcTX8fC4+kc9W9RIHA8xOR4J+zvXpp7YUHD3CLYww1iBzdKjPm0OUh01qAA9xoOpQWIRnHJLHaGMfTwvNsMdHmwIhVMfOmhafChbJdFABitN32PrS5Q7OBxW/JZU/mQg7PIJ4dzRFzaqjIhDmT+Km2I8zZI0pFlZ0xmxt77P7ZgG1DAX4d9DwiVMYRlY/ba9n2ieRbJycD+lXgrw6/kLaRkRwwCN4u/kPUixf5oyqy73ZbK3TMeXJ3P2j+3hGkz5jB/heutRw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) by SA0PR12MB7002.namprd12.prod.outlook.com (2603:10b6:806:2c0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Wed, 22 Jul 2026 02:13:20 +0000 Received: from BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8]) by BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8%5]) with mapi id 15.21.0245.009; Wed, 22 Jul 2026 02:13:20 +0000 From: Richard Cheng To: tony.luck@intel.com, reinette.chatre@intel.com, x86@kernel.org Cc: Dave.Martin@arm.com, james.morse@arm.com, babu.moger@amd.com, shuah@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kobak@nvidia.com, kaihengf@nvidia.com, fenghuay@nvidia.com, ltrager@nvidia.com, Richard Cheng Subject: [PATCH 1/5] selftests/resctrl: Make memory bandwidth measurement vendor-neutral Date: Wed, 22 Jul 2026 10:12:59 +0800 Message-ID: <20260722021303.9471-2-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260722021303.9471-1-icheng@nvidia.com> References: <20260722021303.9471-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SI2PR02CA0021.apcprd02.prod.outlook.com (2603:1096:4:195::10) To BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL0PR12MB2370:EE_|SA0PR12MB7002:EE_ X-MS-Office365-Filtering-Correlation-Id: 298a6254-7ddd-45da-0b1a-08dee796cce5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|23010399003|376014|1800799024|6133799003|56012099006|11063799006|10067099003|3023799007|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: cxhYlGfs7tuJCr1caVVA8CTpvF5/W6zh6ITLqLWje31rCZWLGHZR3np2KZZPP4FZbIC+qL66u48v85UeQciAsTGQFSfM0Mu4pO83hBpcNJ82jYAFG4r+p5kKrPdEj+/esBH82BTwrYDJ3kE8xNQTzfM2IfAFuAkOCVPuB/V5pYaNOix5Y3VjmQ+e/UExUSjuumNuoZ0s6b2v8M14zsyJQibI+3uJ4YuIKcx/C1m3LBNKJ5c+md6QwwpMZH5i3kZci1h3BsneeKNoEG8dXFa9L1YLnFaSq9/jxFxnG4dmNtp6bHmcW4jzKL81jEsTM7AqI6Km0xsRHcuYJli81LQBEktSoXGKp7RSsQtlQItv5CFHKIvljxbgTSisaOs7Wuss+XYu6GYIZeHuyGKdPqbVO/meDdj5YfGTpjtYEs2Bm7NEoFmtWe9hXb0IpK+iTWKxUfFmRdW1a+mBHPFNdtb0iI0ASfiIomira6PJkAxZrPwFVgvdKhtJnznfgwT9tWVjcECHUurSmdCf1qgDhuZaNbWgmWcSa9lpptheS5CZDNAeUNvY2N+uYfZ2T2kD2MeCJAZWRgrkd49Qn7vgsLLTEH2PlTBCoKEOd5TrWBZQmy9kZ/ehqdgcyNFaVcUeb6WGnPzD6mCA4aP08D/i4AnimLYIcW9RuRVFX0MZZxM58eA= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL0PR12MB2370.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(23010399003)(376014)(1800799024)(6133799003)(56012099006)(11063799006)(10067099003)(3023799007)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?R8LSVmVvTo2IGph3SWHmH36xUcBrUSUtNFPqbTlee8XmxG+mfxPzxBLhnDQ2?= =?us-ascii?Q?Oeg88sgCscSN63O/3lLLM4ivbP59xU8MTPdzLqEO2L4H3B7KX1jlruf3pwmQ?= =?us-ascii?Q?e4d0qfDR6EMOCJelYQuJTalfXKc5i/fzk8y783F2B+xSw5D8KRWzg5RSaW3b?= =?us-ascii?Q?A0IZRPuCYWt7HBSAlyDt++HcdkuW9UcmgQKC8rTMKRSAipgf8nV9KOaiWNbv?= =?us-ascii?Q?dp83gi+9hg33PhvF8v5vtoSepjfEmr4l9CGyv4SIBUM/9l4T1SIrImrSU7zx?= =?us-ascii?Q?9pj5GK89s2AlGkmbz6q84UfkxKThy6Qv1Go77FvrAI+FN1j4y1I6TuGBfIdt?= =?us-ascii?Q?EkHByKjF4iWWiv9RqdP/OiulCz7tafHw2HNPNv+E9D8FlP2/pj82Q0VwIDB/?= =?us-ascii?Q?lW1U7kjI+xgli1rjwZAj7C2Fjak1lVPphuAnwM0TVXlKduzDD4e2qFTDkzhS?= =?us-ascii?Q?7OIcC9zpW2MfrpHVAW2z+UkGLIrUp1ksiRhz2vo4qQB5/Y3ibXLBv5IrnUgk?= =?us-ascii?Q?ePwAWNVlmoKtOJbI/b8N4bgZ05iim1+BMv2vwodr8vN0LUPUWC8DAFzye+2W?= =?us-ascii?Q?hxEFzFRBsaqqCIy61hoPKxJNcXbhX8yig6P4LR20arPG/d/fp9P/mXNPg3cD?= =?us-ascii?Q?6v/Qf5GCgLWpc3nrOs6havq2YipoH/F/y/pM8uvJxGfFR1w5soaVu13X9FZ+?= =?us-ascii?Q?lyKxiEMCkqEIBxScOqvzXsFxx1bXsYyODj29h8DPx35SdSY9/F9ORxv3Ob55?= =?us-ascii?Q?sKIdfSl69TkGQe2UpmiOOd2r0sXmSfksImWobbkmhp8AhOPQLpnYFsLCCyk8?= =?us-ascii?Q?vMZTU0WPpiFUF2VkASSittZC5hH0lfc5c8LOGZChVbE4/o3sM6u2UJCfH4Vz?= =?us-ascii?Q?Lsi6YRYOqQZsmoosw62bwxHFEFzT0JzEeeMTf4kbsRXEsEfSRArXEuxZW+OP?= =?us-ascii?Q?pxNauFI2FpJi4WdouqGk65P5vqJocajYZLbZhHBq2T7poZVzF+1hXsoXFiTK?= =?us-ascii?Q?uMirnd8F3OKd88bTFafF5EmDQI1RKxaKnWm8TEte3Vp8GxFhpXok5NW80pQO?= =?us-ascii?Q?4gljvtKHlPHGfUI6Sh7EbgrpgNpyTCtK5UeouHzNHufoC+OHbgcLrLHvkyLL?= =?us-ascii?Q?NYvONHHB2JELydJCqg2bHm+eqQU+IS1r/zVIXIvom9Psix8FKX9+VI2fYwbF?= =?us-ascii?Q?13lN+da7UyrtiEcojaSRwxbzuyfTYo4DDvcvM43iG7MBXGRklJIklWBu4tae?= =?us-ascii?Q?J7YQaiKjSqLuKM0wT0g29QJwKN3Horb+e0xPxP9bB9xzphOFrzubBqtsSEFM?= =?us-ascii?Q?qGRQYP/qioFxSqjsCuxofiNVXUCczvG1qGB7detHxTLb2BNaEyv+l2Y3o7qS?= =?us-ascii?Q?2hRyBIM1V9BO7gt4rl/FI1uNNtwNJ5/GmxA8/Ub2ulwuuw73k2Twb/cbLGIZ?= =?us-ascii?Q?3hRgsT/mRUDJrGRte8jq4YvA5p5of+r7UWdrR+VPcyrB8Xr9WVZexX8Iy/jc?= =?us-ascii?Q?KdrdxJPifnV8NUSEJkOsz15wcvfH9hZoR8N4lBDOLU7i5OIuuAzJlA5TruC2?= =?us-ascii?Q?1S5slEKpjXyki1KxGDj7Kbt3VpMTTxHg5KJkDwQGdxWD4CjJ5ki3oKywpjzw?= =?us-ascii?Q?G7/Ub1kC0pgR82zFd4GUAUYGOCk1XYFxc6uYzMb7FPvOuEFh0C0ep/rr8252?= =?us-ascii?Q?iTnw6+Zt4RXnGpCHy8h+T2UnrlnNXBIf0PIXWRUL81kbbtqq6ENbp/zcLxbm?= =?us-ascii?Q?8B6C0Ug2JQ=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 298a6254-7ddd-45da-0b1a-08dee796cce5 X-MS-Exchange-CrossTenant-AuthSource: BL0PR12MB2370.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jul 2026 02:13:20.8022 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: JIpz0KOFcCwJyfpjWp7zJO2DCMXfrNI3Ahrmw3y7y+8JtdI4oLv/9wjLxBbu8FDZGKXC1/8132zvaYcmLEz/1Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB7002 Content-Type: text/plain; charset="utf-8" The MBA and MBM tests validate resctrl's bandwidth accounting against an independent reference: the Intel iMC uncore PMU read through perf. Most of the machinery involved (counter bookkeeping, the one second measurement window, multiplexing correction, result logging and the comparison with the resctrl value) is not iMC-specific, yet it is all named after the iMC. Rename the shared machinery and the result labels to vendor-neutral names in preparation for supporting reference memory bandwidth PMUs on other architectures: - struct imc_counter_config -> struct mem_bw_counter - imc_counters_config[], imcs -> bw_counters[], nr_bw_counters - MAX_IMCS -> MAX_BW_COUNTERS - initialize_read_mem_bw_imc() -> initialize_mem_bw_ref() - perf_open/close_imc_read_mem_bw() -> perf_open/close_mem_bw_counters() - do_imc_read_mem_bw_test() -> do_mem_bw_test() - get_read_mem_bw_imc() -> get_mem_bw_ref() - "Mem_BW_iMC" result file label -> "Mem_BW_ref" - bw_imc / avg_bw_imc -> bw_ref / avg_bw_ref check_results() parses result lines by field position, not by label, so the label change has no effect on parsing. While touching it, reflow the result-file fprintf() so the previously overlong line (101 columns since before this change) fits within the 100 column limit, keeping the format string unsplit. Functions whose logic is genuinely iMC-specific (num_of_imcs(), read_from_imc_dir()) keep their names. No functional change intended. Signed-off-by: Richard Cheng --- tools/testing/selftests/resctrl/mba_test.c | 26 +-- tools/testing/selftests/resctrl/mbm_test.c | 22 +-- tools/testing/selftests/resctrl/resctrl.h | 4 +- tools/testing/selftests/resctrl/resctrl_val.c | 178 +++++++++--------- 4 files changed, 114 insertions(+), 116 deletions(-) diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/sel= ftests/resctrl/mba_test.c index c7e9adc0368f..468ba8accc18 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -21,7 +21,7 @@ static int mba_init(const struct resctrl_val_param *param= , int domain_id) { int ret; =20 - ret =3D initialize_read_mem_bw_imc(); + ret =3D initialize_mem_bw_ref(); if (ret) return ret; =20 @@ -71,7 +71,7 @@ static int mba_measure(const struct user_params *uparams, return measure_read_mem_bw(uparams, param, bm_pid); } =20 -static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc) +static bool show_mba_info(unsigned long *bw_ref, unsigned long *bw_resc) { unsigned int allocation; bool ret =3D false; @@ -81,27 +81,27 @@ static bool show_mba_info(unsigned long *bw_imc, unsign= ed long *bw_resc) /* Memory bandwidth from 100% down to 10% */ for (allocation =3D 0; allocation < ALLOCATION_MAX / ALLOCATION_STEP; allocation++) { - unsigned long sum_bw_imc =3D 0, sum_bw_resc =3D 0; - long avg_bw_imc, avg_bw_resc; + unsigned long sum_bw_ref =3D 0, sum_bw_resc =3D 0; + long avg_bw_ref, avg_bw_resc; int avg_diff_per; float avg_diff; =20 for (runs =3D NUM_OF_RUNS * allocation; runs < NUM_OF_RUNS * allocation + NUM_OF_RUNS ; runs++) { - sum_bw_imc +=3D bw_imc[runs]; + sum_bw_ref +=3D bw_ref[runs]; sum_bw_resc +=3D bw_resc[runs]; } =20 - avg_bw_imc =3D sum_bw_imc / NUM_OF_RUNS; + avg_bw_ref =3D sum_bw_ref / NUM_OF_RUNS; avg_bw_resc =3D sum_bw_resc / NUM_OF_RUNS; - if (avg_bw_imc < THROTTLE_THRESHOLD || avg_bw_resc < THROTTLE_THRESHOLD)= { + if (avg_bw_ref < THROTTLE_THRESHOLD || avg_bw_resc < THROTTLE_THRESHOLD)= { ksft_print_msg("Bandwidth below threshold (%d MiB). Dropping results fr= om MBA schemata %u.\n", THROTTLE_THRESHOLD, ALLOCATION_MIN + ALLOCATION_STEP * allocation); continue; } =20 - avg_diff =3D (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc; + avg_diff =3D (float)labs(avg_bw_resc - avg_bw_ref) / avg_bw_ref; avg_diff_per =3D (int)(avg_diff * 100); =20 ksft_print_msg("%s Check MBA diff within %d%% for schemata %u\n", @@ -111,7 +111,7 @@ static bool show_mba_info(unsigned long *bw_imc, unsign= ed long *bw_resc) ALLOCATION_MIN + ALLOCATION_STEP * allocation); =20 ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per); - ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc); + ksft_print_msg("avg_bw_ref: %lu\n", avg_bw_ref); ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc); if (avg_diff_per > MAX_DIFF_PERCENT) ret =3D true; @@ -128,7 +128,7 @@ static bool show_mba_info(unsigned long *bw_imc, unsign= ed long *bw_resc) static int check_results(void) { unsigned long bw_resc[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP]; - unsigned long bw_imc[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP]; + unsigned long bw_ref[NUM_OF_RUNS * ALLOCATION_MAX / ALLOCATION_STEP]; char *token_array[8], output[] =3D RESULT_FILE_NAME, temp[512]; int runs; FILE *fp; @@ -150,8 +150,8 @@ static int check_results(void) token =3D strtok(NULL, ":\t"); } =20 - /* Field 3 is perf imc value */ - bw_imc[runs] =3D strtoul(token_array[3], NULL, 0); + /* Field 3 is the reference PMU value */ + bw_ref[runs] =3D strtoul(token_array[3], NULL, 0); /* Field 5 is resctrl value */ bw_resc[runs] =3D strtoul(token_array[5], NULL, 0); runs++; @@ -159,7 +159,7 @@ static int check_results(void) =20 fclose(fp); =20 - return show_mba_info(bw_imc, bw_resc); + return show_mba_info(bw_ref, bw_resc); } =20 static void mba_test_cleanup(void) diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/sel= ftests/resctrl/mbm_test.c index 84d8bc250539..001a87608835 100644 --- a/tools/testing/selftests/resctrl/mbm_test.c +++ b/tools/testing/selftests/resctrl/mbm_test.c @@ -15,21 +15,21 @@ #define NUM_OF_RUNS 5 =20 static int -show_bw_info(unsigned long *bw_imc, unsigned long *bw_resc, size_t span) +show_bw_info(unsigned long *bw_ref, unsigned long *bw_resc, size_t span) { - unsigned long sum_bw_imc =3D 0, sum_bw_resc =3D 0; - long avg_bw_imc =3D 0, avg_bw_resc =3D 0; + unsigned long sum_bw_ref =3D 0, sum_bw_resc =3D 0; + long avg_bw_ref =3D 0, avg_bw_resc =3D 0; int runs, ret, avg_diff_per; float avg_diff =3D 0; =20 for (runs =3D 0; runs < NUM_OF_RUNS; runs++) { - sum_bw_imc +=3D bw_imc[runs]; + sum_bw_ref +=3D bw_ref[runs]; sum_bw_resc +=3D bw_resc[runs]; } =20 - avg_bw_imc =3D sum_bw_imc / NUM_OF_RUNS; + avg_bw_ref =3D sum_bw_ref / NUM_OF_RUNS; avg_bw_resc =3D sum_bw_resc / NUM_OF_RUNS; - avg_diff =3D (float)labs(avg_bw_resc - avg_bw_imc) / avg_bw_imc; + avg_diff =3D (float)labs(avg_bw_resc - avg_bw_ref) / avg_bw_ref; avg_diff_per =3D (int)(avg_diff * 100); =20 ret =3D avg_diff_per > MAX_DIFF_PERCENT; @@ -38,7 +38,7 @@ show_bw_info(unsigned long *bw_imc, unsigned long *bw_res= c, size_t span) ksft_print_msg("avg_diff_per: %d%%\n", avg_diff_per); if (span) ksft_print_msg("Span (MB): %zu\n", span / MB); - ksft_print_msg("avg_bw_imc: %lu\n", avg_bw_imc); + ksft_print_msg("avg_bw_ref: %lu\n", avg_bw_ref); ksft_print_msg("avg_bw_resc: %lu\n", avg_bw_resc); =20 return ret; @@ -46,7 +46,7 @@ show_bw_info(unsigned long *bw_imc, unsigned long *bw_res= c, size_t span) =20 static int check_results(size_t span) { - unsigned long bw_imc[NUM_OF_RUNS], bw_resc[NUM_OF_RUNS]; + unsigned long bw_ref[NUM_OF_RUNS], bw_resc[NUM_OF_RUNS]; char temp[1024], *token_array[8]; char output[] =3D RESULT_FILE_NAME; int runs, ret; @@ -72,11 +72,11 @@ static int check_results(size_t span) } =20 bw_resc[runs] =3D strtoul(token_array[5], NULL, 0); - bw_imc[runs] =3D strtoul(token_array[3], NULL, 0); + bw_ref[runs] =3D strtoul(token_array[3], NULL, 0); runs++; } =20 - ret =3D show_bw_info(bw_imc, bw_resc, span); + ret =3D show_bw_info(bw_ref, bw_resc, span); =20 fclose(fp); =20 @@ -87,7 +87,7 @@ static int mbm_init(const struct resctrl_val_param *param= , int domain_id) { int ret; =20 - ret =3D initialize_read_mem_bw_imc(); + ret =3D initialize_mem_bw_ref(); if (ret) return ret; =20 diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/self= tests/resctrl/resctrl.h index afe635b6e48d..0de72327a085 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -49,7 +49,7 @@ =20 /* * Memory bandwidth (in MiB) below which the bandwidth comparisons - * between iMC and resctrl are considered unreliable. For example RAS + * between the reference PMU and resctrl are considered unreliable. For ex= ample RAS * features or memory performance features that generate memory traffic * may drive accesses that are counted differently by performance counters * and MBM respectively, for instance generating "overhead" traffic which @@ -187,7 +187,7 @@ unsigned char *alloc_buffer(size_t buf_size, bool memfl= ush); void mem_flush(unsigned char *buf, size_t buf_size); void fill_cache_read(unsigned char *buf, size_t buf_size, bool once); ssize_t get_fill_buf_size(int cpu_no, const char *cache_type); -int initialize_read_mem_bw_imc(void); +int initialize_mem_bw_ref(void); int measure_read_mem_bw(const struct user_params *uparams, struct resctrl_val_param *param, pid_t bm_pid); void initialize_mem_bw_resctrl(const struct resctrl_val_param *param, diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/= selftests/resctrl/resctrl_val.c index 7c08e936572d..ee44fbae2cbf 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -14,7 +14,7 @@ #define READ_FILE_NAME "events/cas_count_read" #define DYN_PMU_PATH "/sys/bus/event_source/devices" #define SCALE 0.00006103515625 -#define MAX_IMCS 20 +#define MAX_BW_COUNTERS 20 #define MAX_TOKENS 5 =20 #define CON_MBM_LOCAL_BYTES_PATH \ @@ -27,7 +27,7 @@ struct membw_read_format { __u64 id; /* if PERF_FORMAT_ID */ }; =20 -struct imc_counter_config { +struct mem_bw_counter { __u32 type; __u64 event; __u64 umask; @@ -37,36 +37,36 @@ struct imc_counter_config { }; =20 static char mbm_total_path[1024]; -static int imcs; -static struct imc_counter_config imc_counters_config[MAX_IMCS]; +static int nr_bw_counters; +static struct mem_bw_counter bw_counters[MAX_BW_COUNTERS]; static const struct resctrl_test *current_test; =20 static void read_mem_bw_initialize_perf_event_attr(int i) { - memset(&imc_counters_config[i].pe, 0, + memset(&bw_counters[i].pe, 0, sizeof(struct perf_event_attr)); - imc_counters_config[i].pe.type =3D imc_counters_config[i].type; - imc_counters_config[i].pe.size =3D sizeof(struct perf_event_attr); - imc_counters_config[i].pe.disabled =3D 1; - imc_counters_config[i].pe.inherit =3D 1; - imc_counters_config[i].pe.exclude_guest =3D 0; - imc_counters_config[i].pe.config =3D - imc_counters_config[i].umask << 8 | - imc_counters_config[i].event; - imc_counters_config[i].pe.sample_type =3D PERF_SAMPLE_IDENTIFIER; - imc_counters_config[i].pe.read_format =3D + bw_counters[i].pe.type =3D bw_counters[i].type; + bw_counters[i].pe.size =3D sizeof(struct perf_event_attr); + bw_counters[i].pe.disabled =3D 1; + bw_counters[i].pe.inherit =3D 1; + bw_counters[i].pe.exclude_guest =3D 0; + bw_counters[i].pe.config =3D + bw_counters[i].umask << 8 | + bw_counters[i].event; + bw_counters[i].pe.sample_type =3D PERF_SAMPLE_IDENTIFIER; + bw_counters[i].pe.read_format =3D PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; } =20 static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(int i) { - ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_RESET, 0); - ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_ENABLE, 0); + ioctl(bw_counters[i].fd, PERF_EVENT_IOC_RESET, 0); + ioctl(bw_counters[i].fd, PERF_EVENT_IOC_ENABLE, 0); } =20 static void read_mem_bw_ioctl_perf_event_ioc_disable(int i) { - ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_DISABLE, 0); + ioctl(bw_counters[i].fd, PERF_EVENT_IOC_DISABLE, 0); } =20 /* @@ -88,21 +88,21 @@ static void get_read_event_and_umask(char *cas_count_cf= g, int count) if (!token[i]) break; if (strcmp(token[i], "event") =3D=3D 0) - imc_counters_config[count].event =3D strtol(token[i + 1], NULL, 16); + bw_counters[count].event =3D strtol(token[i + 1], NULL, 16); if (strcmp(token[i], "umask") =3D=3D 0) - imc_counters_config[count].umask =3D strtol(token[i + 1], NULL, 16); + bw_counters[count].umask =3D strtol(token[i + 1], NULL, 16); } } =20 static int open_perf_read_event(int i, int cpu_no) { - imc_counters_config[i].fd =3D - perf_event_open(&imc_counters_config[i].pe, -1, cpu_no, -1, + bw_counters[i].fd =3D + perf_event_open(&bw_counters[i].pe, -1, cpu_no, -1, PERF_FLAG_FD_CLOEXEC); =20 - if (imc_counters_config[i].fd =3D=3D -1) { + if (bw_counters[i].fd =3D=3D -1) { fprintf(stderr, "Error opening leader %llx\n", - imc_counters_config[i].pe.config); + bw_counters[i].pe.config); =20 return -1; } @@ -124,7 +124,7 @@ static int read_from_imc_dir(char *imc_dir, int count) =20 return -1; } - if (fscanf(fp, "%u", &imc_counters_config[count].type) <=3D 0) { + if (fscanf(fp, "%u", &bw_counters[count].type) <=3D 0) { ksft_perror("Could not get iMC type"); fclose(fp); =20 @@ -221,46 +221,46 @@ static int num_of_imcs(void) return count; } =20 -int initialize_read_mem_bw_imc(void) +int initialize_mem_bw_ref(void) { - int imc; + int i; =20 - imcs =3D num_of_imcs(); - if (imcs <=3D 0) - return imcs; + nr_bw_counters =3D num_of_imcs(); + if (nr_bw_counters <=3D 0) + return nr_bw_counters; =20 /* Initialize perf_event_attr structures for all iMC's */ - for (imc =3D 0; imc < imcs; imc++) - read_mem_bw_initialize_perf_event_attr(imc); + for (i =3D 0; i < nr_bw_counters; i++) + read_mem_bw_initialize_perf_event_attr(i); =20 return 0; } =20 -static void perf_close_imc_read_mem_bw(void) +static void perf_close_mem_bw_counters(void) { - int mc; + int i; =20 - for (mc =3D 0; mc < imcs; mc++) { - if (imc_counters_config[mc].fd !=3D -1) - close(imc_counters_config[mc].fd); + for (i =3D 0; i < nr_bw_counters; i++) { + if (bw_counters[i].fd !=3D -1) + close(bw_counters[i].fd); } } =20 /* - * perf_open_imc_read_mem_bw - Open perf fds for IMCs + * perf_open_mem_bw_counters - Open perf fds for the reference-bandwidth c= ounters * @cpu_no: CPU number that the benchmark PID is bound to * * Return: =3D 0 on success. < 0 on failure. */ -static int perf_open_imc_read_mem_bw(int cpu_no) +static int perf_open_mem_bw_counters(int cpu_no) { - int imc, ret; + int i, ret; =20 - for (imc =3D 0; imc < imcs; imc++) - imc_counters_config[imc].fd =3D -1; + for (i =3D 0; i < nr_bw_counters; i++) + bw_counters[i].fd =3D -1; =20 - for (imc =3D 0; imc < imcs; imc++) { - ret =3D open_perf_read_event(imc, cpu_no); + for (i =3D 0; i < nr_bw_counters; i++) { + ret =3D open_perf_read_event(i, cpu_no); if (ret) goto close_fds; } @@ -268,56 +268,54 @@ static int perf_open_imc_read_mem_bw(int cpu_no) return 0; =20 close_fds: - perf_close_imc_read_mem_bw(); + perf_close_mem_bw_counters(); return -1; } =20 /* - * do_imc_read_mem_bw_test - Perform memory bandwidth test + * do_mem_bw_test - Perform memory bandwidth test * * Runs memory bandwidth test over one second period. Also, handles starti= ng - * and stopping of the IMC perf counters around the test. + * and stopping of the reference perf counters around the test. */ -static void do_imc_read_mem_bw_test(void) +static void do_mem_bw_test(void) { - int imc; + int i; =20 - for (imc =3D 0; imc < imcs; imc++) - read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc); + for (i =3D 0; i < nr_bw_counters; i++) + read_mem_bw_ioctl_perf_event_ioc_reset_enable(i); =20 sleep(1); =20 /* Stop counters after a second to get results. */ - for (imc =3D 0; imc < imcs; imc++) - read_mem_bw_ioctl_perf_event_ioc_disable(imc); + for (i =3D 0; i < nr_bw_counters; i++) + read_mem_bw_ioctl_perf_event_ioc_disable(i); } =20 /* - * get_read_mem_bw_imc - Memory read bandwidth as reported by iMC counters + * get_mem_bw_ref - Memory bandwidth as reported by the reference PMU coun= ters * - * Memory read bandwidth utilized by a process on a socket can be calculat= ed - * using iMC counters' read events. Perf events are used to read these - * counters. + * Sum all configured reference counters, scaled to MiB: read CAS counts on + * the x86 iMC. * * Return: =3D 0 on success. < 0 on failure. */ -static int get_read_mem_bw_imc(float *bw_imc) +static int get_mem_bw_ref(float *bw_ref) { - float reads =3D 0, of_mul_read =3D 1; - int imc; + float bw =3D 0, of_mul =3D 1; + int i; =20 /* - * Log read event values from all iMC counters into - * struct imc_counter_config. + * Log event values from all reference counters into + * struct mem_bw_counter. * Take overflow into consideration before calculating total bandwidth. */ - for (imc =3D 0; imc < imcs; imc++) { - struct imc_counter_config *r =3D - &imc_counters_config[imc]; + for (i =3D 0; i < nr_bw_counters; i++) { + struct mem_bw_counter *r =3D &bw_counters[i]; =20 if (read(r->fd, &r->return_value, sizeof(struct membw_read_format)) =3D=3D -1) { - ksft_perror("Couldn't get read bandwidth through iMC"); + ksft_perror("Couldn't read reference bandwidth counter"); return -1; } =20 @@ -325,13 +323,13 @@ static int get_read_mem_bw_imc(float *bw_imc) __u64 r_time_running =3D r->return_value.time_running; =20 if (r_time_enabled !=3D r_time_running) - of_mul_read =3D (float)r_time_enabled / + of_mul =3D (float)r_time_enabled / (float)r_time_running; =20 - reads +=3D r->return_value.value * of_mul_read * SCALE; + bw +=3D r->return_value.value * of_mul * SCALE; } =20 - *bw_imc =3D reads; + *bw_ref =3D bw; return 0; } =20 @@ -435,19 +433,19 @@ void signal_handler_unregister(void) * print_results_bw: the memory bandwidth results are stored in a file * @filename: file that stores the results * @bm_pid: child pid that runs benchmark - * @bw_imc: perf imc counter value + * @bw_ref: reference PMU counter value * @bw_resc: memory bandwidth value * * Return: 0 on success, < 0 on error. */ -static int print_results_bw(char *filename, pid_t bm_pid, float bw_imc, +static int print_results_bw(char *filename, pid_t bm_pid, float bw_ref, unsigned long bw_resc) { - unsigned long diff =3D fabs(bw_imc - bw_resc); + unsigned long diff =3D fabs(bw_ref - bw_resc); FILE *fp; =20 if (strcmp(filename, "stdio") =3D=3D 0 || strcmp(filename, "stderr") =3D= =3D 0) { - printf("Pid: %d \t Mem_BW_iMC: %f \t ", (int)bm_pid, bw_imc); + printf("Pid: %d \t Mem_BW_ref: %f \t ", (int)bm_pid, bw_ref); printf("Mem_BW_resc: %lu \t Difference: %lu\n", bw_resc, diff); } else { fp =3D fopen(filename, "a"); @@ -456,8 +454,9 @@ static int print_results_bw(char *filename, pid_t bm_pi= d, float bw_imc, =20 return -1; } - if (fprintf(fp, "Pid: %d \t Mem_BW_iMC: %f \t Mem_BW_resc: %lu \t Differ= ence: %lu\n", - (int)bm_pid, bw_imc, bw_resc, diff) <=3D 0) { + if (fprintf(fp, + "Pid: %d \t Mem_BW_ref: %f \t Mem_BW_resc: %lu \t Difference: %lu\n= ", + (int)bm_pid, bw_ref, bw_resc, diff) <=3D 0) { ksft_print_msg("Could not log results\n"); fclose(fp); =20 @@ -475,10 +474,9 @@ static int print_results_bw(char *filename, pid_t bm_p= id, float bw_imc, * @param: Parameters passed to resctrl_val() * @bm_pid: PID that runs the benchmark * - * Measure memory bandwidth from resctrl and from another source which is - * perf imc value or could be something else if perf imc event is not - * available. Compare the two values to validate resctrl value. It takes - * 1 sec to measure the data. + * Measure memory bandwidth from resctrl and from the independent reference + * PMU. Compare the two values to validate resctrl value. It takes 1 sec to + * measure the data. * resctrl does not distinguish between read and write operations so * its data includes all memory operations. */ @@ -487,42 +485,42 @@ int measure_read_mem_bw(const struct user_params *upa= rams, { unsigned long bw_resc, bw_resc_start, bw_resc_end; FILE *mem_bw_fp; - float bw_imc; + float bw_ref; int ret; =20 mem_bw_fp =3D open_mem_bw_resctrl(mbm_total_path); if (!mem_bw_fp) return -1; =20 - ret =3D perf_open_imc_read_mem_bw(uparams->cpu); + ret =3D perf_open_mem_bw_counters(uparams->cpu); if (ret < 0) goto close_fp; =20 ret =3D get_mem_bw_resctrl(mem_bw_fp, &bw_resc_start); if (ret < 0) - goto close_imc; + goto close_counters; =20 rewind(mem_bw_fp); =20 - do_imc_read_mem_bw_test(); + do_mem_bw_test(); =20 ret =3D get_mem_bw_resctrl(mem_bw_fp, &bw_resc_end); if (ret < 0) - goto close_imc; + goto close_counters; =20 - ret =3D get_read_mem_bw_imc(&bw_imc); + ret =3D get_mem_bw_ref(&bw_ref); if (ret < 0) - goto close_imc; + goto close_counters; =20 - perf_close_imc_read_mem_bw(); + perf_close_mem_bw_counters(); fclose(mem_bw_fp); =20 bw_resc =3D (bw_resc_end - bw_resc_start) / MB; =20 - return print_results_bw(param->filename, bm_pid, bw_imc, bw_resc); + return print_results_bw(param->filename, bm_pid, bw_ref, bw_resc); =20 -close_imc: - perf_close_imc_read_mem_bw(); +close_counters: + perf_close_mem_bw_counters(); close_fp: fclose(mem_bw_fp); return ret; --=20 2.43.0 From nobody Sat Jul 25 00:01:55 2026 Received: from DM1PR04CU001.outbound.protection.outlook.com (mail-centralusazon11010034.outbound.protection.outlook.com [52.101.61.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27F6B388E68; Wed, 22 Jul 2026 02:13:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.61.34 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686413; cv=fail; b=f6nbNab/ipxQjaU/ANHF1t9GvFT33+q/3efDL6rIfXdnFeTrPDVhFZNfezqKoL6FNb3SpIrGBNRzycsGvZBbez+DvH+5O0uw7juRsDsxEGuzdEhdxfLzgaq7uWPBu+Q+S71uTZ/WSaIYdK+JrGjH8rcyfcH961H0NHt+36R29u4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686413; c=relaxed/simple; bh=vTw8hO2jk/SU76/esJAx1ml9G6kUKteWpP+M1WRjPtE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=u6w8iDt2oL7X0LRjxZ3f4S2Wece8EZqR3OTXtAJFCjHhmZE9XHCBNqOEho1zvmx0m6mtM+ht75oO2zmzuHkagTM9OWzP+y1jwVkvxOmzKHmfLLfOsa5pWkUjSR8NjIACzGzQrKocw5Do6Y0zyF1NlO3Mys2HRdNp0AiVhNSv5zE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=Vpu+DXLf; arc=fail smtp.client-ip=52.101.61.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="Vpu+DXLf" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nzQT/HvrMlqqKGz+U++yTVUpDRyX/IXy9T8FFWbf/sbS1Pz00D0/r2VjLKgGIOMID7nZGKu1oMWi0NpE3fwMIbnezqyOJfmi/BXcQIfCMbJjNyVcrlUeqL8LJKXIVjLYQVEY+PqpJm5V4kDt9O96o8cQOC5Nx+PD2V1HRF3CQb2ExqYA9sRY58NFos/h8Be0L5dA/Tf+Kbw3e+Eo2W8+G4zQYvKocOyUru5WY6vTIBnFTpPSLEfJbrbfIWdWLCf+76epJBtZUZaZXDi/XnKRWtF+eGgFUc1V0WonMF+YHFL+TmTcRbX7JLdC8jGhSTBH4sRP33XvDhRcxBSdTO+uEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=8GjrW5SBJciLJDjKXrnxUISAjSv14y9IexFVu22a+0Q=; b=dmNnIs44rz0efvmCfmtW1Hzz3cqJY73aT8JMJs35SNoio8CtYrupBqLtTOZfPGFBITVGy6zU8UUtR/Ba85w9dprjdNJTelMWqb+dqjwdwGEOSyIB1HSwWCnqX34SalV1vpnnDT2R1wdoQKZr3fNUGUHEkzPidYKzOz3CU0yLx+4pHoPC1aYhMEAzsuYdZXGieK1LnxtbZR2UWBSRxcyg+hROUH1yvzHHaqJoiq59KL/mXiCH1yAC3LFgDgHH5waDTGxrFS5OiRiNOmb/3Uo9Ewr0ugmv+7n0qgvzYpClqaUKDoAd2BAJAlPIGFedYXqBSYHS8Gp2YXPiY9XClUUuvQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=8GjrW5SBJciLJDjKXrnxUISAjSv14y9IexFVu22a+0Q=; b=Vpu+DXLfaZHzMVoihnomRPiC9NLUCJlgVrC2K2ZzPmgv37FpmiNSsZBIfpdPYLJzmTKwOOEanpNpiu1wLcbqTAUxYkfFRXBvW0H12IJciBwFpNAeZ9H4VhxCCr+D2f6TqZk2yvseK42aop4lR69EJyi6JxHmyId3wZ8ForhJiUKTlU6iNPNzXJsbqH/Fia8o2D8wm199bIdkipwXa32mv38N1xwOxOMrk0SNWl9RuPxs6WuoVPBkZ93tFRt6vnQgHiHLyGrXVlP5PLrOoLDHpDYgD20b55Qx/s8jlJ2Aqaue7qUOBN8X7Tu1ZLHucZ/MecQUaQ0RwD5FafvYhTT/pg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) by SA0PR12MB7002.namprd12.prod.outlook.com (2603:10b6:806:2c0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Wed, 22 Jul 2026 02:13:28 +0000 Received: from BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8]) by BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8%5]) with mapi id 15.21.0245.009; Wed, 22 Jul 2026 02:13:28 +0000 From: Richard Cheng To: tony.luck@intel.com, reinette.chatre@intel.com, x86@kernel.org Cc: Dave.Martin@arm.com, james.morse@arm.com, babu.moger@amd.com, shuah@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kobak@nvidia.com, kaihengf@nvidia.com, fenghuay@nvidia.com, ltrager@nvidia.com, Richard Cheng Subject: [PATCH 2/5] selftests/resctrl: Abstract reference bandwidth counters behind a backend Date: Wed, 22 Jul 2026 10:13:00 +0800 Message-ID: <20260722021303.9471-3-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260722021303.9471-1-icheng@nvidia.com> References: <20260722021303.9471-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TP0P295CA0044.TWNP295.PROD.OUTLOOK.COM (2603:1096:910:4::6) To BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL0PR12MB2370:EE_|SA0PR12MB7002:EE_ X-MS-Office365-Filtering-Correlation-Id: c1b33001-a644-4d88-d34c-08dee796d15e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|23010399003|376014|1800799024|6133799003|56012099006|11063799006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: d0favaZgAss2O8tBHvHF7/ICH6O346IbIGcQTlPVM2VecDkvFAoVwbpfz+iFFBnhO/if4gc7uhO9oNAQMmals0dtH0Jh5lJXv37jW33jN4bc6riorQpuDmbK/PIe7ebYXDaNK44FOvzOj+QOiLkG4NC5NNm6j4TCA0FDuuDhfzeNVlO2jjsETyyRhseQkURlDWWwLmoPkMr+KSLT/jmgZud0zjSNZt/zp7GxUIbVtC/NKqVdKjZ2csphfd4L8jfvuwSSRgLPRNwXfOI6yvOXKnyCWfLrrTxQs+AuBbl5DSh9HtCE/guDpQn6QOV/3I1nlxmskp4o2VXvQv74fa8fB1RC2Sf9tk+NY7jWzp4N7OQwfZF1q6OVS+B7Cf/p9egu3IIxMh/2XZDC7tE+L4w20Ds3Z5gzfiDIvcQslUEo21I6r5tECCKq2vW0n4iuYrV+x+lCfj+XIa8GoEpccfLTGhgB6naYEYJC8JRg9mNXTStA+/3Cj+AlzE6pVyLFcy7+7orB5cJj3Uj0asfdhLCl7QUC5iCZW/4eGcDGwnYOwDC48UNvzpioMyrJrejxyQfOzZEkuZ5+psEz8QDm1opafqaiq6DGZtJ+r1Pf1uT28VB9NIseKhUL6M4h+tRCzdi4pgjhrvB4OtFIvaLoVhO/Z0mWP3aMkht72gqLKW0a8xc= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL0PR12MB2370.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(23010399003)(376014)(1800799024)(6133799003)(56012099006)(11063799006)(10067099003)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?MCjCriLjvbW2KYwIfB4NGFeFCKFYP+IAglMknqiF4HW///vHUGs1pYDJ20PM?= =?us-ascii?Q?RePIR/nDSfGxj1rwY1Dkn5T0Bt4qEqkBXZlFIQXMP1QleYEyaOcZNC9hYrA5?= =?us-ascii?Q?ZkbsKNzNNbK0OgXcQg+Eq20LEkl1nUpowqsHnvhHoSbR6nBrYAjxx3KzRe31?= =?us-ascii?Q?4siW/vb8IOiOv9X/lFDlZzw9plAeOILjbXW/iYx9OFoqjWO+fEH/CGV6bhNv?= =?us-ascii?Q?mfafNVYvgPohdacaxBJnYVY3+hv18wPbIVVXY7K2jicYQqIcyNO7mcMz+JRJ?= =?us-ascii?Q?2u+y6JTcGe9JCHGPhjv9sAUvfoP2Eg7T3wujOj4PkjGq25OKKMvgzen8vRim?= =?us-ascii?Q?Gz5KszXG5/bSMmYLLO8bBC9oBj7rH5Nki+W89Me+vPhIrnVESzuFXRs/qfv/?= =?us-ascii?Q?GZ5Rk+TAfL8T9Bg0E4YcxuLjhH0OUD0hBZpzIfaVlITGgDo1Exa7ul4i/2h3?= =?us-ascii?Q?tuQlYvz3oTdWzVQC/rfLeXXyxFcZ1iEyI23K4qFBj4vlD4vzAG/uedPjNZDD?= =?us-ascii?Q?U1rvEvLEZydWkTn8eYgvONkXy615F+7UNjgY/T7cymAhQYEaWMxy3HJSOAyd?= =?us-ascii?Q?WBM2tfvQ81xtXaw8f8tERTah5goqyTboODLkp1fB4zHIEJK0zr2ma1pgHkzl?= =?us-ascii?Q?K+FVq8busLjHcrMuHWDgHRYW5S71oHhbMbiD1huu/p4nxga+gTP5Vc3g+C7U?= =?us-ascii?Q?YyERapd6suCVXsxbYezz6xh0n7tj9vd08+McmdVNdVe68d4Yuo9b/zu1410m?= =?us-ascii?Q?iSylWWGhKGgGuf8VNUP8aF34/xCcg1CVNDDU3w/y5CRps+HzqUNqDjgGvt1S?= =?us-ascii?Q?VHPPW9kM1MNFpOuq5e9m6felu848X/mWSY+wMMVyFHpeXYpq1ngdOsE4n20T?= =?us-ascii?Q?Pthoiyn4ZEcmAEYpJTjedlRWu+0PdD7ryWjss7JvgOmX1exiWe8S0xHFCkbb?= =?us-ascii?Q?VMj+RUQ3VT9Hzii1Z3EadcmAkKRoFH2eX4ZUzNjzJrfA6zyNWvhJYRvCVYA2?= =?us-ascii?Q?eXLjh4NlA/h0J1sUyMGAT/iBp+JkV3Ol2CxJYV59YD72hthWrL5jUeHsdPxe?= =?us-ascii?Q?VRRAue+uYHI1BUDqEYqpEPCjCtjJ2E/ftW75kUfo/pH6TqJBgFG1iIGEE4KF?= =?us-ascii?Q?0g8QqmnRI9QotGQNAtA2AdkAQ2OzYC7Zact7GBDVyDNBcyWmZFW3sfxNzL9v?= =?us-ascii?Q?CphBwCnunAiFoPZoxaNoVfBMEuw/mikrg80YcDTU2lJScm09gQwCWtnYiNNu?= =?us-ascii?Q?u90RGAQhqpwPWAwhBbvyhnpMPVPKuEMZ3L+h2lWvsgKDKlUa2kvpaAIux+W9?= =?us-ascii?Q?ZLFoK8NF5fZsOG/p40DJRwHXNSx0I7TbdeObTFWvDyqNI2Yu4mwX2LrO73Dr?= =?us-ascii?Q?wINckiOiSdGVCWwHeMUQZrLYQHfu+b84LZO0qOaE66an9iER6kwIqOLTCc3v?= =?us-ascii?Q?RmQhR/lNAr/XgPOPUD95QYuErP82+FmsGHqJUEiT6iMutnUtrmPrMdbKzHOi?= =?us-ascii?Q?3iJvR3S/QgbtM3e75cDRoFDMk+yWvbKx6rbPNcVOmgPvtVGx7aIc6n30UlyM?= =?us-ascii?Q?0pnB8lolKQzJWG2ulXrnx31d/mo/tD89DzNBbA/cYmFXDMOj7+WMFRn2LMLc?= =?us-ascii?Q?Tt5yV/noz1yHHrnHtIrVr8/p0RUJqlrJbDiuAWFn8MpT14/rXt3AQSj5IPI/?= =?us-ascii?Q?DVFTFH+Hgxq7R0EvtDCZq9fdwsUJ2xYLn4rb0dsFLqLn2Khhcfe2002wYdRK?= =?us-ascii?Q?rGp82PzOlA=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: c1b33001-a644-4d88-d34c-08dee796d15e X-MS-Exchange-CrossTenant-AuthSource: BL0PR12MB2370.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jul 2026 02:13:28.1517 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: DSCojKSmeITNOAHtFOfTqbA1mvCiIC3iydzH0bZDryymrjOH/BZIuBnK1uXPr8CCmgR96rw40U58wmeshRtNKQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB7002 Content-Type: text/plain; charset="utf-8" The reference bandwidth measurement is hard-wired to the Intel iMC: discovery, event configuration and perf open all assume the iMC PMU sysfs layout. Other architectures expose equivalent uncore PMUs that could serve as the same kind of independent reference. Introduce struct mem_bw_backend with two operations, detect() (is this backend's PMU present?) and setup_counters() (populate bw_counters[] for measuring the benchmark CPU), plus a backend table currently containing only the iMC. Shared code selects a backend at init time and no longer contains any PMU-specific knowledge. Counter configuration moves from test init time to perf open time via setup_counters(), because a backend may need the benchmark CPU to pick per-socket PMU instances. Each counter now carries the CPU to open it on. The added per-measurement discovery cost is a handful of sysfs reads, negligible against the one second measurement window. Add mem_bw_ref_available() so feature checks can verify that a reference PMU exists: the MBA test is now skipped instead of failing at init on machines without iMC counters (e.g. virtual machines). Add mem_bw_ref_cleanup() to reset the backend selection between tests. Signed-off-by: Richard Cheng --- tools/testing/selftests/resctrl/mba_test.c | 4 +- tools/testing/selftests/resctrl/mbm_test.c | 1 + tools/testing/selftests/resctrl/resctrl.h | 2 + tools/testing/selftests/resctrl/resctrl_val.c | 145 ++++++++++++++++-- 4 files changed, 141 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/sel= ftests/resctrl/mba_test.c index 468ba8accc18..8b891d3e6650 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -164,6 +164,7 @@ static int check_results(void) =20 static void mba_test_cleanup(void) { + mem_bw_ref_cleanup(); remove(RESULT_FILE_NAME); } =20 @@ -210,7 +211,8 @@ static int mba_run_test(const struct resctrl_test *test= , const struct user_param static bool mba_feature_check(const struct resctrl_test *test) { return test_resource_feature_check(test) && - resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes"); + resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes") && + mem_bw_ref_available(); } =20 struct resctrl_test mba_test =3D { diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/sel= ftests/resctrl/mbm_test.c index 001a87608835..873acf6aa648 100644 --- a/tools/testing/selftests/resctrl/mbm_test.c +++ b/tools/testing/selftests/resctrl/mbm_test.c @@ -123,6 +123,7 @@ static int mbm_measure(const struct user_params *uparam= s, =20 static void mbm_test_cleanup(void) { + mem_bw_ref_cleanup(); remove(RESULT_FILE_NAME); } =20 diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/self= tests/resctrl/resctrl.h index 0de72327a085..2bd19c22a344 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h @@ -188,6 +188,8 @@ void mem_flush(unsigned char *buf, size_t buf_size); void fill_cache_read(unsigned char *buf, size_t buf_size, bool once); ssize_t get_fill_buf_size(int cpu_no, const char *cache_type); int initialize_mem_bw_ref(void); +bool mem_bw_ref_available(void); +void mem_bw_ref_cleanup(void); int measure_read_mem_bw(const struct user_params *uparams, struct resctrl_val_param *param, pid_t bm_pid); void initialize_mem_bw_resctrl(const struct resctrl_val_param *param, diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/= selftests/resctrl/resctrl_val.c index ee44fbae2cbf..a2b919bd4839 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -34,12 +34,29 @@ struct mem_bw_counter { struct perf_event_attr pe; struct membw_read_format return_value; int fd; + int cpu; +}; + +/* + * mem_bw_backend - Source of the independent reference bandwidth that + * validates resctrl MBM + * @name: Human-readable PMU name + * @detect: True if this backend's PMU is present on the system + * @setup_counters: Populate bw_counters[] / nr_bw_counters with the perf + * events measuring memory bandwidth generated from + * @bench_cpu. Returns 0 on success, < 0 on failure. + */ +struct mem_bw_backend { + const char *name; + bool (*detect)(void); + int (*setup_counters)(int bench_cpu); }; =20 static char mbm_total_path[1024]; static int nr_bw_counters; static struct mem_bw_counter bw_counters[MAX_BW_COUNTERS]; static const struct resctrl_test *current_test; +static const struct mem_bw_backend *mem_bw_backend; =20 static void read_mem_bw_initialize_perf_event_attr(int i) { @@ -94,10 +111,11 @@ static void get_read_event_and_umask(char *cas_count_c= fg, int count) } } =20 -static int open_perf_read_event(int i, int cpu_no) +static int open_perf_read_event(int i) { bw_counters[i].fd =3D - perf_event_open(&bw_counters[i].pe, -1, cpu_no, -1, + perf_event_open(&bw_counters[i].pe, -1, + bw_counters[i].cpu, -1, PERF_FLAG_FD_CLOEXEC); =20 if (bw_counters[i].fd =3D=3D -1) { @@ -221,21 +239,108 @@ static int num_of_imcs(void) return count; } =20 -int initialize_mem_bw_ref(void) +/* True if any x86 uncore iMC PMU ("uncore_imc_") is present. */ +static bool intel_imc_present(void) { - int i; + struct dirent *ep; + bool found =3D false; + char *temp; + DIR *dp; =20 - nr_bw_counters =3D num_of_imcs(); - if (nr_bw_counters <=3D 0) - return nr_bw_counters; + dp =3D opendir(DYN_PMU_PATH); + if (!dp) + return false; + while ((ep =3D readdir(dp))) { + temp =3D strstr(ep->d_name, UNCORE_IMC); + if (!temp) + continue; + temp +=3D sizeof(UNCORE_IMC); + if (temp[0] >=3D '0' && temp[0] <=3D '9') { + found =3D true; + break; + } + } + closedir(dp); + return found; +} =20 - /* Initialize perf_event_attr structures for all iMC's */ - for (i =3D 0; i < nr_bw_counters; i++) +/* + * imc_setup_counters - Configure iMC CAS-count-read counters + * @bench_cpu: CPU the benchmark is bound to + * + * Discovers all iMC PMUs and configures one read-bandwidth counter per iM= C, + * opened on the benchmark CPU (each iMC counts socket-wide regardless). + * + * Return: 0 on success, < 0 on failure. + */ +static int imc_setup_counters(int bench_cpu) +{ + int i, count; + + count =3D num_of_imcs(); + if (count <=3D 0) + return -1; + + nr_bw_counters =3D count; + for (i =3D 0; i < nr_bw_counters; i++) { read_mem_bw_initialize_perf_event_attr(i); + bw_counters[i].cpu =3D bench_cpu; + } =20 return 0; } =20 +static const struct mem_bw_backend mem_bw_backends[] =3D { + { + .name =3D "Intel iMC", + .detect =3D intel_imc_present, + .setup_counters =3D imc_setup_counters, + }, +}; + +/* + * mem_bw_ref_available - Is an independent reference-bandwidth PMU presen= t? + * + * Used by the MBA/MBM feature checks so the test is SKIPped (not failed) = on + * hardware lacking a usable memory-bandwidth PMU. + */ +bool mem_bw_ref_available(void) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(mem_bw_backends); i++) { + if (mem_bw_backends[i].detect()) + return true; + } + + return false; +} + +/* + * initialize_mem_bw_ref - Select the reference-bandwidth backend for this= system + * + * Counter discovery happens at perf-open time through the backend's + * setup_counters() since it can depend on the benchmark CPU. + * + * Return: 0 on success, < 0 if no reference PMU is available. + */ +int initialize_mem_bw_ref(void) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(mem_bw_backends); i++) { + if (mem_bw_backends[i].detect()) { + mem_bw_backend =3D &mem_bw_backends[i]; + ksft_print_msg("Using %s as memory bandwidth reference\n", + mem_bw_backend->name); + return 0; + } + } + + ksft_print_msg("No memory bandwidth reference PMU found\n"); + return -1; +} + static void perf_close_mem_bw_counters(void) { int i; @@ -250,17 +355,27 @@ static void perf_close_mem_bw_counters(void) * perf_open_mem_bw_counters - Open perf fds for the reference-bandwidth c= ounters * @cpu_no: CPU number that the benchmark PID is bound to * + * Counters are (re)configured by the selected backend first since their + * discovery can depend on the benchmark CPU (e.g. per-socket PMU instance= s). + * * Return: =3D 0 on success. < 0 on failure. */ static int perf_open_mem_bw_counters(int cpu_no) { int i, ret; =20 + if (!mem_bw_backend) + return -1; + + ret =3D mem_bw_backend->setup_counters(cpu_no); + if (ret < 0) + return ret; + for (i =3D 0; i < nr_bw_counters; i++) bw_counters[i].fd =3D -1; =20 for (i =3D 0; i < nr_bw_counters; i++) { - ret =3D open_perf_read_event(i, cpu_no); + ret =3D open_perf_read_event(i); if (ret) goto close_fds; } @@ -345,6 +460,16 @@ void initialize_mem_bw_resctrl(const struct resctrl_va= l_param *param, param->ctrlgrp, domain_id); } =20 +/* + * mem_bw_ref_cleanup - Reset the selected reference-bandwidth backend + * + * Safe to call when no backend was selected. + */ +void mem_bw_ref_cleanup(void) +{ + mem_bw_backend =3D NULL; +} + /* * Open file to read MBM local bytes from resctrl FS */ --=20 2.43.0 From nobody Sat Jul 25 00:01:55 2026 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013006.outbound.protection.outlook.com [40.93.196.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77BD9388E68; Wed, 22 Jul 2026 02:13:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.6 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686422; cv=fail; b=bQyScu61UbFNAqLevmGMxOXc1OE/Bm36Iuop/Z6naG1QOyxkwzStePpGVA64vU6mwEAbP2nXqdR91yGvVX0UC1kU5bWWaHTAp0rVdm6bV/2+VPX782Hx6TLxQCH9nzN6d8UhwR+UWzwp3xbuAAkmxNSQks7jJc/6yTuHabcj55I= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686422; c=relaxed/simple; bh=PVPJGqbAeH60CiLxG/vegQpow0sXbcGFg4yJbq/dXBs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=qFUCGJh2zhi2gxmA4v7S1E8ohyRb36ihNHBJjJhdWz3RV2UPX0O9H3Ardj45MpOGgrvzmsBMdASR+6Kwo5r0ufgIC2zSJfBFWeCOGyohY3DLHsiT428m9SYe2IvkD1n6lHJuLp6XDOa0Tz6M6kWtotg0M0yZ/bkUseHrsYEn9mM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=UlKYz/lj; arc=fail smtp.client-ip=40.93.196.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="UlKYz/lj" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Dxr4bZFbcLRmsx6yFWhUMmUS0PDJ9UN1W1nxbemxRVMMh+fkDoFLnV55FrMZHHI7X2QQFk36PVEEnAmcFm4Fqb8wdjbxIGHtVKexSEQ2Y5alp6vPkJeHsH2szDzPFv0KAIRc+JSrRl60W73HrYevLujuHmReaHealCuaFGe+WXydnW/aSLPX+ny7f+UoUdXcRX0MyRwIp15JW5pEal/nzLFzHVWkQ9ousr4EsLRtppFVVLtSYVdG3vb3OlWrr/LwSjULqqYohavc26vapgwtINvEzOz5mBnbJqP5CZdI2899nbPphki8FTwq+7LBGN/fGEO5XLAI7ghb/Tc581dg0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=oJZLGHcDNEvLcg0fyvZny0rcCFqacEclqhQuhC+wFJk=; b=yf+oLNN6xQDE+PawSoAsKC+gI/n8bKQGjThLP0ta9Idnu6blMar88Y0v+ARsACu75hRPS+ZYM0Ekj3F6CmX7XFBdWYHs6rOinLsVznUCRTTFyk1taGsJuLzcFrUPVCgFz/Ymh1ZHVDTvZGln1VR0QsBbIXHaF2fSMwhQNOC4JqXzlpq5w1EH78yC5oqmTalRkccJtOt74sj5/afmIGzZsd+oijteFe2SgEqYwLaNCFUdzKu6FTlz0pNV3RBxhkqIn7IzpLvae/TCqezI8C6ct3EVDfz1GrmdI8+6ycn9z4mA1KzEELKttrwwXY0DtBdyuHnklXRxqe6cyoGVjOnyDg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=oJZLGHcDNEvLcg0fyvZny0rcCFqacEclqhQuhC+wFJk=; b=UlKYz/ljMpMmaz3LKrR5qAM1jwKn0a9l46NkLFpCIZE33i6VtC2/eRktlwWuahhOUow8YUKh5e4zeuJUn81/F/moWTHL4EzmnlfHojDtvZmgAZQ0wWXN7vDxfdDzZ6CVxn06HPhkXNPrdb+x1zYqHwKJZ/mEJqSVByJLCJyFneldkDY24/RINvjCwQw47EKc08VnMxG4fbmiCpr75jT3YldMORQ6SE+H8+JbGpZay6Rfga0dUQxDEUlG0vbe6ZD20IXChQPOwr0428wWsZiOZC3gaFEjfo18s+R+DMIiQ3lMNKA2YH9BXTMUtGLwHhh3VEW6X8cpacugILYIgTxDPQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) by SA0PR12MB7002.namprd12.prod.outlook.com (2603:10b6:806:2c0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Wed, 22 Jul 2026 02:13:34 +0000 Received: from BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8]) by BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8%5]) with mapi id 15.21.0245.009; Wed, 22 Jul 2026 02:13:34 +0000 From: Richard Cheng To: tony.luck@intel.com, reinette.chatre@intel.com, x86@kernel.org Cc: Dave.Martin@arm.com, james.morse@arm.com, babu.moger@amd.com, shuah@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kobak@nvidia.com, kaihengf@nvidia.com, fenghuay@nvidia.com, ltrager@nvidia.com, Richard Cheng Subject: [PATCH 3/5] selftests/resctrl: Support the MPAM memory bandwidth monitoring layout Date: Wed, 22 Jul 2026 10:13:01 +0800 Message-ID: <20260722021303.9471-4-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260722021303.9471-1-icheng@nvidia.com> References: <20260722021303.9471-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TP0P295CA0036.TWNP295.PROD.OUTLOOK.COM (2603:1096:910:4::15) To BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL0PR12MB2370:EE_|SA0PR12MB7002:EE_ X-MS-Office365-Filtering-Correlation-Id: e8c092c1-e5b4-4b6c-208b-08dee796d4f0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|23010399003|376014|1800799024|6133799003|5023799004|56012099006|11063799006|10067099003|3023799007|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: /HshBzvXTqkFDEe+Fln5z9aJrWrOZ75cGT/54Ys9MpZyyuqcj67gNfxCLSDWFWGy2+JXlYke67lXKs7fGP+hkNZUEirnABkBrsbSQHOi+l2eTZMsGv0o63ltBAm0wXlXQfevFy63T23a02vUUfCJioCYjDvBiyjZohgiM+va4skkAyFLZqaDpozD0FizGKLaKwNTIPWcucp9ywvlOcbUCYlUdSTzekalWferBPUXlmqWsqIjMTpXwi+1INem5ls7FznJYYNsVvLRbjSVYHb+y1R1wBV5YYc368wBDJ13F25o5WiQNi9AyQL864bVaJJn61eIGmPp8lAIsS1QtpaT6Rh4Fp+AHKPa9bPxNaVbcFk4VQutsCqpQ8HsYSV+YM0vuQlsCFXMpS6bZXyYujrCc96gvYkX0QuUjTSUpqDefGRJc6GhUsjfT+M5hDt0ICdjN0BlWGDv4f/C/aQExxLcgkgXTt7z1j2tO7nrtROUQ/khjbqJi1b9E1uLME4i+CiZBOR32W6LZ0oPx2+n49/Wtjl87soFKITdsmH826Lgqt/eCJoYD2Vm9mzQPNMfNn1BRdThbzq9J5lV99xVL3sACrWS7JDYZNUxYSUBFdQHjS2mjHNZTr6IOYWC0ZuoCw2EELOBHkS3CvjTAFPaP9fgswhmodDxNDgs9Gx0HajuAEI= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL0PR12MB2370.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(23010399003)(376014)(1800799024)(6133799003)(5023799004)(56012099006)(11063799006)(10067099003)(3023799007)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Y1AqHgiBOuvgyFNg/7rrMPIPw5WKhAqja8wYqOwHw4CKUCwhTYhWofZNUzpx?= =?us-ascii?Q?kpZBDKMMWO1BLV1VxhXoujCrf8QarhJ1dQWCXfotYLWTWF/8VCKCtuwtmF7J?= =?us-ascii?Q?NJNpC4eB90VPu6LYTMeWJOGAVFj5zkK/dKhzPIT0jCnwVRH0Zdsn4CZOXX0e?= =?us-ascii?Q?zNSmOuA23Njw3pzjnNl3clxaHTugeBoUdNR2Nb1lm8Ispf+F7zTTvClDwk/C?= =?us-ascii?Q?HxOogmeYP9YEd6LlsxaFjCww86o0d95oxKs79Bao5PPpzEfBMkU8RunInJWr?= =?us-ascii?Q?C/1WOBhCOqFmZiLPNt532/w3cWbbkSPpunSD2ZehiiYVW1X651P5XNCnhZGW?= =?us-ascii?Q?aEpLoKNWJfYpakZGCw8FESVnGn9D4Rb1lJR0sZftdYoz59xhuRX4nK29Xxev?= =?us-ascii?Q?SbMHtWKTsJu/OrcuY39oDv1WoOYB3q3nDkZDxI6V0DGW7xJvfcGXFBBIqS33?= =?us-ascii?Q?JM+lPDUj4my5I2o8QJ3D5eUsjW+JNITX0HjibDaVDsUfbrfYT2mdghDuOLUs?= =?us-ascii?Q?CFo/GsSLgiylWJ7G/CwrMagHIulo6y3CcMjhoX09VOMri+7nB6fM/1BCK6tq?= =?us-ascii?Q?63jOLCOL6soH77tSAIfDzuvvs0J0161y5JOjZeTw0N5G2wBBCfJZ9Ywf5CRC?= =?us-ascii?Q?zKaoqqN2Yu+XIFRq6QQz56EHyDdy9+xFCBT4q8Ny3c7uMztYQE+Pjt4Tpw7n?= =?us-ascii?Q?5+clsDIQeYtyxMjpApCKNYxUAKZ9GniYud7XU2kl0kX5dxZMsQFO5nAWqsjN?= =?us-ascii?Q?1+jLoV64lkwOESyfIOYWoJyqXWvlLnQvfgrKJ4xoBwlkBBp/hW32Wv58g5cs?= =?us-ascii?Q?HUzIDcqiwccTsDOGHJx75okk4noW5IoQ104prRO0C30iYb2fLvB0VD1C/k38?= =?us-ascii?Q?vqgWdAM1FsF+hDRwrV9vt44yNXb42NlXrCfBBoki92kDAK7tG49grDXBpI+F?= =?us-ascii?Q?tXAzY956Vx08QnnbkZiznzqKgjhLyKsqRLsmEw1acUUSw3fU3XkeJEQHjP8E?= =?us-ascii?Q?qyhx/K2OVIq3s2vW46Yb5LrBmp5v8pkQJAw1IrIUC3+lzr1F7wBEYXxSNQV3?= =?us-ascii?Q?y45SM++p1NcSV562jbwj8OZkgiCtNRp5Lcxyx0hbWzwkIYEL9xYoBheN8e8i?= =?us-ascii?Q?gDd951qx7Bm7ZX9NLN7VA1zqMaZ5hy2ACvn4+XUtTP/ZpBTC72Tm/GjZM1Fe?= =?us-ascii?Q?sw3p3BPId/t8bgEG541RPYefkqAUkv5xzDWtqTgIE1bAcwypDnsofJuia6/W?= =?us-ascii?Q?UhRNFvX59IfQxz89m1yTwovzzzg5TwyyjgMH6itZ5a39AzB8GPgXYkumBCaV?= =?us-ascii?Q?W9Jc0hin9E6CXQAR+h0YBpiGap8RWUvRX4LbqypAB5OuBrtj97uhChOYu0li?= =?us-ascii?Q?yXspoxnicoQ2ZyOHsNLFDfkWeZF19Hzw660MrHvzcJo+pNqc3WCmdMlu1GiO?= =?us-ascii?Q?9pomwz6STCB8mqrf1yvDjM3R8ZvmUJQ/AdKRgAZJnL8LEZ15W79mHfrBrJIL?= =?us-ascii?Q?JEmN42G1LZOpSR1OP2Thu/rrbDR7JQEdUTjZQgd8AEUTkJByDNIURw4jb7aQ?= =?us-ascii?Q?sKHNeT+zRIZGJ8l6J7zlkTGftAnf9E99KEj7DjlNILKp3C/pTcZsSZJuyus3?= =?us-ascii?Q?u7vglUZ8dv4srbIvQPqHRM//z4lQcmlvg1BIsOyRpltJcRIcnurEcsI5WO/h?= =?us-ascii?Q?NAMq0a/Mdf7xvhmP2JwnMGCHWYl8k83soi/kPxcZhvvEQt4RU7HHlVjZSgr4?= =?us-ascii?Q?UibTF+dvkg=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: e8c092c1-e5b4-4b6c-208b-08dee796d4f0 X-MS-Exchange-CrossTenant-AuthSource: BL0PR12MB2370.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jul 2026 02:13:34.2721 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: dzSB3ulAiCDqXQawpR55nMGwZKQQ4KhooEsSbExnTS1Bi+ricu3wlNdJOkEb182Ab40QDcndw4y9vr+0ksw/JQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB7002 Content-Type: text/plain; charset="utf-8" Arm MPAM systems running resctrl expose memory bandwidth differently from x86: - MB control/monitor domains are keyed by NUMA node id, which need not match the L3 cache id (on a Grace/Vera system L3 ids are {1,2} while MB domains are {0,1,2,10,...}). - Monitoring lives in a separate MB_MON resource that provides only mbm_total_bytes; there is no local/total split and no L3_MON bandwidth event. - In "mbm_event" (ABMC) assignment mode a hardware counter must be explicitly assigned to a group+domain+event before the bandwidth file returns a value (it reads "Unassigned" otherwise), and removing a group does not release its counter, so it must be unassigned explicitly or it leaks. Teach the test framework this layout: - get_domain_id() resolves MB domains via the CPU's NUMA node when the MB_MON resource exists. x86 (no MB_MON) is unaffected. - initialize_mem_bw_resctrl() falls back to mon_MB_/mbm_total_bytes when mbm_local_bytes is absent, and assigns an ABMC counter when the group's mbm_MB_assignments file is present. Note the assignment parser requires a trailing newline; without it the write fails with EINVAL. - mem_bw_ref_cleanup() unassigns the counter again. - The MBA feature check accepts MB_MON's mbm_total_bytes as the monitoring source. Comparing a reference PMU total (read+write) with mbm_total_bytes is a like-for-like comparison; the iMC path keeps comparing read bandwidth with mbm_local_bytes as before. No effect yet on any vendor: the MBA test is still gated to Intel. Signed-off-by: Richard Cheng --- tools/testing/selftests/resctrl/mba_test.c | 3 +- tools/testing/selftests/resctrl/resctrl_val.c | 69 +++++++++++++++++-- tools/testing/selftests/resctrl/resctrlfs.c | 45 +++++++++++- 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/sel= ftests/resctrl/mba_test.c index 8b891d3e6650..6c85107c32ee 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -211,7 +211,8 @@ static int mba_run_test(const struct resctrl_test *test= , const struct user_param static bool mba_feature_check(const struct resctrl_test *test) { return test_resource_feature_check(test) && - resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes") && + (resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes") || + resctrl_mon_feature_exists("MB_MON", "mbm_total_bytes")) && mem_bw_ref_available(); } =20 diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/= selftests/resctrl/resctrl_val.c index a2b919bd4839..0c3079d31340 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -20,6 +20,21 @@ #define CON_MBM_LOCAL_BYTES_PATH \ "%s/%s/mon_data/mon_L3_%02d/mbm_local_bytes" =20 +/* + * MPAM exposes only total (read+write) bandwidth, under MB_MON, and per t= he + * NUMA-node-keyed MB domain rather than the L3 cache id. + */ +#define CON_MBM_TOTAL_BYTES_PATH \ + "%s/%s/mon_data/mon_MB_%02d/mbm_total_bytes" + +/* + * In MPAM "mbm_event" (ABMC) counter-assignment mode a hardware counter m= ust + * be explicitly assigned to a group+domain+event before the bandwidth file + * reads a value; otherwise it returns "Unassigned". + */ +#define MBM_MB_ASSIGN_PATH \ + "%s/%s/mbm_MB_assignments" + struct membw_read_format { __u64 value; /* The value of the event */ __u64 time_enabled; /* if PERF_FORMAT_TOTAL_TIME_ENABLED */ @@ -58,6 +73,10 @@ static struct mem_bw_counter bw_counters[MAX_BW_COUNTERS= ]; static const struct resctrl_test *current_test; static const struct mem_bw_backend *mem_bw_backend; =20 +/* MPAM ABMC counter assignment state, see initialize_mem_bw_resctrl(). */ +static char mbm_assign_path[1024]; +static int mbm_assign_domain =3D -1; + static void read_mem_bw_initialize_perf_event_attr(int i) { memset(&bw_counters[i].pe, 0, @@ -452,21 +471,63 @@ static int get_mem_bw_ref(float *bw_ref) * initialize_mem_bw_resctrl: Appropriately populate "mbm_total_path" * @param: Parameters passed to resctrl_val() * @domain_id: Domain ID (cache ID; for MB, L3 cache ID) + * + * x86 resctrl reports per-RMID local bandwidth under L3_MON. MPAM exposes= only + * total (read+write) bandwidth under MB_MON, indexed by the NUMA-node-key= ed MB + * domain, and in "mbm_event" (ABMC) mode a hardware counter must be assig= ned to + * the group+domain before the file reads a value. */ void initialize_mem_bw_resctrl(const struct resctrl_val_param *param, int domain_id) { - sprintf(mbm_total_path, CON_MBM_LOCAL_BYTES_PATH, RESCTRL_PATH, - param->ctrlgrp, domain_id); + const char *grp =3D param->ctrlgrp ? param->ctrlgrp : ""; + + if (resctrl_mon_feature_exists("L3_MON", "mbm_local_bytes")) { + sprintf(mbm_total_path, CON_MBM_LOCAL_BYTES_PATH, RESCTRL_PATH, + grp, domain_id); + return; + } + + /* MPAM: total bandwidth under MB_MON. */ + sprintf(mbm_total_path, CON_MBM_TOTAL_BYTES_PATH, RESCTRL_PATH, + grp, domain_id); + + /* Assign an ABMC counter for this group+domain if in mbm_event mode. */ + snprintf(mbm_assign_path, sizeof(mbm_assign_path), MBM_MB_ASSIGN_PATH, + RESCTRL_PATH, grp); + if (access(mbm_assign_path, W_OK) =3D=3D 0) { + FILE *fp =3D fopen(mbm_assign_path, "w"); + + if (fp) { + /* The assignment parser requires a trailing newline. */ + fprintf(fp, "mbm_total_bytes:%d=3De\n", domain_id); + fclose(fp); + mbm_assign_domain =3D domain_id; + } + } else { + /* Not in counter-assignment mode (or no MB_MON); nothing to do. */ + mbm_assign_path[0] =3D '\0'; + } } =20 /* - * mem_bw_ref_cleanup - Reset the selected reference-bandwidth backend + * mem_bw_ref_cleanup - Release an assigned ABMC counter and reset backend= state * - * Safe to call when no backend was selected. + * Group removal does not reclaim assigned MPAM counters, so the test must + * unassign explicitly. Safe to call when nothing was assigned. */ void mem_bw_ref_cleanup(void) { + if (mbm_assign_domain >=3D 0 && mbm_assign_path[0]) { + FILE *fp =3D fopen(mbm_assign_path, "w"); + + if (fp) { + fprintf(fp, "mbm_total_bytes:%d=3D_\n", mbm_assign_domain); + fclose(fp); + } + } + mbm_assign_domain =3D -1; + mbm_assign_path[0] =3D '\0'; mem_bw_backend =3D NULL; } =20 diff --git a/tools/testing/selftests/resctrl/resctrlfs.c b/tools/testing/se= lftests/resctrl/resctrlfs.c index b9c1bfb6cc02..893f6748c68c 100644 --- a/tools/testing/selftests/resctrl/resctrlfs.c +++ b/tools/testing/selftests/resctrl/resctrlfs.c @@ -121,11 +121,40 @@ static int get_resource_cache_level(const char *resou= rce) return get_cache_level(resource); } =20 +/* + * cpu_to_numa_node - NUMA node a logical CPU belongs to + * @cpu_no: CPU number + * + * Reads the "node" symlink in the CPU's sysfs directory. + * + * Return: NUMA node id (>=3D 0) on success, < 0 on failure. + */ +static int cpu_to_numa_node(int cpu_no) +{ + char cpu_dir[1024]; + struct dirent *ep; + int node =3D -1; + DIR *dp; + + snprintf(cpu_dir, sizeof(cpu_dir), "%s%d", PHYS_ID_PATH, cpu_no); + dp =3D opendir(cpu_dir); + if (!dp) + return -1; + while ((ep =3D readdir(dp))) { + if (!strncmp(ep->d_name, "node", 4) && isdigit(ep->d_name[4])) { + node =3D atoi(ep->d_name + 4); + break; + } + } + closedir(dp); + return node; +} + /* * get_domain_id - Get resctrl domain ID for a specified CPU * @resource: resource name * @cpu_no: CPU number - * @domain_id: domain ID (cache ID; for MB, L3 cache ID) + * @domain_id: domain ID (cache ID; for MB, L3 cache ID, or NUMA node on M= PAM) * * Return: >=3D 0 on success, < 0 on failure. */ @@ -135,6 +164,20 @@ int get_domain_id(const char *resource, int cpu_no, in= t *domain_id) int cache_num; FILE *fp; =20 + /* + * On MPAM the MB monitoring/allocation domains are keyed by NUMA node + * (surfaced via a separate MB_MON group) and need not match the L3 cache + * id used on x86, so resolve the MB domain from the CPU's NUMA node. + */ + if (!strcmp(resource, "MB") && resctrl_resource_exists("MB_MON")) { + int node =3D cpu_to_numa_node(cpu_no); + + if (node >=3D 0) { + *domain_id =3D node; + return 0; + } + } + cache_num =3D get_resource_cache_level(resource); if (cache_num < 0) return cache_num; --=20 2.43.0 From nobody Sat Jul 25 00:01:55 2026 Received: from BL0PR03CU003.outbound.protection.outlook.com (mail-eastusazon11012045.outbound.protection.outlook.com [52.101.53.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E5AC368957; Wed, 22 Jul 2026 02:13:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.53.45 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686428; cv=fail; b=XNgoMXe3MlnfKYbl37vJjd3zWjUuZ5VQHyiAS9XjPPdixfRX420VMWC19A7TAyx05EbvD0LIhc4mZYiB1EWFZQcZZB9Lu3nqy31qlQKx2c+eBGT3Fh8joYPVOYmXBiZS1Rj83piWBfb1MV8ito12+r9FStL/ZQhy7yqtil7tTd4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686428; c=relaxed/simple; bh=E2iN5bf86ahRJVmRv3fShnrf8zrBRSJ/VWMUD9rCeW0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=P0EqQBg9x3rXDCJGbSoBvQ+2qOu03iMAxHMxlsYs1FTnDgoyQpbL5j9zgT6U5+cJ3q7u8u8IRxOsJH5de52RueC3pvcI9GODAVRRCdmI7V9PrykxzMl33mxR08LkN0JXmUA9fpqTjtjgkWJ6KBB2P+MtRs1O1zdzBzsTgga89DQ= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=TDAiQHfx; arc=fail smtp.client-ip=52.101.53.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="TDAiQHfx" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wLWA4xNjEbTriq4j6nBpSg2yzzQxclJUjRYnFLYR2cym4UnzGK1RPrA4B7HMzwzAX65oLY8JwFUOV/5+SDZF1RCmUuKwSdgUkbDoNOqRvWZjV/SCZYow7omNbIb7Lhzk7oxUQWVQTrHVIiqYTzIgMTZ2akbdCj+MjjSHx/VtEGxzhP++dnR9Mp2PR2lOWjql/ieqEIqJJ23QdyvnLLF/pt8b5MmNxTofyHu1TjCjumcFg8nWUVq8/ChxgAiimSIxDYUmfFNvEm9lB8J9hipDsyUzGXh6w8ZR42oREgVx9nPmkILkfZly27TxK9lHQ+kxlSEchtCJhNb7f9I7A08hGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=KccohgbGezuecjfZNzfTsKmueulNEvE1VJVdIlhamxY=; b=W1p5nne6sLXaHfuBDeRnJIzx8lLz4GeZz68qxysc09oB+LO9XvZSWk9JeNIK2x2Pd8okMcycOs+Q0pJ2T4hOhHJlrVoF04DTCt1o9/Fh3Z0Cebh+Q3h+D/E/iQD0pLAk4bctzA4knHAOoHNvTZO6YTHiFmo/h7aRfIeqVHB/q+0uoPJCX7PPZXyfpPabI0uE/bjBPAYSYlkW+d15DxkqDDuJC4OzVV3Dv/itPMGkFoGT4SnPyuO+f5m4Vo3ZzAN5ZaIIUp6kO5b8k7ThOOQi3E/EWVSIVr6EOOwCgKHRYcJo9T9aJPRBtmdyWSGEF7ZkXSowkuTS9kbZVRjXoyMWUw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KccohgbGezuecjfZNzfTsKmueulNEvE1VJVdIlhamxY=; b=TDAiQHfxQ655SuAfOM34HTa2weOcgzOx7jlH1rwZFX6ms+WHf1DVo/dbcb7fDUPT9ZrdwbgfUaF/bbZm6wr5oWfulrv97ampCcXgTwqpic/eZoceGBwFnW/goRc+7vBlG5dY0RzsiNqUivwE5GVJP0YVXgCRGELsfY200PWSvHXrA/t/xYmOlymiwGcb4qj02Sipj7aShxMIr6Cn3QBzJlxN9zWAe0nH7NCFC8b4Gy6AQIIk/LNHiR3e1pZ/nQFQR3zwCg1veWoEBfSoVpCyhQmBeTplXq/FzI719BpdEctfYiOPeInu/RHNq9KphFkJeGdZHG1QiTRkxi3Eyr0NuA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) by SA0PR12MB7002.namprd12.prod.outlook.com (2603:10b6:806:2c0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Wed, 22 Jul 2026 02:13:41 +0000 Received: from BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8]) by BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8%5]) with mapi id 15.21.0245.009; Wed, 22 Jul 2026 02:13:40 +0000 From: Richard Cheng To: tony.luck@intel.com, reinette.chatre@intel.com, x86@kernel.org Cc: Dave.Martin@arm.com, james.morse@arm.com, babu.moger@amd.com, shuah@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kobak@nvidia.com, kaihengf@nvidia.com, fenghuay@nvidia.com, ltrager@nvidia.com, Richard Cheng Subject: [PATCH 4/5] selftests/resctrl: Gate the MBA test on features, not CPU vendor Date: Wed, 22 Jul 2026 10:13:02 +0800 Message-ID: <20260722021303.9471-5-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260722021303.9471-1-icheng@nvidia.com> References: <20260722021303.9471-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TPYP295CA0057.TWNP295.PROD.OUTLOOK.COM (2603:1096:7d0:8::8) To BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL0PR12MB2370:EE_|SA0PR12MB7002:EE_ X-MS-Office365-Filtering-Correlation-Id: fe083fea-2016-4580-13f8-08dee796d904 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|23010399003|376014|1800799024|6133799003|5023799004|56012099006|11063799006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: IwflLwxQ/sgwITDXAteGHU3vVGJU4Nr5VzA/i5F4p+hVG5t/U7kapw2vL1LpQZOrGXd5/DUMgvfjPaSYQokSOELygWWD6am/BXKIWY4MTq76dwTK0Y2yvQpivmrRwsBWp+waUoHk39AQQa92O+AUWBs7IoXo9yWx7pp48Lr+G4gk96PDgQxay4kYzGxbzRE/ms2tMFPNnaw6i4yp+3Ohzugca6Wqjtwlk+fN40P/zL2nJUkra6DggEQFcgJ1jju2I96tgLwDvk6aGh3LR6fRrpHkUqjNWxMYEz3Zhtjy9P8NeyMWfBnhnqTBGP99k2KQ7PJKn4lvDWminGWrVTyW+0AaH65qwyamBlv0Yp3G/Aoxu8cgNHznS+bS612zrLX8T/o1Kws/g2CNNozbi06+ZSRrD3exjPHFaMuja0oD2pnVwBK7mswzjdo488IDDLncIq0BenyVdVY6sHUXEy0MhEzb7dn8r3uEVxqTxB4x8ozAKFYkBnUavqUvShsB26xpjcw9EKh0MgH+my04gzSHwoZWc6hnDeMNlXAunp0L5jCbrMvjYqWMtxNmi/xOPa3eCC9KV6RVIWX6vS60kxlbza63JmvmFpeTQDN0P4UuyeeyB7k8W/8yJjYHXzss0+enpSwzG9pDWJm6JGKwqsOV6I3QN8pP/mG7sWEiwAOB42c= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL0PR12MB2370.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(23010399003)(376014)(1800799024)(6133799003)(5023799004)(56012099006)(11063799006)(10067099003)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?wcIHqjTjTHTMBW15whxm02gvYjHhzDLNxdzcoXfoDsURhgrbxYLQ4psZBg+i?= =?us-ascii?Q?8kKFBlkoo2GeAcKZYeg6ptWu9+LObhkde1ln6YHNbiOvdGEFcsC69E/EZRTQ?= =?us-ascii?Q?ffMwMqFVnKiNBLR4Y3naUtYjJoAxupVVDqBUEdrqYlWFq5vE7oQF91bhowN1?= =?us-ascii?Q?lZLM0Hhw+jSgI4+jGk4JfI16EgB1i8VedSY4x2q0IBZodkRT0bcOG3XOzMj6?= =?us-ascii?Q?O0jNHQEkVHcYU1+jMWw6spaXVpmqi/8JGE6moJT4P0tVISjdg1kMRc0AqlCT?= =?us-ascii?Q?xcpknMBAaHqQyRRzbOP0kWlqfnf4yVNp1BAsrqQuR7od8ZE6Nw4l/DStbO98?= =?us-ascii?Q?na+4VKT4gq1yaqyqlI9b1ult737R643iVdiSg80jeETH3kVNDJbfQfyn83Re?= =?us-ascii?Q?Wp/LktaHQkSSwq+JSNxhO+HvanL74wRAvj/QUvtnTD7ad8G6LIESjKlqL1xd?= =?us-ascii?Q?MG9B4qTFJqHSsvZswfFKrLgPL5IXV3P6UrLEyAufuBWa1h2uwEGsE3pVESU+?= =?us-ascii?Q?bYav4U3Q5C1Ww5epAF04wEudzoc5km8mHLC0V3nOM26N0stbIKUNLdaZhZj3?= =?us-ascii?Q?9UBTw5IhcIDhYWNoRauyWVBpsiIZ7pHdS73W4btDAMtQPNTZIkXX4Jo3SckH?= =?us-ascii?Q?Km7E/7KFRhE/IkQVDRKzRLMJRAJySt+ur+UYIx0RhkxjvgzEgv/hmfkEgacB?= =?us-ascii?Q?OG1vAA9Hgf+rweFfiYOaDQrblmFOrnsiLw2Dr1Uc/KY8JVkvqH45434JAlsw?= =?us-ascii?Q?NCkOjsk2p5upikz1jvGiD11ZUhG9DOahwYZW+LhPzEv23QeLNJ71N77dizuB?= =?us-ascii?Q?Bo35SSIXqyuV+aEHKjhi7mf09BqZjk9oOG8Xr/GGOMvWwl0vVhZKrY8uKkVa?= =?us-ascii?Q?KJwVIVN368wG6B6FedWc6z3Pt4Nc8qFeWfD3KCANG5a61huNexOp0p1099lt?= =?us-ascii?Q?ytNAmBpTIhBTQqL06LPiFNe21zIm9pfaWgQnNfm5TokhVmUZk9DEgy1RQ+TG?= =?us-ascii?Q?EwNG3bOA1AWsoN5P8azaHY+Trh22qte8RjLZrj151lBhuE5JjCXzUyK5EnZx?= =?us-ascii?Q?/Rd+TFFvZ9sSaCbyQJ4zu15Sdbz6Z9z7HU56Md273KEBeoDG9YpL+VPuDuiq?= =?us-ascii?Q?7bfK2wu2kzvCgvLXc5ardlaXk+bpHcWniZgqPueApB/p8/iUmjJOR5yXZQwu?= =?us-ascii?Q?Yt7dhZql6X2E07Va8Z4fFNmQPNVoPartTkf4B0Ib8HB8oC98VlgjRCky8yXs?= =?us-ascii?Q?6lraWLbqu2uvw19nR4sTMgLJifTuaYxd8pTWLvM0wk0YDQLuG6YgDrkJSx1D?= =?us-ascii?Q?kpmbj9oOaVchLc5PXy/d9Ct1PkwI0k+8m5LymKSVGttW9ptWiAWvTzHcRuRh?= =?us-ascii?Q?IUebOlTYgpzZhC8nJL6oCL8nWwzMlEelYGulCzVhpIAHNd0hXM+OXboKsDJj?= =?us-ascii?Q?jPCA8Icx1fjPXCAp1NmnKu/f2r3siI9GxZU7BkZG3MIJhR649DorZqt5UfHV?= =?us-ascii?Q?MWdxRLyTLaZFSR1R2XuSqKP9FGnoOCN39GNc3KHUGYr1ET84iIQe1FxCXKGL?= =?us-ascii?Q?IXnxOnbc48wi3WwxRTMeowNYJ7HfaP+hqbl3CixKbdEOgP3/QYg9NuxIPQjj?= =?us-ascii?Q?iEBixuQESEMTFtCC1G969uchi2OJcroUnA782JAaM6x0DiBuMxopPWFMOXxB?= =?us-ascii?Q?HijqPdMu1wKnepASTM38b3ZKyHwJkGzKxdd4I4OdlraAXNqk/ZtDxs0j/uV9?= =?us-ascii?Q?fhGKdYl6oQ=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: fe083fea-2016-4580-13f8-08dee796d904 X-MS-Exchange-CrossTenant-AuthSource: BL0PR12MB2370.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jul 2026 02:13:40.8711 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2XKqHIap/clbRVB2opIoGo47onQMCSDASKEeAwJ6bVrQrpvsVXKo8tkV/4cj0TXGLAia0WzTV7bO3sAnN3DCyA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB7002 Content-Type: text/plain; charset="utf-8" The MBA test is skipped on every CPU that does not report "GenuineIntel", although everything the test needs is discoverable at runtime: an MB resource with a bandwidth monitor in resctrl, and a reference PMU backend to validate against. The vendor gate also can never match on architectures whose /proc/cpuinfo has no vendor_id line at all, such as arm64. Drop .vendor_specific from the MBA test and rely on the feature check. On systems where any required piece is missing - including architectures for which no reference bandwidth backend exists yet - the test reports SKIP exactly as it did under the vendor gate. Signed-off-by: Richard Cheng --- tools/testing/selftests/resctrl/mba_test.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/sel= ftests/resctrl/mba_test.c index 6c85107c32ee..22a887a1b4f8 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -208,6 +208,12 @@ static int mba_run_test(const struct resctrl_test *tes= t, const struct user_param return ret; } =20 +/* + * The MBA test runs wherever resctrl exposes an MB resource, a memory-ban= dwidth + * monitor (x86 local bytes under L3_MON or MPAM total bytes under MB_MON)= , and + * an independent reference-bandwidth PMU exists to + * validate against. It is not gated on CPU vendor. + */ static bool mba_feature_check(const struct resctrl_test *test) { return test_resource_feature_check(test) && @@ -219,7 +225,6 @@ static bool mba_feature_check(const struct resctrl_test= *test) struct resctrl_test mba_test =3D { .name =3D "MBA", .resource =3D "MB", - .vendor_specific =3D ARCH_INTEL, .feature_check =3D mba_feature_check, .run_test =3D mba_run_test, .cleanup =3D mba_test_cleanup, --=20 2.43.0 From nobody Sat Jul 25 00:01:55 2026 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013033.outbound.protection.outlook.com [40.93.196.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F26D368957; Wed, 22 Jul 2026 02:13:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.33 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686434; cv=fail; b=LDmvIIXyOUx0+1OrtOHevWpErFVLx5R2Zpxomol9m27ueNdeEwepZ2GD4ADxxDPY3Qx0EkO00hdsIJqsVCd2cDVwBRspA5cAvNw5rKFg3zObXsoGIi95l5fCvx9ehCt0ipt/+pYWcgMrDVROklNdOhj3pTlJ1kJYG6fkudT/+sA= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784686434; c=relaxed/simple; bh=SjD1RVHa/EAeeMWIYrMaZ8oN2bZu+BWC8QCRC6J69XQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=Dtds25DT2mT75Okqyv7dpjN6o1pQBjRjHPU54wIzVbzhj24ooWNhQH+55ow3tis/w4oNp/EsVDCvCrAtJH0kH87PZx/LxqSGgOUFbjn3MHlu5lzy2eAZpQJtVUE/SF6qY4LChdNpBxgawmkPW5L8WnjWSoWDeGrQGQmF9UTdzts= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=KKoQwVS4; arc=fail smtp.client-ip=40.93.196.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="KKoQwVS4" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=e1UiXSGCXuX8W6kM3P/qMTYSnQAwS5WRpAS0NHz6Zc8mNafSFRI6lyleO05SEbCQPVpT9I3OFT5YOZLCK/AEO2r6J5mswE6Mjh04ItdA1PtonlxPDwci1KXNU2gTSbNnjYHibWQNW1SgyutZ50W0mIEHOkyRy+eVVZZs7rrYG8Que8PYGg3ZDhiuMfTrNyt1veLnsLou8FiFC+Tjsgkyc25gt7X9BZtkmVWbOZgZtSNS9ABvRZ2o9cPaOSjdqCtad6Ut3a2aktcVSi9zHRA4X1r+3DNR4qUZi12X3sAOUMbQJqQCHKorqqAAvzB+bzQ8u5MYFewgQlSQyKavLPhVjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=B6iqZfgPN+yczwKqNuF43oyP16bdtdJ7DkbPQt37Kxg=; b=LcrGFVfHIOG7mBE3gQxyyO5toBCVT5JytlEsrzG5kJi0/616OS0BTlI0ub6PuUTtqPOY7tG43UzjXDTXh3Wq4kgcB9UqR9QxvkN4F+QT3mnnLaFYpUJBnPovh9//yB84GwygqVNTMelpS0/5Y6tBjrePPiTB9jMuBriEJ8GKKawO+dXgiYH5AS1/EHAQtCO/3++W2LaDVQZd/dAOGihH8cJs55BoFOZj8kWYKME3buUqrwb6F6t+dVf0/EB/acK9E27B2TqJcbZ01ucC76+k03JHPb7fqQ7VVTq+nY3J6EwUzL3cMrM+PpvuJ0qBMD0pvTkWC87xr3hbAuv2PoKK1g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=B6iqZfgPN+yczwKqNuF43oyP16bdtdJ7DkbPQt37Kxg=; b=KKoQwVS4jK8/aE5XJb90zpQFD6JN5YMrOGPN5pvsNncOmQm4CN5waZTTZ9CE+Yze+7lYxkK1D9j3SruIe2TSQ0mq5XHJZdRJyB1nEKzcnScQD3fti/9xvENNvc9XcTyyK8hCmgerJ036lQf+2lOGN2XQecEfoLzYV4mIPOf9HFFTuMfpEOFGP2zBAqcl+b6ja+PfhDhBMGwFbyhls7kuu8FLDrbiJF6CHXGp8ogWAxYzyMVjtiPbXhTWivl6j8RA6ds3VfGgEps7e3a5PaHH7I2bhx+3T3Lu95jYyIBhS/u4X8yZUx5AxqGNENiasUnOlVE+ntBEPEqmCZQsJ6zbqQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) by SA0PR12MB7002.namprd12.prod.outlook.com (2603:10b6:806:2c0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.10; Wed, 22 Jul 2026 02:13:48 +0000 Received: from BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8]) by BL0PR12MB2370.namprd12.prod.outlook.com ([fe80::86cf:c3ec:2cf5:74c8%5]) with mapi id 15.21.0245.009; Wed, 22 Jul 2026 02:13:48 +0000 From: Richard Cheng To: tony.luck@intel.com, reinette.chatre@intel.com, x86@kernel.org Cc: Dave.Martin@arm.com, james.morse@arm.com, babu.moger@amd.com, shuah@kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, newtonl@nvidia.com, kristinc@nvidia.com, kobak@nvidia.com, kaihengf@nvidia.com, fenghuay@nvidia.com, ltrager@nvidia.com, Richard Cheng Subject: [PATCH 5/5] selftests/resctrl: Add NVIDIA SCF reference bandwidth backend Date: Wed, 22 Jul 2026 10:13:03 +0800 Message-ID: <20260722021303.9471-6-icheng@nvidia.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260722021303.9471-1-icheng@nvidia.com> References: <20260722021303.9471-1-icheng@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: TPYP295CA0048.TWNP295.PROD.OUTLOOK.COM (2603:1096:7d0:8::14) To BL0PR12MB2370.namprd12.prod.outlook.com (2603:10b6:207:47::27) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL0PR12MB2370:EE_|SA0PR12MB7002:EE_ X-MS-Office365-Filtering-Correlation-Id: abc50e96-c23f-45a8-31f5-08dee796ddac X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|23010399003|376014|1800799024|6133799003|56012099006|11063799006|10067099003|3023799007|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: qQx2NmsvHTcoJ4aC7Gu84ZqGy3KRkfcwq4GR+xijdO1n7z0HgM9e0I0/9QbUOU+oWyPCz/IwijjYPsOl+V1owqcz24+zZK+xyFw//RLi9KPCH22bb+L5GtazgXOpjlwC4/1K/1a7RiWz/0BhKGERFG5lvZwxCTm89n391TfZlV28Q8qJ2VTajLZ2WU9hdv+IhKVf4HOR7WWUc44ktHMHRgZIWu/Wnec1pAzlKwsgIMPlR9AO6ng6ledHqx0v5G0J6DdGu2Up8iLul3875HZ/NWtR+nyfB7QJzgARxHSRgTecC+QUBRS3loTdnREbxEDHlvE2GvYXFL4/Kv5grCzGLRAM93+r3Cp+5PAon462Jq6Hi1Ozn+w+zgc4N9qxh9iLrxAjRm/SNMTDLRg3LZU2GOeNsEAPUT7JE+je1F1XTR4reROeSisWfVgvH6vsgDaKOI8YYoULzNR0DFyvssj9JcQSTQqe7yHXHZKfT2DdwbchUIxQfR516jDWTZ3sqbzPnLLAJ32pPRa279uy83nW22QiYbs2bizTVy8MA8QmCeOAHSkruVAUq4Et8DtQi3YoIXELUIH5+EbSfpyr0szbY2++A01b9T08Z89Y1SWdjaa59+Yad+kholxln9a+EUCd5V4QXj/Qpg5r1ZsEEOizzotZouAp6mfGJMTrBkXfFzM= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BL0PR12MB2370.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(23010399003)(376014)(1800799024)(6133799003)(56012099006)(11063799006)(10067099003)(3023799007)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?gLv4qOMzWtZDKld9qBi3skrwl1RGKuNupeEHpZ+Wunbhmg6rxsvPHzC38VfJ?= =?us-ascii?Q?GO5rDz0vbyuecBr8hiPy2svabN6KdfubembiCYGR/z+35FWtzFKUbWFlSREI?= =?us-ascii?Q?5x9EfheheYLBMRIE63ecyRE5S7iyOjaUOWEQon8CedoFgVtNLsfpwyXSmlGr?= =?us-ascii?Q?gDPHJJ7t68yhJkYLAyO0H/Y8PIgyIds05MDgaxrRYYe1Wt8j4xT+e8Qo6If/?= =?us-ascii?Q?LaqAx7n7ePBHdzztesbyNRq1cJu+SzQ5AnC/J1p2p454+eNHsb3oRQpj6Kws?= =?us-ascii?Q?A8y5X9x6I/sndrBxh/3YCf+HQcptCsUcduvs3dTFAFQaRnKkpqqhFX8FNdFf?= =?us-ascii?Q?0OW6iCrhLmINtVjikVXRdzCL6W83NXJQlqOuPoQO5l8Yov1PI9qcugLoDf21?= =?us-ascii?Q?S7Nzj3K48F8lE6k61zHL9ax5g/3X+D9HJcO8bgNcr3B8sTKdzcUwjzcksOxd?= =?us-ascii?Q?jZ8cunI57/cUMmQ3au7oDWXXs5NzdPzA4yJQW7Oxh2ewpgiNdq7A5P2QI+ai?= =?us-ascii?Q?KFdbuXKcBkBcBya0his2YfPM5e/OZs29Ps9AuS2ehDC4K3bVNQM8cHHNqOId?= =?us-ascii?Q?bvfFvAAgp6BhztO5k0KgakHhAzN6y5D5KPFnkOew3VScFG23THC6yVzMgnNl?= =?us-ascii?Q?HY3oaszHOihc+pkJD5srwqXNJtycFgwde0+D1KueWFmNBGsDedt7JKglrSX+?= =?us-ascii?Q?qn4SFVxD3jWt3Z0Zn/bSSLjriPAb+v50I+2+f/3UEoxgsQU7+ClX0bDIuwVW?= =?us-ascii?Q?eY1Au3mMag9l/AVZURuGevtePj4U5hzDGSYnUApTqfxPvgKBXc6wZuBw8INe?= =?us-ascii?Q?mzDi8k5OcRsFJt3G3/iAO4a8+dsqyJtQP661lvZdOpx66SAhAOs/TT9TWelS?= =?us-ascii?Q?1ZMQsM2agBzpS/Wr76nZs4K6Md5hBhyXFA+V60bH0xSUkdvurxOHOPFVhO30?= =?us-ascii?Q?3sXx5et3vIeP9mw6G9kV9xbBWriHyE96LnvQaSgsbyvcwKSO6fMz+UcR7o0F?= =?us-ascii?Q?Mm0RWiFyVqWJ8qK6febsf9UwIXDI0vdgWILgQzI5bZbPc96KKH8owuZhCktH?= =?us-ascii?Q?zxYlSDYd+RiIsjoL3FuRg0+c9EfdAV7gCerAyNEgGxqcIjXIiVYrvUtCrXkQ?= =?us-ascii?Q?VkbxRP23mb0GGPWo4eU3qDeHtDS3v7U097izgvjc29Zb/jgHCw2jRK8/Nfb8?= =?us-ascii?Q?iZxJAKyg2UumYN7TAG3cyoA5iUW9HrAAuiBSypDvMHBAF9SXmgjVkjk1tNWl?= =?us-ascii?Q?UxVDFgjPhpXrXme9Tw1m0FrVauV11kRnKEXwEm8IWeoE6GxODhMJ6f59cFDD?= =?us-ascii?Q?Z4o03pv7mvAwtgu9WjBxxlMXij6TeS0BnXtyfjXikBO0QFkFeY7tJ4IIfUQ9?= =?us-ascii?Q?8twEAfiq1QCW24era9CXfKHC9ebYB6r7AC01hQrqfjEGYHsDt6frJfJgR2TO?= =?us-ascii?Q?/WUBQfNWEeCvumOVrT94HL60/0UqyD8USgch+mg9O5zy3J0ztu24l/zIFGps?= =?us-ascii?Q?6tB6offKrgNWM24t/z6XusDtxa9IGirGjy54RGJnCEs8j2rXUgxLTEZDiqHf?= =?us-ascii?Q?/tbCHdQ3aFrt0XNxEef2x3sXKDx1EgjQjtk7QdVgq/7Lrd5q3zxNjuurNPdi?= =?us-ascii?Q?bSAz42PrgtnLk3BpFJ49gl8uk0kw0MLhBW2TrRgNfc4NXYYxu9Ryy7XhhMpA?= =?us-ascii?Q?6QDoXDcJmMh+h/m24jktMh5Ppg10cN44AKz3irvudU1OSeviNtLtpTF2/tuF?= =?us-ascii?Q?qo43/RjcZw=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: abc50e96-c23f-45a8-31f5-08dee796ddac X-MS-Exchange-CrossTenant-AuthSource: BL0PR12MB2370.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Jul 2026 02:13:48.6069 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: mItfpbXn/4eMBY0kSTci1tlECP9z55rDu8JhyIGC6K4826lG46tCS6b2HRSn0/gb3sg6ocLnb7opcOymzQbrYg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB7002 Content-Type: text/plain; charset="utf-8" NVIDIA Grace/Vera systems expose the SoC coherency fabric (SCF) uncore PMU, which counts per-socket DRAM traffic and can serve as the independent reference for the MBA test, in the same role the iMC plays on x86. Together with the MPAM MB/MB_MON support this makes the MBA test runnable on arm64. Implementation notes, all verified on a two-socket Vera system: - The arm_cspmu driver registers these PMUs under the generic nvidia_uncore_pmu_ name, so instances are identified by the PMIIDR value in the sysfs "identifier" file (product id 0x2cf =3D SCF) rather than by device name. This also keeps working should a future kernel register the PMU under a dedicated name. - The driver registers no named events on current silicon, and the documented byte counters (cmem_rd_data, gmem_*) read zero under load, so the backend programs raw events: 0xF1 (LLC refill, i.e. reads) and 0xF3 (LLC writeback, i.e. writes). Each event counts 64-byte cache lines, the same scale as iMC CAS counts, and refill+writeback matches the read+write semantics of MPAM's mbm_total_bytes. - The SCF PMU is per-socket; the backend selects the instance(s) whose cpumask belongs to the benchmark CPU's package. - The events are opened system-wide (pid =3D=3D -1), where inherit must be 0 or perf_event_open() fails on this PMU. Validated against the MPAM MB resource: SCF and mbm_total_bytes agree within 3-4% across all MBA schemata levels (10%..100%), against the 8% test threshold. Signed-off-by: Richard Cheng --- tools/testing/selftests/resctrl/mba_test.c | 2 +- tools/testing/selftests/resctrl/resctrl_val.c | 164 +++++++++++++++++- 2 files changed, 162 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/sel= ftests/resctrl/mba_test.c index 22a887a1b4f8..40352df5303c 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c @@ -211,7 +211,7 @@ static int mba_run_test(const struct resctrl_test *test= , const struct user_param /* * The MBA test runs wherever resctrl exposes an MB resource, a memory-ban= dwidth * monitor (x86 local bytes under L3_MON or MPAM total bytes under MB_MON)= , and - * an independent reference-bandwidth PMU exists to + * an independent reference-bandwidth PMU (Intel iMC or NVIDIA SCF) exists= to * validate against. It is not gated on CPU vendor. */ static bool mba_feature_check(const struct resctrl_test *test) diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/= selftests/resctrl/resctrl_val.c index 0c3079d31340..e7b6eb255e3b 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c @@ -17,6 +17,23 @@ #define MAX_BW_COUNTERS 20 #define MAX_TOKENS 5 =20 +/* + * NVIDIA SoC uncore/SCF (System Coherency Fabric) PMU: the ARM64 analog o= f the + * Intel iMC reference counters used to cross-check resctrl MBM. On Grace/= Vera + * the fabric PMU registers generically as "nvidia_uncore_pmu_"; the SCF + * instances (one per socket) are identified by the PMIIDR product-id field + * (0x2cf), independent of the device name. The driver does not register n= amed + * events on this silicon, so the read (LLC refill) and write (LLC writeba= ck) + * bandwidth events are encoded raw. Each event counts 64-byte cacheline + * transfers, i.e. the same SCALE as Intel CAS counts. Summing read+write + * matches resctrl's MBM total bytes (which includes reads and writes). + */ +#define UNCORE_NV_SCF "nvidia_uncore_pmu" +#define NV_SCF_PRODID 0x2cf +#define NV_SCF_EVENT_READ 0xF1 /* scf_cache_refill */ +#define NV_SCF_EVENT_WRITE 0xF3 /* scf_cache_wb */ +#define CPU_PKG_ID_PATH "/sys/devices/system/cpu/cpu%d/topology/physical_= package_id" + #define CON_MBM_LOCAL_BYTES_PATH \ "%s/%s/mon_data/mon_L3_%02d/mbm_local_bytes" =20 @@ -258,6 +275,55 @@ static int num_of_imcs(void) return count; } =20 +/* Read an unsigned value from a PMU device sysfs attribute. */ +static int read_pmu_value(const char *pmu, const char *attr, int base, + unsigned long *val) +{ + char path[600], buf[64]; + FILE *fp; + + snprintf(path, sizeof(path), "%s/%s/%s", DYN_PMU_PATH, pmu, attr); + fp =3D fopen(path, "r"); + if (!fp) + return -1; + if (!fgets(buf, sizeof(buf), fp)) { + fclose(fp); + return -1; + } + fclose(fp); + *val =3D strtoul(buf, NULL, base); + return 0; +} + +/* physical_package_id (socket) of a logical CPU, < 0 on failure. */ +static int cpu_package_id(int cpu) +{ + char path[128]; + int pkg =3D -1; + FILE *fp; + + snprintf(path, sizeof(path), CPU_PKG_ID_PATH, cpu); + fp =3D fopen(path, "r"); + if (!fp) + return -1; + if (fscanf(fp, "%d", &pkg) !=3D 1) + pkg =3D -1; + fclose(fp); + return pkg; +} + +/* True if @pmu is an NVIDIA SCF instance (PMIIDR product id =3D=3D NV_SCF= _PRODID). */ +static bool is_nvidia_scf_pmu(const char *pmu) +{ + unsigned long id; + + if (strncmp(pmu, UNCORE_NV_SCF, sizeof(UNCORE_NV_SCF) - 1)) + return false; + if (read_pmu_value(pmu, "identifier", 16, &id)) + return false; + return ((id >> 20) & 0xfff) =3D=3D NV_SCF_PRODID; +} + /* True if any x86 uncore iMC PMU ("uncore_imc_") is present. */ static bool intel_imc_present(void) { @@ -283,6 +349,93 @@ static bool intel_imc_present(void) return found; } =20 +/* True if any NVIDIA SCF PMU instance is present. */ +static bool nvidia_scf_present(void) +{ + struct dirent *ep; + bool found =3D false; + DIR *dp; + + dp =3D opendir(DYN_PMU_PATH); + if (!dp) + return false; + while ((ep =3D readdir(dp))) { + if (is_nvidia_scf_pmu(ep->d_name)) { + found =3D true; + break; + } + } + closedir(dp); + return found; +} + +/* + * nvidia_scf_setup_counters - Configure SCF read+write bandwidth counters + * @bench_cpu: CPU the benchmark is bound to + * + * The SCF PMU is per-socket; pick the instance(s) on the benchmark's sock= et and + * configure two raw counters each (LLC refill =3D reads, LLC writeback = =3D writes). + * Per-socket so traffic from the throttled MB domain is attributed correc= tly. + * + * Return: 0 on success, < 0 on failure. + */ +static int nvidia_scf_setup_counters(int bench_cpu) +{ + static const __u64 events[] =3D { NV_SCF_EVENT_READ, NV_SCF_EVENT_WRITE }; + int bench_pkg =3D cpu_package_id(bench_cpu); + struct dirent *ep; + int n =3D 0; + DIR *dp; + + if (bench_pkg < 0) { + ksft_print_msg("Could not determine socket of CPU %d\n", bench_cpu); + return -1; + } + + dp =3D opendir(DYN_PMU_PATH); + if (!dp) { + ksft_perror("Unable to open PMU directory"); + return -1; + } + + while ((ep =3D readdir(dp))) { + unsigned long type, pmu_cpu; + size_t e; + + if (!is_nvidia_scf_pmu(ep->d_name)) + continue; + /* cpumask holds the representative CPU of this PMU instance. */ + if (read_pmu_value(ep->d_name, "cpumask", 10, &pmu_cpu)) + continue; + if (cpu_package_id((int)pmu_cpu) !=3D bench_pkg) + continue; + if (read_pmu_value(ep->d_name, "type", 10, &type)) + continue; + + for (e =3D 0; e < ARRAY_SIZE(events) && n < MAX_BW_COUNTERS; e++) { + memset(&bw_counters[n], 0, + sizeof(bw_counters[n])); + bw_counters[n].type =3D (__u32)type; + bw_counters[n].event =3D events[e]; + bw_counters[n].umask =3D 0; + bw_counters[n].cpu =3D (int)pmu_cpu; + read_mem_bw_initialize_perf_event_attr(n); + /* System-wide (pid =3D=3D -1) CPU event: inherit is invalid. */ + bw_counters[n].pe.inherit =3D 0; + n++; + } + } + closedir(dp); + + if (n =3D=3D 0) { + ksft_print_msg("No NVIDIA SCF PMU found for socket %d\n", bench_pkg); + return -1; + } + + nr_bw_counters =3D n; + return 0; +} + /* * imc_setup_counters - Configure iMC CAS-count-read counters * @bench_cpu: CPU the benchmark is bound to @@ -315,6 +468,11 @@ static const struct mem_bw_backend mem_bw_backends[] = =3D { .detect =3D intel_imc_present, .setup_counters =3D imc_setup_counters, }, + { + .name =3D "NVIDIA SCF", + .detect =3D nvidia_scf_present, + .setup_counters =3D nvidia_scf_setup_counters, + }, }; =20 /* @@ -430,7 +588,7 @@ static void do_mem_bw_test(void) * get_mem_bw_ref - Memory bandwidth as reported by the reference PMU coun= ters * * Sum all configured reference counters, scaled to MiB: read CAS counts on - * the x86 iMC. + * the x86 iMC, LLC refill + writeback counts on the NVIDIA SCF. * * Return: =3D 0 on success. < 0 on failure. */ @@ -661,8 +819,8 @@ static int print_results_bw(char *filename, pid_t bm_pi= d, float bw_ref, * @bm_pid: PID that runs the benchmark * * Measure memory bandwidth from resctrl and from the independent reference - * PMU. Compare the two values to validate resctrl value. It takes 1 sec to - * measure the data. + * PMU (iMC on x86, SCF on NVIDIA ARM64). Compare the two values to valida= te + * resctrl value. It takes 1 sec to measure the data. * resctrl does not distinguish between read and write operations so * its data includes all memory operations. */ --=20 2.43.0