From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.20]) (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 27324377566 for ; Fri, 10 Jul 2026 23:42:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=198.175.65.20 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783726967; cv=fail; b=sUQGYAEWshbyHU2q1Eh8CwDNp+FkHH59pfVkeR5377hx+YfbZDeiMDiyjZmDGP28/k8OXo4HF8Z8zOU2KWMh3QEzx6qdUlA/S5pkuGOmt4lzX/3kyF7Bp8fH26h5rJF6TUfZ6QoWkh/lg2s+9kqis27NBCKGrYBTgfuJmfzjVfo= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783726967; c=relaxed/simple; bh=RlYBqvXr1LPcqW5xpXULWgkr5AENjELMm+Nr+niKtZA=; h=Message-ID:Date:Subject:To:CC:References:From:In-Reply-To: Content-Type:MIME-Version; b=HbWNuq1QnFDmaov2bKneFaf/Bq1E2mv9+RfEAEzU2ySFZde+eipPvNpvYupYUZ+qTb3S5LfGMSGOsROI0Ql6GrdkSBGYBKqjxa4BUOcWFO7pb6KWnspO6OttF3EjUHSbONxfkWd/ezrcxJIJqsKPKL7hekbbFgy0Gj84GylRojI= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=WE0HUYPm; arc=fail smtp.client-ip=198.175.65.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="WE0HUYPm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1783726966; x=1815262966; h=message-id:date:subject:to:cc:references:from: in-reply-to:content-transfer-encoding:mime-version; bh=RlYBqvXr1LPcqW5xpXULWgkr5AENjELMm+Nr+niKtZA=; b=WE0HUYPmUS+ht0TbcWz2H5BWS7JpPWrR7Vj1zlgpGyJRNxIUBJQrSZzT 6jUueoBrY2ffxOnXK0p9kkjZhhJ0qy2il67ezqqP11b+XfnhqcMoSCQnJ n0e6qdlKIYwOIgiVURM3RYa4qppb56xag71owmlDcX1moeNv32xj0YE44 Ei15Agf0xLEi5WPuvCsZUagC72zt+qSs8uTjhh6P51RP2qix7KF5+GUNl 3nFAEXMIPR0AhmuGHzVE0njqaK8bTRp5vA7T7VQSRkaogDKd+wQo4cUkv W/l6IRxNFQb4hkPB9FQspdl1+pv7nUp9mC5ij9HDtcuyT2LwF/TK1mXk2 A==; X-CSE-ConnectionGUID: 800kmkkrRuWa1EPMCgK7CQ== X-CSE-MsgGUID: BSCc8acpRmygPgkO2H/lKw== X-IronPort-AV: E=McAfee;i="6800,10657,11841"; a="84208781" X-IronPort-AV: E=Sophos;i="6.25,154,1779174000"; d="scan'208";a="84208781" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by orvoesa112.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2026 16:42:45 -0700 X-CSE-ConnectionGUID: 5KioDtrRRliNm0ycPo+K7w== X-CSE-MsgGUID: /hhvWP4PR+abPtoO6522eA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,154,1779174000"; d="scan'208";a="293203927" Received: from fmsmsx901.amr.corp.intel.com ([10.18.126.90]) by orviesa001.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2026 16:42:44 -0700 Received: from FMSMSX901.amr.corp.intel.com (10.18.126.90) by fmsmsx901.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.43; Fri, 10 Jul 2026 16:42:43 -0700 Received: from fmsedg903.ED.cps.intel.com (10.1.192.145) by FMSMSX901.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.43 via Frontend Transport; Fri, 10 Jul 2026 16:42:43 -0700 Received: from SN4PR2101CU001.outbound.protection.outlook.com (40.93.195.22) by edgegateway.intel.com (192.55.55.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.43; Fri, 10 Jul 2026 16:42:42 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=EbzYqgUIjb57ngJAMaZ+QO/pN7cKFR1ZIG/41xAO7p8ltiVs5kwUe56LLh3dkX0ZA/40eJpEQtBa7duKyMlkMyNQmikSSOxeZL8EYCvxEf9RJusE19ok1ljppfwhslT7NlpIzeLRvumv6oqcKQo7mWqzURGpBUejDXC9/d4iQjErHvtwN28l2y8F+jJKf18rSn8rS7cL4FOgsOHei48xN23qpQtPxNnd7PzONzznT/1oyXd2HhQ+gUK8CwnSR2lUCGCMuEcaiIyuZeK932uhwXNneitMsj/6At9Y/X+IpfnfbwIrC4pR6U0XVxrPIQPL0+J6BivbA74hC2GA/mtd8Q== 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=bf+jTUEvm4zc+XLDzRue86IxeUwiqS/sfyO8ujBbgPw=; b=uNRglz8luqECFOoajgAS1O/Go+q/ePxl5dV3SuqgYY1khh6iPVS+9Uf3ADtyjNAf2RIbD2ufKo1mBRp0YQ9ZVb/HEoWHOGWAlpkzbe7UUWbJafLn0j5PXLqC7ctAtKsIA/u5xlNHq8IuVxZoBj3XWPqrz0HYr9T61fJt3pu5oIvAgSS8VaZTAqLtFcAs6D7UX7iwkQL6JrDQqaidPVq3RPcWA/oeJdHiGZJsnMXDF5PIzZks2jrfLhdmJT8I+yuFr90YGZUhAMNnx46l7a1qJVTNQYcpbz7pQB1ebo8CSRYc+KKBn74GJAjZUQxafLnui5mClyaEPSpkzTwxYDNCTw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from SJ2PR11MB8370.namprd11.prod.outlook.com (2603:10b6:a03:540::20) by PH3PPFBA2AA2BA3.namprd11.prod.outlook.com (2603:10b6:518:1::d46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.181.17; Fri, 10 Jul 2026 23:42:39 +0000 Received: from SJ2PR11MB8370.namprd11.prod.outlook.com ([fe80::b6cf:ce77:3cdf:7cc]) by SJ2PR11MB8370.namprd11.prod.outlook.com ([fe80::b6cf:ce77:3cdf:7cc%5]) with mapi id 15.21.0181.014; Fri, 10 Jul 2026 23:42:39 +0000 Message-ID: <83182a45-e4e5-47df-88cd-79c0f6beaed1@intel.com> Date: Fri, 10 Jul 2026 16:42:37 -0700 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5 03/10] x86/resctrl: Parse ACPI ERDT table and save CACD cpumask for RMDD domains To: Chen Yu , CC: , , , , , , , , , , , Hongyu Ning References: <04bf985905dfaa759b919a11fd5d806b179fc0bb.1782866200.git.yu.c.chen@intel.com> From: Reinette Chatre Content-Language: en-US In-Reply-To: <04bf985905dfaa759b919a11fd5d806b179fc0bb.1782866200.git.yu.c.chen@intel.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-ClientProxiedBy: MW4PR03CA0293.namprd03.prod.outlook.com (2603:10b6:303:b5::28) To SJ2PR11MB8370.namprd11.prod.outlook.com (2603:10b6:a03:540::20) 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: SJ2PR11MB8370:EE_|PH3PPFBA2AA2BA3:EE_ X-MS-Office365-Filtering-Correlation-Id: 6a55aae5-3c8c-47ba-b110-08dededced93 X-LD-Processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|23010399003|366016|1800799024|56012099006|4143699003|11063799006|18002099003|22082099003|3023799007; X-Microsoft-Antispam-Message-Info: d+CP+7JIxHml7puA55sM49p1UjK1Mc3LS1gY9DMb+eAuspxiaKG8L/ft+Z/KyGaWg8Mk2eX+YqmfVFZkAAnuJHRUkcd09ilnfXZzzD5gFTHcJVRAjPCRKsbM2/eL2XIRui9kghJCUCllf0GLQVOI1qIk31mk40zBOYFIDrcus5mBtO0BUDprCUz8qvv3kTIMnofZHxpj/n5NpHvP9naP+RNExhk+IDq5PZGN3t3J89W9Pc0MVGz7+IOjnWSKZiZBwnX3kQcv5F86W52Jb26WVVcPscZOHomF1VYl8Hv8wLIZo6i/ibi0g0FO7baFtZuDfoWxEiHNSO5mYDfbzJbxCaFYkxA8hntX0k7gkijBqBf5Wv+3U0/u8e34X6tfE6hYdPiIsW8FqjTF3NNosRw9YlOIQhh9M/YHu31Rg6/21aj8YBnBJTu31pe64ZYocm47irSQophzPRQhBEnp5piWInlpDX9GTg/at1zdOQyGJnmal/FabaEfN0MXaBVE7uuyYomFxPSnzoLSDw0zodC4hAOTEU8mswuPp28wV9uuMahxwpyxYv16tFys60Sgl7aa1C1PVNnG5i+bTbQDwaaGNW6UaEtGAp+hLhTM2pGtiY7kMuzZxWpFdxEGeJGnGmtgcWiLUC/9pAunBcwh/GJBGtUBPi6gGK1imEtWLpi4ZXg= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ2PR11MB8370.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(7416014)(376014)(23010399003)(366016)(1800799024)(56012099006)(4143699003)(11063799006)(18002099003)(22082099003)(3023799007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?c3VNaTk1ZjViUDdTNW1zTERXaCtVYVBFYTVibm0vV2t5MzJ5Skx6dnk1bDJQ?= =?utf-8?B?VGpEY0Z3TVpHS0dZSnE1RXlPbkUvSkNHNE00cmZ2R2xJbDF3YVREV0JKVHNY?= =?utf-8?B?Qlk1cXJaWXY0ZG92aDFMbVlUeWRtamNZWjNMaGUzQSsySmp3ZFQrZGlwbFhJ?= =?utf-8?B?YnEyVGJwOXZlZ04zZTduNWRQVkdZa3lIalBNWGRGYThQSXAzUi9FYjF5aHEr?= =?utf-8?B?WGFnM2JrL21ESzFibVpHcU96TDR4dzJJOW9IT0pPT3FLaThDQUZxN2U4ZCtj?= =?utf-8?B?TjRZdHFpNHhxUzBUaFRmaWNKNVlGbnVYUFNjQ2ZMS2JrSlVJT1YyeGR3RlJ4?= =?utf-8?B?djc4elVhWTBDeWJBMHgweXg4S3JwWU9YVGtpVUQyUGNGRVpzS3hkNzRPM0pm?= =?utf-8?B?aXdPcStHOGdyT3oxUCt6eVBKR0NVOVFHY1BqZVd3TTJDMHZzR0d6Mlc4aHZn?= =?utf-8?B?aVY5S0owOG1LblNnWS9Kc2NqcktDUE15Sk1HbTc3NjR3UzRLOG9ISmtwa1Y5?= =?utf-8?B?eFJSWENJSHdTNHc4N01wSk9UKzZJSnY0TFpVTkFJbG9uWCtDN01Zd2UvZ0ly?= =?utf-8?B?Q0tncThXYjZIWUtydU9MMFhuRHdBYUY2amh3THIwMDVIdm1oQUFaOU9wU3lT?= =?utf-8?B?ZEdUQy92QjhjdnExS3gxbTdpeEJiRWJlU2l6aFZsWmtrK1Jub2NwVXh5VkNY?= =?utf-8?B?Z1VEbElrWExrUC9IV0VUdk9pbzNiNmhyOCsySTkybHNKeXgzdFR0QnplZkJy?= =?utf-8?B?UHE2dEtORTNnelR5UVlMTkJLMWFoT3EwYXlMcmJRQ01wdWNNSkxwUFFXNGlD?= =?utf-8?B?T1crbnFUUjQ0c2VxSldxeHBxbitQQnFybWEzYzdCVHk0ekt2T0tpTWpRNEpp?= =?utf-8?B?T2hBZ2NTLzQ4YSs0RW9EZElrN2NVNkYzbkdLM1d2NXM4aUpHdFdWMCtwZkVz?= =?utf-8?B?UFprU0h6K25scnp4UFVZdXQzejBSeUtEOEUxZ0J4MitkRVAvcHpzNkJpVkNN?= =?utf-8?B?MHFyUExlNkJ2eDhWTzhqSHpRNG9qOWlQeEdwak94d202YnIxY3BZU2lHMU9s?= =?utf-8?B?NXN6WFNuQ3p5T3U4QnRYd1hwbTFTcFp4UHZ6SFU2WUxjMDJvZzB0ZzF5SWd0?= =?utf-8?B?cnRuMFdScStHV3A0d0o5VWNUNkMzR1FabjR2aC9YOTJWall3anZMVUozc3hm?= =?utf-8?B?ZGZDRUFkT1JBanVrLzB0Ynl5WExkOFpHT21tZ1ExOENycm9FaDlPcXJOMHoz?= =?utf-8?B?L25MQ09iMnFlZUt2a25ZckpqK1MweWloZ0paQnRFbnFLRXRFNmMyNUszWlZJ?= =?utf-8?B?Zmt3ZnNGczFISUUrZUxqMjM0bUVRNVBKN1Vkd0U0WG5YcWx1VFlHaWM3SFNm?= =?utf-8?B?V2d1dmtqS3hNN3F3citWK2NTY2h6TGRwbjNrQlBCWWczYU5KNklzUlBmYTda?= =?utf-8?B?dFZPK244dTE0d2J5cHlON1VGTHBRZjhiNHhIZ3JnSGxrbFFkRzdBcExYOW5y?= =?utf-8?B?dWtKSHAxZzgrVXJGb0xMMWJoWWxOcEZ5YUU4OWhDc1VMQmtueGhmVzRwNEFP?= =?utf-8?B?Kzg1YWVCbm1aYWlCZzFNUWl6K04wa2pFcExkOXFhZkhPZjdscGF6eUdBWnZL?= =?utf-8?B?VzJlUGhHUTVhSnhDbDJhQU9lVjJXK3NoamNrc0pEOFl6cVVnL3FZRDJlTGZ3?= =?utf-8?B?dmZwRlRxWkhGRUVTOGlrN0syQkVnQ0t4elphdWlKeU5XNWp2ak9TdHB2Q3R5?= =?utf-8?B?aEIzUDVaNjBEekR1dWVOZkRwTXMvNjlNUkx3cDd6RFd3WEUwYzEvTkZOL2lP?= =?utf-8?B?dFBlNUFhdmdzSHBJQ1lhTHE2SzJGWkRPL0w2WnJIZGgza1RFendhdFBFQTJa?= =?utf-8?B?Skhhb1gzS2NPcXBCSFZBdFFsNm9PdUNVQjBLdUc1dVJmS1ZPWkJKZVVrdmFm?= =?utf-8?B?NXVVa2NlY1NqMVpiSzhUQWlHcjF5amNwVERkME5ZcnVpTVozb1hGWk96TDF5?= =?utf-8?B?MWNOUEMrZmFDNklYMHVUNUZha05yNzJvQUQ4dHQ4bkF0dDJvcWU4T0FaZ1JJ?= =?utf-8?B?ZnBFaDJacW91ZitFU20yOGVYTmNwYzBORktQbStFOENBMkRYNVJhWlVMdk9y?= =?utf-8?B?dWU5VS9ZUmMyWnR3UmNGUUpFY3Z3UGNQUEgwQUlMdW0rZzBpSUFrSmtPRG91?= =?utf-8?B?SlV3T3dIcVBDRXB1V2RRVmMvOUZIQUw1NysxSWVZUmdKZzNzaFdMdVZJeUxm?= =?utf-8?B?dVNpK2g0MGk5Wm9haXBFZkNBcjdpaDVNVENaMTU0SWJueUE2Z29STCtNRUY0?= =?utf-8?B?NnZwakJOMTVzQWJITWNHQ1E5T2ZhVjFXbUFCTWVQTFU5YXJvY3R4ZlZ4OHVQ?= =?utf-8?Q?BA1g8RjTVXFgF/yE=3D?= X-Exchange-RoutingPolicyChecked: StrAI17kXdCVh27HEDz32n0vXBIiG5nYagBGd/25eWsI7+ueejXdSiT4LyyYx6r20ACrNppP/gCKBxY6Arvg7OEUdEdMny8m9QAJdI99c+hcyt91C20tt9fsRShfUx1Y6UPlsTNTh46jiKolNssOJljnAb2R3q70HBiqlH5x+MbhaFGhfPMMRggBm0YSHgu11SkBGOKAjxYSLZfo+er8ExfRp+ntHAXxw8NKFb6uFLCgTTOAoOWQjZftBR6eLIi9giDDi/JkdnzQq9e3gWI/DSioKucLO3jRvZvr54R8tRdJrH1cS9lQMc1h8eX97yCOY46yyExH1b/eqSq5gDXB0Q== X-MS-Exchange-CrossTenant-Network-Message-Id: 6a55aae5-3c8c-47ba-b110-08dededced93 X-MS-Exchange-CrossTenant-AuthSource: SJ2PR11MB8370.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Jul 2026 23:42:39.4300 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: hzPkcESpye2iYOUexafepfIBOo+TpwipWxepYB23mGAnV9XXlgXGLPoof7J0XcBoM2isgeiHRH7UoJbJqJb1w3K5TgOjELzUXggdwS485Jg= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH3PPFBA2AA2BA3 X-OriginatorOrg: intel.com Hi Chenyu, On 7/1/26 6:45 AM, Chen Yu wrote: > From: Anil S Keshavamurthy > > Parse the ERDT (Enhanced RDT) ACPI table so enhanced RDT features can > consume firmware-provided domain information. > > The ERDT may contain these sub-tables: > > - Resource Management Domain Description Structure (RMDD) > - CPU Agent Collection Description Structure (CACD) > - Cache Monitoring Registers for CPU Agents Description Structure > (CMRC) How should "The ERDT may contain these sub-tables" be interpreted here? This sounds like some high level partial description of ERDT that is not specific to this patch. > > There is one ERDT per platform. Each RMDD describes one resource "one ERDT" -> "one ERDT table"? > management domain (RMD), also known as an L3 domain, and carries MMIO > base information for later monitoring support. > > Add basic ERDT table parsing and retain the relevant sub-table > information for later processing. > > Handle RMDD specially. For each RMDD, parse the associated CACD, map > its x2APIC IDs to logical CPUs, and save the resulting CPU mask. This > mask associates each ERDT domain with the CPUs that belong to it and is > used later when attaching ERDT data to resctrl monitoring domains. > > Suggested-by: Tony Luck > Suggested-by: Reinette Chatre > Tested-by: Hongyu Ning > Signed-off-by: Anil S Keshavamurthy > Signed-off-by: Chen Yu > --- ... > diff --git a/arch/x86/kernel/cpu/resctrl/erdt.c b/arch/x86/kernel/cpu/resctrl/erdt.c > new file mode 100644 > index 000000000000..6405df9be817 > --- /dev/null > +++ b/arch/x86/kernel/cpu/resctrl/erdt.c > @@ -0,0 +1,271 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Enhanced Resource Director Technology (ERDT) > + * > + * Copyright (C) 2026 Intel Corporation > + * > + */ > + > +#define pr_fmt(fmt) "resctrl: " fmt > + > +#include > +#include > +#include Which parts of cpu.h are used? > +#include > +#include > +#include > +#include > +#include xarray is no longer needed? > + > +#include > + > +#include "internal.h" > + > +static LIST_HEAD(domain_info_list); > + > +static bool __erdt_enabled; Is double underscore needed? Could you please add a comment above the variable to describe what it means when "erdt is enabled"? > + > +#define ERDT_VALID_VERSION 1 > +#define RMDD_FLAG_CPU_L3_DOMAIN BIT(0) > + > +/* Bitmask of valid sub-tables found in the first RMDD, used to ensure all RMDDs match. */ > +static u32 valid_subtbl_mask; > + > +int erdt_get_max_rmid(int cpu) > +{ > + struct erdt_domain_info *d; > + struct list_head *pos; > + > + if (!__erdt_enabled) > + return 0; > + > + list_for_each(pos, &domain_info_list) { > + d = container_of(pos, struct erdt_domain_info, list); (list_for_each_entry()?) > + > + if (cpumask_test_cpu(cpu, d->cpu_mask)) > + return d->max_rmid; > + } > + > + return -1; > +} Using a CPU as parameter to determine the maximum RMID supported by ERDT is unexpected. Looking ahead at how this function is used I find only one usage: rdt_get_l3_mon_config() { ... /* * Currently assume all CPU domains share the same maximum RMID * value from the RMDD table, use CPU0 domain's value. */ int erdt_max_rmid = erdt_get_max_rmid(0); >From this usage I do not see any reason why to do any CPU matching ... erdt_get_max_rmid() could just return the max_rmid of any domain ... but that does not look right either since the comment states an assumption that is never enforced in the code. Could this be made more robust by replacing the "per-erdt-domain max_rmid" with one global "ERDT max RMID" to which all RMDD's max RMID is compared to *ensure* they are all the same. If there is no such guarantee then I expect this will be the minimum among all RMDD? All seems to point to there only being one global value that is determined during ERDT enumeration and then this helper can just return that value directly? > + > +static void __iomem *erdt_ioremap(phys_addr_t base, u32 num_pages, const char *desc) > +{ > + void __iomem *addr; > + size_t size; > + > + if (check_mul_overflow((size_t)num_pages, (size_t)SZ_4K, &size)) I do not think check_mul_overflow() requires size_t type, does it? > + return NULL; > + > + addr = ioremap(base, size); > + if (!addr) { > + pr_err("ERDT: Failed to map %s at phys addr %pa (size: %u pages)\n", > + desc, &base, num_pages); > + } (unnecessary braces) > + return addr; > +} > + > +static void erdt_iounmap_domain(struct erdt_domain_info *domain) > +{ > + for (int i = 0; i < ERDT_MMIO_NUM_TYPES; i++) { > + if (domain->base[i]) { > + iounmap(domain->base[i]); > + domain->base[i] = NULL; > + } > + } > +} > + > +static void cleanup_one_domain(struct erdt_domain_info *d) > +{ > + erdt_iounmap_domain(d); > + free_cpumask_var(d->cpu_mask); free_cpumask_var() does not look right ... it is for stack usage, no? (more later) > + kfree(d); > +} > + > +/* > + * Save CACD information for this RMDD: > + * convert the X2APIC to CPU and save them in a mask. > + */ > +static __init int cacd_init(struct acpi_subtbl_hdr_16 *subtbl, > + struct erdt_domain_info *domain_info) > +{ > + struct acpi_erdt_cacd *cacd = (struct acpi_erdt_cacd *)subtbl; > + int num_ids, cpu; > + > + if (cacd->header.length < struct_size(cacd, X2APICIDS, 1)) { > + pr_warn(FW_BUG "Invalid x2apicid CACD table\n"); > + return -EIO; > + } > + > + num_ids = (cacd->header.length - sizeof(*cacd)) / sizeof(cacd->X2APICIDS[0]); > + > + for (int i = 0; i < num_ids; i++) { > + cpu = topo_lookup_cpuid(cacd->X2APICIDS[i]); > + if (cpu < 0) { > + pr_warn(FW_BUG "Unknown x2apicid 0x%x\n", cacd->X2APICIDS[i]); > + return -EIO; > + } > + > + cpumask_set_cpu(cpu, domain_info->cpu_mask); > + } > + > + return 0; > +} > + > +static inline struct acpi_subtbl_hdr_16 *rmdd_subtbl(struct acpi_erdt_rmdd *rmdd) > +{ > + return (void *)rmdd + sizeof(*rmdd); > +} > + > +static inline struct acpi_subtbl_hdr_16 *next_subtbl(struct acpi_subtbl_hdr_16 *subtbl) > +{ > + return (void *)subtbl + subtbl->length; > +} > + > +static inline bool subtbl_valid(void *end, struct acpi_subtbl_hdr_16 *subtbl) > +{ > + /* Ensure the header is within bounds before dereferencing it. */ > + if ((void *)subtbl + sizeof(*subtbl) > end) > + return false; > + > + /* A sub-table must be at least as large as its header. */ > + if (subtbl->length < sizeof(*subtbl)) > + return false; > + > + /* The entire sub-table (including body) must fit within the parent. */ > + if ((void *)subtbl + subtbl->length > end) > + return false; > + > + return true; > +} > + > +static __init bool parse_rmdd_entry(struct acpi_subtbl_hdr_16 *rmdd_hdr) nit: what is motivation for the "entry" term? this is only occurance of the word "entry" in this patch while RMDD is more frequently referred to as "table" or "sub-table". > +{ > + struct erdt_domain_info *domain_info; > + struct acpi_subtbl_hdr_16 *subtbl; > + struct acpi_erdt_rmdd *rmdd; > + u32 subtbl_mask = 0; > + > + if (rmdd_hdr->length < sizeof(*rmdd)) { > + pr_warn(FW_BUG "Invalid RMDD length %u\n", rmdd_hdr->length); Please include unit, similar to equivalent ERDT message. > + return false; > + } > + > + rmdd = (struct acpi_erdt_rmdd *)rmdd_hdr; > + > + /* Quietly ignore non-CPU-based L3 domains */ > + if (!(rmdd->flags & RMDD_FLAG_CPU_L3_DOMAIN)) > + return true; > + > + domain_info = kzalloc_obj(*domain_info, GFP_KERNEL); > + if (!domain_info) > + return false; > + > + if (!zalloc_cpumask_var(&domain_info->cpu_mask, GFP_KERNEL)) > + goto cleanup; Similar to free_cpumask_var() this does not look right since the cpu_mask is not on stack here ... (more later) > + > + domain_info->base[ERDT_MMIO_RMDD_CREG] = > + erdt_ioremap(rmdd->creg_base, rmdd->creg_size, "RMDD ctrl base"); > + if (!domain_info->base[ERDT_MMIO_RMDD_CREG]) > + goto cleanup; > + > + for (subtbl = rmdd_subtbl(rmdd); > + subtbl_valid((void *)rmdd + rmdd->header.length, subtbl); > + subtbl = next_subtbl(subtbl)) { > + switch (subtbl->type) { > + case ACPI_ERDT_TYPE_CACD: It is quite subtle that there could be multiple CACD tables. Could this be highlighted with a small comment? Something like: /* An RMDD table has one or more CACD sub-table(s) */ > + if (cacd_init(subtbl, domain_info)) > + goto cleanup; > + > + subtbl_mask |= BIT(ACPI_ERDT_TYPE_CACD); > + break; > + default: > + break; > + } > + } > + > + if (!subtbl_mask) > + goto cleanup; > + > + /* > + * Require all RMDDs to support same set of sub-tables > + */ > + if (!valid_subtbl_mask) { > + valid_subtbl_mask = subtbl_mask; > + } else if (subtbl_mask != valid_subtbl_mask) { > + pr_warn(FW_BUG "RMDD sub-table set does not match the first RMDD\n"); Would it be useful to print the domain ID to help diagnistics? > + goto cleanup; > + } > + > + if (!rmdd->max_rmid || rmdd->max_rmid > INT_MAX) { rmdd->max_rmid is a u32 so INT_MAX test is not clear to me here > + pr_warn(FW_BUG "Unreasonable RMDD max_rmid %u\n", rmdd->max_rmid); Is there a limit in the spec? > + goto cleanup; > + } > + domain_info->max_rmid = rmdd->max_rmid; As mentioned before, instead of a per-domain RMID, could there be a global ERDT RMID that is initialized by first ERDT domain and updated/compared with every following ERDT domain? > + > + list_add(&domain_info->list, &domain_info_list); > + > + return true; > + > +cleanup: > + cleanup_one_domain(domain_info); > + return false; > +} > + > +void erdt_exit(void) > +{ > + struct erdt_domain_info *d; > + struct list_head *pos, *n; > + > + list_for_each_safe(pos, n, &domain_info_list) { list_for_each_entry_safe()? > + d = container_of(pos, struct erdt_domain_info, list); > + list_del(pos); > + cleanup_one_domain(d); > + } > + __erdt_enabled = false; > + valid_subtbl_mask = 0; > +} > + > +static __init int enumerate_erdt_table(struct acpi_table_header *table_hdr) > +{ > + struct acpi_table_erdt *erdt = (struct acpi_table_erdt *)table_hdr; > + struct acpi_subtbl_hdr_16 *subtbl; > + void *table_end; > + > + if (erdt->header.revision != ERDT_VALID_VERSION) { > + pr_info("Unsupported ERDT table revision %d\n", erdt->header.revision); Would it be helpful to print what the ERDT table revision is to help diagnostics? > + return -EINVAL; > + } > + > + if (erdt->header.length < sizeof(*erdt)) { > + pr_warn(FW_BUG "ERDT: Invalid table length %u bytes\n", erdt->header.length); > + return -EINVAL; > + } > + > + subtbl = (void *)erdt + sizeof(struct acpi_table_erdt); > + table_end = (void *)erdt + erdt->header.length; > + > + while (subtbl_valid(table_end, subtbl)) { > + if (subtbl->type == ACPI_ERDT_TYPE_RMDD && > + !parse_rmdd_entry(subtbl)) > + goto cleanup; > + > + subtbl = next_subtbl(subtbl); > + } > + > + if (list_empty(&domain_info_list)) > + goto cleanup; > + > + __erdt_enabled = true; > + > + return 0; > + > +cleanup: > + erdt_exit(); > + return -EINVAL; > +} > + > +int __init erdt_init(void) > +{ > + return acpi_table_parse(ACPI_SIG_ERDT, enumerate_erdt_table); > +} > diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h > index e3cfa0c10e92..299d7222f693 100644 > --- a/arch/x86/kernel/cpu/resctrl/internal.h > +++ b/arch/x86/kernel/cpu/resctrl/internal.h > @@ -21,6 +21,26 @@ > > #define RMID_VAL_UNAVAIL BIT_ULL(62) > > +/* > + * Index into erdt_domain_info::base[] for each MMIO region. > + * @ERDT_MMIO_RMDD_CREG: RMDD control register base address > + * @ERDT_MMIO_CMRC_BASE: CMRC monitoring register base address > + */ > +enum erdt_mmio_type { > + ERDT_MMIO_RMDD_CREG, > + ERDT_MMIO_CMRC_BASE, > + ERDT_MMIO_LAST = ERDT_MMIO_CMRC_BASE > +}; > + > +#define ERDT_MMIO_NUM_TYPES (ERDT_MMIO_LAST + 1) > + Please add documentation here that describes each member of struct erdt_domain_info. > +struct erdt_domain_info { > + void __iomem *base[ERDT_MMIO_NUM_TYPES]; > + cpumask_var_t cpu_mask; Should this be struct cpumask instead? Compare with struct rdt_domain_hdr. When evaluating cpumask_var_t, please read the detailed comments above its definition in include/linux/cpumask_types.h - specifically note the start: *cpumask_var_t: struct cpumask for stack usage* > + int max_rmid; > + struct list_head list; Could you please rename this to be "node" or "entry" to make it obvious that this is an entry of a list? This is not consistent in resctrl but really helps when reading the code. > +}; > + > /* > * With the above fields in use 62 bits remain in MSR_IA32_QM_CTR for > * data to be returned. The counter width is discovered from the hardware > @@ -253,4 +273,8 @@ static inline void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resour > static inline bool intel_handle_aet_option(bool force_off, char *tok) { return false; } > #endif > > +int erdt_get_max_rmid(int cpu); > +int erdt_init(void); > +void erdt_exit(void); > + > #endif /* _ASM_X86_RESCTRL_INTERNAL_H */ Reinette