Skip to content

Commit b7065f4

Browse files
committed
x86/cpu/topology: Provide logical pkg/die mapping
With the topology bitmaps in place the logical package and die IDs can trivially be retrieved by determining the bitmap weight of the relevant topology domain level up to and including the physical ID in question. Provide a function to that effect. Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Michael Kelley <[email protected]> Tested-by: Sohil Mehta <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5e40fb2 commit b7065f4

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

arch/x86/include/asm/topology.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,15 @@ static inline unsigned int topology_max_die_per_package(void)
156156
return __max_dies_per_package;
157157
}
158158

159+
#ifdef CONFIG_X86_LOCAL_APIC
160+
int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);
161+
#else
162+
static inline int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level)
163+
{
164+
return 0;
165+
}
166+
#endif
167+
159168
#ifdef CONFIG_SMP
160169
#define topology_cluster_id(cpu) (cpu_data(cpu).topo.l2c_id)
161170
#define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu))

arch/x86/kernel/cpu/topology.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,34 @@ void __init topology_register_boot_apic(u32 apic_id)
229229
topo_register_apic(apic_id, CPU_ACPIID_INVALID, true);
230230
}
231231

232+
/**
233+
* topology_get_logical_id - Retrieve the logical ID at a given topology domain level
234+
* @apicid: The APIC ID for which to lookup the logical ID
235+
* @at_level: The topology domain level to use
236+
*
237+
* @apicid must be a full APIC ID, not the normalized variant. It's valid to have
238+
* all bits below the domain level specified by @at_level to be clear. So both
239+
* real APIC IDs and backshifted normalized APIC IDs work correctly.
240+
*
241+
* Returns:
242+
* - >= 0: The requested logical ID
243+
* - -ERANGE: @apicid is out of range
244+
* - -ENODEV: @apicid is not registered
245+
*/
246+
int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level)
247+
{
248+
/* Remove the bits below @at_level to get the proper level ID of @apicid */
249+
unsigned int lvlid = topo_apicid(apicid, at_level);
250+
251+
if (lvlid >= MAX_LOCAL_APIC)
252+
return -ERANGE;
253+
if (!test_bit(lvlid, apic_maps[at_level].map))
254+
return -ENODEV;
255+
/* Get the number of set bits before @lvlid. */
256+
return bitmap_weight(apic_maps[at_level].map, lvlid);
257+
}
258+
EXPORT_SYMBOL_GPL(topology_get_logical_id);
259+
232260
#ifdef CONFIG_ACPI_HOTPLUG_CPU
233261
/**
234262
* topology_hotplug_apic - Handle a physical hotplugged APIC after boot

0 commit comments

Comments
 (0)