arch/xtensa/kernel/process.c

Source file repositories/reference/linux-study-clean/arch/xtensa/kernel/process.c

File Facts

System
Linux kernel
Corpus path
arch/xtensa/kernel/process.c
Extension
.c
Size
10976 bytes
Lines
401
Domain
Architecture Layer
Bucket
arch/xtensa
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

if (ti) {
			coprocessor_flush(ti, i);

			for (j = 0; j < n; j++)
				if (unique_owner[j] == ti)
					break;
			if (j == n)
				unique_owner[n++] = ti;

			coprocessor_owner[i] = NULL;
		}
	}
	for (i = 0; i < n; i++) {
		/* pairs with memw (1) in fast_coprocessor and memw in switch_to */
		smp_wmb();
		unique_owner[i]->cpenable = 0;
	}
	xtensa_set_sr(0, cpenable);
}

static void local_coprocessor_release_all(void *info)
{
	struct thread_info *ti = info;
	struct thread_info **coprocessor_owner;
	int i;

	coprocessor_owner = this_cpu_ptr(&exc_table)->coprocessor_owner;

	/* Walk through all cp owners and release it for the requested one. */

	for (i = 0; i < XCHAL_CP_MAX; i++) {
		if (coprocessor_owner[i] == ti)
			coprocessor_owner[i] = NULL;
	}
	/* pairs with memw (1) in fast_coprocessor and memw in switch_to */
	smp_wmb();
	ti->cpenable = 0;
	if (ti == current_thread_info())
		xtensa_set_sr(0, cpenable);
}

void coprocessor_release_all(struct thread_info *ti)
{
	if (ti->cpenable) {
		/* pairs with memw (2) in fast_coprocessor */
		smp_rmb();
		smp_call_function_single(ti->cp_owner_cpu,
					 local_coprocessor_release_all,
					 ti, true);
	}
}

static void local_coprocessor_flush_all(void *info)
{
	struct thread_info *ti = info;
	struct thread_info **coprocessor_owner;
	unsigned long old_cpenable;
	int i;

	coprocessor_owner = this_cpu_ptr(&exc_table)->coprocessor_owner;
	old_cpenable = xtensa_xsr(ti->cpenable, cpenable);

	for (i = 0; i < XCHAL_CP_MAX; i++) {
		if (coprocessor_owner[i] == ti)
			coprocessor_flush(ti, i);
	}
	xtensa_set_sr(old_cpenable, cpenable);
}

void coprocessor_flush_all(struct thread_info *ti)
{
	if (ti->cpenable) {
		/* pairs with memw (2) in fast_coprocessor */
		smp_rmb();
		smp_call_function_single(ti->cp_owner_cpu,
					 local_coprocessor_flush_all,
					 ti, true);
	}
}

static void local_coprocessor_flush_release_all(void *info)
{
	local_coprocessor_flush_all(info);
	local_coprocessor_release_all(info);
}

void coprocessor_flush_release_all(struct thread_info *ti)
{
	if (ti->cpenable) {
		/* pairs with memw (2) in fast_coprocessor */

Annotation

Implementation Notes