arch/s390/kernel/processor.c

Source file repositories/reference/linux-study-clean/arch/s390/kernel/processor.c

File Facts

System
Linux kernel
Corpus path
arch/s390/kernel/processor.c
Extension
.c
Size
9036 bytes
Lines
387
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source 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 cpu_info {
	unsigned int cpu_mhz_dynamic;
	unsigned int cpu_mhz_static;
	struct cpuid cpu_id;
};

static DEFINE_PER_CPU(struct cpu_info, cpu_info);
static DEFINE_PER_CPU(int, cpu_relax_retry);

static bool machine_has_cpu_mhz;

void __init cpu_detect_mhz_feature(void)
{
	if (test_facility(34) && __ecag(ECAG_CPU_ATTRIBUTE, 0) != -1UL)
		machine_has_cpu_mhz = true;
}

static void update_cpu_mhz(void *arg)
{
	unsigned long mhz;
	struct cpu_info *c;

	mhz = __ecag(ECAG_CPU_ATTRIBUTE, 0);
	c = this_cpu_ptr(&cpu_info);
	c->cpu_mhz_dynamic = mhz >> 32;
	c->cpu_mhz_static = mhz & 0xffffffff;
}

void s390_update_cpu_mhz(void)
{
	s390_adjust_jiffies();
	if (machine_has_cpu_mhz)
		on_each_cpu(update_cpu_mhz, NULL, 0);
}

void notrace stop_machine_yield(const struct cpumask *cpumask)
{
	int cpu, this_cpu;

	this_cpu = smp_processor_id();
	if (__this_cpu_inc_return(cpu_relax_retry) >= spin_retry) {
		__this_cpu_write(cpu_relax_retry, 0);
		cpu = cpumask_next_wrap(this_cpu, cpumask);
		if (cpu >= nr_cpu_ids)
			return;
		if (arch_vcpu_is_preempted(cpu))
			smp_yield_cpu(cpu);
	}
}

static void do_sync_core(void *info)
{
	sync_core();
}

void text_poke_sync(void)
{
	on_each_cpu(do_sync_core, NULL, 1);
}

void text_poke_sync_lock(void)
{
	cpus_read_lock();
	text_poke_sync();
	cpus_read_unlock();
}

/*
 * cpu_init - initializes state that is per-CPU.
 */
void cpu_init(void)
{
	struct cpuid *id = this_cpu_ptr(&cpu_info.cpu_id);

	get_cpu_id(id);
	if (machine_has_cpu_mhz)
		update_cpu_mhz(NULL);
	mmgrab(&init_mm);
	current->active_mm = &init_mm;
	BUG_ON(current->mm);
	enter_lazy_tlb(&init_mm, current);
}

static void show_facilities(struct seq_file *m)
{
	unsigned int bit;

	seq_puts(m, "facilities      :");
	for_each_set_bit_inv(bit, (long *)&stfle_fac_list, MAX_FACILITY_BIT)
		seq_printf(m, " %d", bit);

Annotation

Implementation Notes