arch/sparc/kernel/smp_64.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/smp_64.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/smp_64.c
Extension
.c
Size
36991 bytes
Lines
1564
Domain
Architecture Layer
Bucket
arch/sparc
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 tlb_pending_info {
	unsigned long ctx;
	unsigned long nr;
	unsigned long *vaddrs;
};

static void tlb_pending_func(void *info)
{
	struct tlb_pending_info *t = info;

	__flush_tlb_pending(t->ctx, t->nr, t->vaddrs);
}

void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs)
{
	u32 ctx = CTX_HWBITS(mm->context);
	struct tlb_pending_info info;

	get_cpu();

	info.ctx = ctx;
	info.nr = nr;
	info.vaddrs = vaddrs;

	smp_call_function_many(mm_cpumask(mm), tlb_pending_func,
			       &info, 1);

	__flush_tlb_pending(ctx, nr, vaddrs);

	put_cpu();
}

void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
{
	unsigned long context = CTX_HWBITS(mm->context);

	get_cpu();

	smp_cross_call_masked(&xcall_flush_tlb_page,
			      context, vaddr, 0,
			      mm_cpumask(mm));

	__flush_tlb_page(context, vaddr);

	put_cpu();
}

void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
	start &= PAGE_MASK;
	end    = PAGE_ALIGN(end);
	if (start != end) {
		smp_cross_call(&xcall_flush_tlb_kernel_range,
			       0, start, end);

		__flush_tlb_kernel_range(start, end);
	}
}

/* CPU capture. */
/* #define CAPTURE_DEBUG */
extern unsigned long xcall_capture;

static atomic_t smp_capture_depth = ATOMIC_INIT(0);
static atomic_t smp_capture_registry = ATOMIC_INIT(0);
static unsigned long penguins_are_doing_time;

void smp_capture(void)
{
	int result = atomic_add_return(1, &smp_capture_depth);

	if (result == 1) {
		int ncpus = num_online_cpus();

#ifdef CAPTURE_DEBUG
		printk("CPU[%d]: Sending penguins to jail...",
		       smp_processor_id());
#endif
		penguins_are_doing_time = 1;
		atomic_inc(&smp_capture_registry);
		smp_cross_call(&xcall_capture, 0, 0, 0);
		while (atomic_read(&smp_capture_registry) != ncpus)
			rmb();
#ifdef CAPTURE_DEBUG
		printk("done\n");
#endif
	}
}

void smp_release(void)

Annotation

Implementation Notes