arch/csky/kernel/smp.c

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

File Facts

System
Linux kernel
Corpus path
arch/csky/kernel/smp.c
Extension
.c
Size
6095 bytes
Lines
316
Domain
Architecture Layer
Bucket
arch/csky
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 ipi_data_struct {
	unsigned long bits ____cacheline_aligned;
	unsigned long stats[IPI_MAX] ____cacheline_aligned;
};
static DEFINE_PER_CPU(struct ipi_data_struct, ipi_data);

static irqreturn_t handle_ipi(int irq, void *dev)
{
	unsigned long *stats = this_cpu_ptr(&ipi_data)->stats;

	while (true) {
		unsigned long ops;

		ops = xchg(&this_cpu_ptr(&ipi_data)->bits, 0);
		if (ops == 0)
			return IRQ_HANDLED;

		if (ops & (1 << IPI_RESCHEDULE)) {
			stats[IPI_RESCHEDULE]++;
			scheduler_ipi();
		}

		if (ops & (1 << IPI_CALL_FUNC)) {
			stats[IPI_CALL_FUNC]++;
			generic_smp_call_function_interrupt();
		}

		if (ops & (1 << IPI_IRQ_WORK)) {
			stats[IPI_IRQ_WORK]++;
			irq_work_run();
		}

		BUG_ON((ops >> IPI_MAX) != 0);
	}

	return IRQ_HANDLED;
}

static void (*send_arch_ipi)(const struct cpumask *mask);

static int ipi_irq;
void __init set_send_ipi(void (*func)(const struct cpumask *mask), int irq)
{
	if (send_arch_ipi)
		return;

	send_arch_ipi = func;
	ipi_irq = irq;
}

static void
send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
{
	int i;

	for_each_cpu(i, to_whom)
		set_bit(operation, &per_cpu_ptr(&ipi_data, i)->bits);

	smp_mb();
	send_arch_ipi(to_whom);
}

static const char * const ipi_names[] = {
	[IPI_EMPTY]		= "Empty interrupts",
	[IPI_RESCHEDULE]	= "Rescheduling interrupts",
	[IPI_CALL_FUNC]		= "Function call interrupts",
	[IPI_IRQ_WORK]		= "Irq work interrupts",
};

int arch_show_interrupts(struct seq_file *p, int prec)
{
	unsigned int cpu, i;

	for (i = 0; i < IPI_MAX; i++) {
		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
			   prec >= 4 ? " " : "");
		for_each_online_cpu(cpu)
			seq_printf(p, "%10lu ",
				per_cpu_ptr(&ipi_data, cpu)->stats[i]);
		seq_printf(p, " %s\n", ipi_names[i]);
	}

	return 0;
}

void arch_send_call_function_ipi_mask(struct cpumask *mask)
{
	send_ipi_message(mask, IPI_CALL_FUNC);
}

Annotation

Implementation Notes