Skip to content

Commit cf002da

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/intel/uncore: Support MSR portal for discovery tables
Starting from the Panther Lake, the discovery table mechanism is also supported in client platforms. The difference is that the portal of the global discovery table is retrieved from an MSR. The layout of discovery tables are the same as the server platforms. Factor out __parse_discovery_table() to parse discover tables. The uncore PMON is Die scope. Need to parse the discovery tables for each die. Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Dapeng Mi <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent d7b8f8e commit cf002da

File tree

2 files changed

+70
-20
lines changed

2 files changed

+70
-20
lines changed

arch/x86/events/intel/uncore_discovery.c

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,32 +274,15 @@ uncore_ignore_unit(struct uncore_unit_discovery *unit, int *ignore)
274274
return false;
275275
}
276276

277-
static int parse_discovery_table(struct pci_dev *dev, int die,
278-
u32 bar_offset, bool *parsed,
279-
int *ignore)
277+
static int __parse_discovery_table(resource_size_t addr, int die,
278+
bool *parsed, int *ignore)
280279
{
281280
struct uncore_global_discovery global;
282281
struct uncore_unit_discovery unit;
283282
void __iomem *io_addr;
284-
resource_size_t addr;
285283
unsigned long size;
286-
u32 val;
287284
int i;
288285

289-
pci_read_config_dword(dev, bar_offset, &val);
290-
291-
if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64)
292-
return -EINVAL;
293-
294-
addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK);
295-
#ifdef CONFIG_PHYS_ADDR_T_64BIT
296-
if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
297-
u32 val2;
298-
299-
pci_read_config_dword(dev, bar_offset + 4, &val2);
300-
addr |= ((resource_size_t)val2) << 32;
301-
}
302-
#endif
303286
size = UNCORE_DISCOVERY_GLOBAL_MAP_SIZE;
304287
io_addr = ioremap(addr, size);
305288
if (!io_addr)
@@ -342,7 +325,32 @@ static int parse_discovery_table(struct pci_dev *dev, int die,
342325
return 0;
343326
}
344327

345-
bool intel_uncore_has_discovery_tables(int *ignore)
328+
static int parse_discovery_table(struct pci_dev *dev, int die,
329+
u32 bar_offset, bool *parsed,
330+
int *ignore)
331+
{
332+
resource_size_t addr;
333+
u32 val;
334+
335+
pci_read_config_dword(dev, bar_offset, &val);
336+
337+
if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64)
338+
return -EINVAL;
339+
340+
addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK);
341+
#ifdef CONFIG_PHYS_ADDR_T_64BIT
342+
if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
343+
u32 val2;
344+
345+
pci_read_config_dword(dev, bar_offset + 4, &val2);
346+
addr |= ((resource_size_t)val2) << 32;
347+
}
348+
#endif
349+
350+
return __parse_discovery_table(addr, die, parsed, ignore);
351+
}
352+
353+
static bool intel_uncore_has_discovery_tables_pci(int *ignore)
346354
{
347355
u32 device, val, entry_id, bar_offset;
348356
int die, dvsec = 0, ret = true;
@@ -391,6 +399,45 @@ bool intel_uncore_has_discovery_tables(int *ignore)
391399
return ret;
392400
}
393401

402+
static bool intel_uncore_has_discovery_tables_msr(int *ignore)
403+
{
404+
unsigned long *die_mask;
405+
bool parsed = false;
406+
int cpu, die;
407+
u64 base;
408+
409+
die_mask = kcalloc(BITS_TO_LONGS(uncore_max_dies()),
410+
sizeof(unsigned long), GFP_KERNEL);
411+
if (!die_mask)
412+
return false;
413+
414+
cpus_read_lock();
415+
for_each_online_cpu(cpu) {
416+
die = topology_logical_die_id(cpu);
417+
if (__test_and_set_bit(die, die_mask))
418+
continue;
419+
420+
if (rdmsrq_safe_on_cpu(cpu, UNCORE_DISCOVERY_MSR, &base))
421+
continue;
422+
423+
if (!base)
424+
continue;
425+
426+
__parse_discovery_table(base, die, &parsed, ignore);
427+
}
428+
429+
cpus_read_unlock();
430+
431+
kfree(die_mask);
432+
return parsed;
433+
}
434+
435+
bool intel_uncore_has_discovery_tables(int *ignore)
436+
{
437+
return intel_uncore_has_discovery_tables_msr(ignore) ||
438+
intel_uncore_has_discovery_tables_pci(ignore);
439+
}
440+
394441
void intel_uncore_clear_discovery_tables(void)
395442
{
396443
struct intel_uncore_discovery_type *type, *next;

arch/x86/events/intel/uncore_discovery.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/* SPDX-License-Identifier: GPL-2.0-only */
22

3+
/* Store the full address of the global discovery table */
4+
#define UNCORE_DISCOVERY_MSR 0x201e
5+
36
/* Generic device ID of a discovery table device */
47
#define UNCORE_DISCOVERY_TABLE_DEVICE 0x09a7
58
/* Capability ID for a discovery table device */

0 commit comments

Comments
 (0)