Commit f6f0c9a7 authored by Huacai Chen's avatar Huacai Chen
Browse files

LoongArch: Add SMT (Simultaneous Multi-Threading) support



Loongson-3A6000 has SMT (Simultaneous Multi-Threading) support, each
physical core has two logical cores (threads). This patch add SMT probe
and scheduler support via ACPI PPTT.

If SCHED_SMT enabled, Loongson-3A6000 is treated as 4 cores, 8 threads;
If SCHED_SMT disabled, Loongson-3A6000 is treated as 8 cores, 8 threads.

Remove smp_num_siblings to support HMP (Heterogeneous Multi-Processing).

Signed-off-by: default avatarLiupu Wang <wangliupu@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 61650023
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ config LOONGARCH
	select ACPI
	select ACPI_GENERIC_GSI if ACPI
	select ACPI_MCFG if ACPI
	select ACPI_PPTT if ACPI
	select ACPI_SYSTEM_POWER_STATES_SUPPORT	if ACPI
	select ARCH_BINFMT_ELF_STATE
	select ARCH_ENABLE_MEMORY_HOTPLUG
@@ -376,6 +377,13 @@ config EFI_STUB
	  This kernel feature allows the kernel to be loaded directly by
	  EFI firmware without the use of a bootloader.

config SCHED_SMT
	bool "SMT scheduler support"
	default y
	help
	  Improves scheduler's performance when there are multiple
	  threads in one physical core.

config SMP
	bool "Multi-Processing support"
	help
+9 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ extern int acpi_strict;
extern int acpi_disabled;
extern int acpi_pci_disabled;
extern int acpi_noirq;
extern int pptt_enabled;

#define acpi_os_ioremap acpi_os_ioremap
void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
@@ -30,6 +31,14 @@ static inline bool acpi_has_cpu_in_madt(void)
}

extern struct list_head acpi_wakeup_device_list;
extern struct acpi_madt_core_pic acpi_core_pic[NR_CPUS];

extern int __init parse_acpi_topology(void);

static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
{
	return acpi_core_pic[cpu_logical_map(cpu)].processor_id;
}

#endif /* !CONFIG_ACPI */

+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ struct cpuinfo_loongarch {
	struct cache_desc	cache_leaves[CACHE_LEAVES_MAX];
	int			core;   /* physical core number in package */
	int			package;/* physical package number */
	int			global_id; /* physical global thread number */
	int			vabits; /* Virtual Address size in bits */
	int			pabits; /* Physical Address size in bits */
	unsigned int		ksave_mask; /* Usable KSave mask. */
+32 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ u64 acpi_saved_sp;

#define PREFIX			"ACPI: "

struct acpi_madt_core_pic acpi_core_pic[NR_CPUS];

void __init __iomem * __acpi_map_table(unsigned long phys, unsigned long size)
{

@@ -99,6 +101,7 @@ acpi_parse_processor(union acpi_subtable_headers *header, const unsigned long en

	acpi_table_print_madt_entry(&header->common);
#ifdef CONFIG_SMP
	acpi_core_pic[processor->core_id] = *processor;
	set_processor_mask(processor->core_id, processor->flags);
#endif

@@ -140,6 +143,35 @@ static void __init acpi_process_madt(void)
	loongson_sysconf.nr_cpus = num_processors;
}

int pptt_enabled;

int __init parse_acpi_topology(void)
{
	int cpu, topology_id;

	for_each_possible_cpu(cpu) {
		topology_id = find_acpi_cpu_topology(cpu, 0);
		if (topology_id < 0) {
			pr_warn("Invalid BIOS PPTT\n");
			return -ENOENT;
		}

		if (acpi_pptt_cpu_is_thread(cpu) <= 0)
			cpu_data[cpu].core = topology_id;
		else {
			topology_id = find_acpi_cpu_topology(cpu, 1);
			if (topology_id < 0)
				return -ENOENT;

			cpu_data[cpu].core = topology_id;
		}
	}

	pptt_enabled = 1;

	return 0;
}

#ifndef CONFIG_SUSPEND
int (*acpi_suspend_lowlevel)(void);
#else
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
	seq_printf(m, "processor\t\t: %ld\n", n);
	seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
	seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
	seq_printf(m, "global_id\t\t: %d\n", cpu_data[n].global_id);
	seq_printf(m, "CPU Family\t\t: %s\n", __cpu_family[n]);
	seq_printf(m, "Model Name\t\t: %s\n", __cpu_full_name[n]);
	seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version);
Loading