arch/powerpc/kernel/smp.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/smp.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/smp.c
Extension
.c
Size
45705 bytes
Lines
1826
Domain
Architecture Layer
Bucket
arch/powerpc
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

struct thread_groups {
	unsigned int property;
	unsigned int nr_groups;
	unsigned int threads_per_group;
	unsigned int thread_list[MAX_THREAD_LIST_SIZE];
};

/* Maximum number of properties that groups of threads within a core can share */
#define MAX_THREAD_GROUP_PROPERTIES 2

struct thread_groups_list {
	unsigned int nr_properties;
	struct thread_groups property_tgs[MAX_THREAD_GROUP_PROPERTIES];
};

static struct thread_groups_list tgl[NR_CPUS] __initdata;
/*
 * On big-cores system, thread_group_l1_cache_map for each CPU corresponds to
 * the set its siblings that share the L1-cache.
 */
DEFINE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map);

/*
 * On some big-cores system, thread_group_l2_cache_map for each CPU
 * corresponds to the set its siblings within the core that share the
 * L2-cache.
 */
DEFINE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map);

/*
 * On P10, thread_group_l3_cache_map for each CPU is equal to the
 * thread_group_l2_cache_map
 */
DEFINE_PER_CPU(cpumask_var_t, thread_group_l3_cache_map);

/* SMP operations for this machine */
struct smp_ops_t *smp_ops;

/* Can't be static due to PowerMac hackery */
volatile unsigned int cpu_callin_map[NR_CPUS];

int smt_enabled_at_boot = 1;

/*
 * Returns 1 if the specified cpu should be brought up during boot.
 * Used to inhibit booting threads if they've been disabled or
 * limited on the command line
 */
int smp_generic_cpu_bootable(unsigned int nr)
{
	/* Special case - we inhibit secondary thread startup
	 * during boot if the user requests it.
	 */
	if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
		if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
			return 0;
		if (smt_enabled_at_boot
		    && cpu_thread_in_core(nr) >= smt_enabled_at_boot)
			return 0;
	}

	return 1;
}


#ifdef CONFIG_PPC64
int smp_generic_kick_cpu(int nr)
{
	if (nr < 0 || nr >= nr_cpu_ids)
		return -EINVAL;

	/*
	 * The processor is currently spinning, waiting for the
	 * cpu_start field to become non-zero After we set cpu_start,
	 * the processor will continue on to secondary_start
	 */
	if (!paca_ptrs[nr]->cpu_start) {
		paca_ptrs[nr]->cpu_start = 1;
		smp_mb();
		return 0;
	}

#ifdef CONFIG_HOTPLUG_CPU
	/*
	 * Ok it's not there, so it might be soft-unplugged, let's
	 * try to bring it back
	 */
	generic_set_cpu_up(nr);
	smp_wmb();
	smp_send_reschedule(nr);

Annotation

Implementation Notes