arch/x86/kernel/cpu/topology_common.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/cpu/topology_common.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/cpu/topology_common.c
Extension
.c
Size
6692 bytes
Lines
256
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (c->topo.intel_type) {
		case INTEL_CPU_TYPE_ATOM: return TOPO_CPU_TYPE_EFFICIENCY;
		case INTEL_CPU_TYPE_CORE: return TOPO_CPU_TYPE_PERFORMANCE;
		}
	}
	if (c->x86_vendor == X86_VENDOR_AMD) {
		switch (c->topo.amd_type) {
		case 0:	return TOPO_CPU_TYPE_PERFORMANCE;
		case 1:	return TOPO_CPU_TYPE_EFFICIENCY;
		}
	}

	return TOPO_CPU_TYPE_UNKNOWN;
}

const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c)
{
	switch (get_topology_cpu_type(c)) {
	case TOPO_CPU_TYPE_PERFORMANCE:
		return "performance";
	case TOPO_CPU_TYPE_EFFICIENCY:
		return "efficiency";
	default:
		return "unknown";
	}
}

static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
{
	struct {
		u32	cache_type	:  5,
			unused		: 21,
			ncores		:  6;
	} eax;

	if (c->cpuid_level < 4)
		return 1;

	cpuid_subleaf_reg(4, 0, CPUID_EAX, &eax);
	if (!eax.cache_type)
		return 1;

	return eax.ncores + 1;
}

static void parse_legacy(struct topo_scan *tscan)
{
	unsigned int cores, core_shift, smt_shift = 0;
	struct cpuinfo_x86 *c = tscan->c;

	cores = parse_num_cores_legacy(c);
	core_shift = get_count_order(cores);

	if (cpu_has(c, X86_FEATURE_HT)) {
		if (!WARN_ON_ONCE(tscan->ebx1_nproc_shift < core_shift))
			smt_shift = tscan->ebx1_nproc_shift - core_shift;
		/*
		 * The parser expects leaf 0xb/0x1f format, which means
		 * the number of logical processors at core level is
		 * counting threads.
		 */
		core_shift += smt_shift;
		cores <<= smt_shift;
	}

	topology_set_dom(tscan, TOPO_SMT_DOMAIN, smt_shift, 1U << smt_shift);
	topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
}

static bool fake_topology(struct topo_scan *tscan)
{
	/*
	 * Preset the CORE level shift for CPUID less systems and XEN_PV,
	 * which has useless CPUID information.
	 */
	topology_set_dom(tscan, TOPO_SMT_DOMAIN, 0, 1);
	topology_set_dom(tscan, TOPO_CORE_DOMAIN, 0, 1);

	return tscan->c->cpuid_level < 1;
}

static void parse_topology(struct topo_scan *tscan, bool early)
{
	const struct cpuinfo_topology topo_defaults = {
		.cu_id			= 0xff,
		.llc_id			= BAD_APICID,
		.l2c_id			= BAD_APICID,
		.cpu_type		= TOPO_CPU_TYPE_UNKNOWN,
	};
	struct cpuinfo_x86 *c = tscan->c;

Annotation

Implementation Notes