Commit 1e4ee513 authored by Tiwei Bie's avatar Tiwei Bie Committed by Johannes Berg
Browse files

um: Add initial SMP support



Add initial symmetric multi-processing (SMP) support to UML. With
this support enabled, users can tell UML to start multiple virtual
processors, each represented as a separate host thread.

In UML, kthreads and normal threads (when running in kernel mode)
can be scheduled and executed simultaneously on different virtual
processors. However, the userspace code of normal threads still
runs within their respective single-threaded stubs.

That is, SMP support is currently available both within the kernel
and across different processes, but still remains limited within
threads of the same process in userspace.

Signed-off-by: default avatarTiwei Bie <tiwei.btw@antgroup.com>
Link: https://patch.msgid.link/20251027001815.1666872-6-tiwei.bie@linux.dev


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9c82de55
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
    |        s390: |  ok  |
    |          sh: |  ok  |
    |       sparc: |  ok  |
    |          um: | TODO |
    |          um: |  ok  |
    |         x86: |  ok  |
    |      xtensa: |  ok  |
    -----------------------
+43 −3
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ config UML
	select OF_EARLY_FLATTREE if OF
	select GENERIC_IRQ_SHOW
	select GENERIC_CPU_DEVICES
	select GENERIC_SMP_IDLE_THREAD
	select HAVE_GCC_PLUGINS
	select ARCH_SUPPORTS_LTO_CLANG
	select ARCH_SUPPORTS_LTO_CLANG_THIN
@@ -81,10 +82,48 @@ config HZ
	int
	default 100

config NR_CPUS
config UML_SUBARCH_SUPPORTS_SMP
	bool

config SMP
	bool "Symmetric multi-processing support"
	default n
	depends on UML_SUBARCH_SUPPORTS_SMP
	help
	  This option enables UML SMP support.

	  With this enabled, users can tell UML to start multiple virtual
	  processors. Each virtual processor is represented as a separate
	  host thread.

	  In UML, kthreads and normal threads (when running in kernel mode)
	  can be scheduled and executed simultaneously on different virtual
	  processors. However, the userspace code of normal threads still
	  runs within their respective single-threaded stubs.

	  That is, SMP support is available both within the kernel and
	  across different processes, but remains limited within threads
	  of the same process in userspace.

config NR_CPUS_RANGE_BEGIN
	int
	range 1 1
	default 1
	default 1 if !SMP
	default 2

config NR_CPUS_RANGE_END
	int
	default 1 if !SMP
	default 64

config NR_CPUS_DEFAULT
	int
	default 1 if !SMP
	default 2

config NR_CPUS
	int "Maximum number of CPUs" if SMP
	range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END
	default NR_CPUS_DEFAULT

source "arch/$(HEADER_ARCH)/um/Kconfig"

@@ -254,6 +293,7 @@ source "arch/um/drivers/Kconfig"

config ARCH_SUSPEND_POSSIBLE
	def_bool y
	depends on !SMP

menu "Power management options"

+3 −2
Original line number Diff line number Diff line
@@ -7,15 +7,16 @@

#ifndef __ASSEMBLER__

#include <shared/smp.h>

struct task_struct;
extern struct task_struct *cpu_tasks[NR_CPUS];

static __always_inline struct task_struct *get_current(void)
{
	return cpu_tasks[0];
	return cpu_tasks[uml_curr_cpu()];
}


#define current get_current()

#endif /* __ASSEMBLER__ */
+23 −1
Original line number Diff line number Diff line
@@ -2,8 +2,30 @@
#ifndef __ASM_UM_HARDIRQ_H
#define __ASM_UM_HARDIRQ_H

#include <asm-generic/hardirq.h>
#include <linux/cache.h>
#include <linux/threads.h>

#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1

typedef struct {
	unsigned int __softirq_pending;
#if IS_ENABLED(CONFIG_SMP)
	unsigned int irq_resched_count;
	unsigned int irq_call_count;
#endif
} ____cacheline_aligned irq_cpustat_t;

DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);

#define __ARCH_IRQ_STAT

#define inc_irq_stat(member)	this_cpu_inc(irq_stat.member)

#include <linux/irq.h>

static inline void ack_bad_irq(unsigned int irq)
{
	pr_crit("unexpected IRQ trap at vector %02x\n", irq);
}

#endif /* __ASM_UM_HARDIRQ_H */
+10 −0
Original line number Diff line number Diff line
@@ -7,16 +7,26 @@
#define __ARCH_UM_MMU_H

#include "linux/types.h"
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <mm_id.h>

typedef struct mm_context {
	struct mm_id id;
	struct mutex turnstile;

	struct list_head list;

	/* Address range in need of a TLB sync */
	spinlock_t sync_tlb_lock;
	unsigned long sync_tlb_range_from;
	unsigned long sync_tlb_range_to;
} mm_context_t;

#define INIT_MM_CONTEXT(mm)						\
	.context = {							\
		.turnstile = __MUTEX_INITIALIZER(mm.context.turnstile),	\
		.sync_tlb_lock = __SPIN_LOCK_INITIALIZER(mm.context.sync_tlb_lock), \
	}

#endif
Loading