Commit de5e73dc authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Alex Deucher
Browse files

drm/amd/display: Simplify the per-CPU usage.



The fpu_recursion_depth counter is used to ensure that dc_fpu_begin()
can be invoked multiple times while the FPU-disable function itself is
only invoked once. Also the counter part (dc_fpu_end()) is ballanced
properly.

Instead of using the get_cpu_ptr() dance around the inc it is simpler to
increment the per-CPU variable directly. Also the per-CPU variable has
to be incremented and decremented on the same CPU. This is ensured by
the inner-part which disables preemption. This is kind of not obvious,
works and the preempt-counter is touched a few times for no reason.

Disable preemption before incrementing fpu_recursion_depth for the first
time. Keep preemption disabled until dc_fpu_end() where the counter is
decremented making it obvious that the preemption has to stay disabled
while the counter is non-zero.
Use simple inc/dec functions.
Remove the nested preempt_disable/enable functions which are now not
needed.

Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Reviewed-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9c77dcf6
Loading
Loading
Loading
Loading
+20 −30
Original line number Diff line number Diff line
@@ -60,11 +60,9 @@ static DEFINE_PER_CPU(int, fpu_recursion_depth);
 */
inline void dc_assert_fp_enabled(void)
{
	int *pcpu, depth = 0;
	int depth;

	pcpu = get_cpu_ptr(&fpu_recursion_depth);
	depth = *pcpu;
	put_cpu_ptr(&fpu_recursion_depth);
	depth = __this_cpu_read(fpu_recursion_depth);

	ASSERT(depth >= 1);
}
@@ -84,32 +82,27 @@ inline void dc_assert_fp_enabled(void)
 */
void dc_fpu_begin(const char *function_name, const int line)
{
	int *pcpu;
	int depth;

	pcpu = get_cpu_ptr(&fpu_recursion_depth);
	*pcpu += 1;
	preempt_disable();
	depth = __this_cpu_inc_return(fpu_recursion_depth);

	if (*pcpu == 1) {
	if (depth == 1) {
#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
		kernel_fpu_begin();
#elif defined(CONFIG_PPC64)
		if (cpu_has_feature(CPU_FTR_VSX_COMP)) {
			preempt_disable();
		if (cpu_has_feature(CPU_FTR_VSX_COMP))
			enable_kernel_vsx();
		} else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) {
			preempt_disable();
		else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP))
			enable_kernel_altivec();
		} else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) {
			preempt_disable();
		else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE))
			enable_kernel_fp();
		}
#elif defined(CONFIG_ARM64)
		kernel_neon_begin();
#endif
	}

	TRACE_DCN_FPU(true, function_name, line, *pcpu);
	put_cpu_ptr(&fpu_recursion_depth);
	TRACE_DCN_FPU(true, function_name, line, depth);
}

/**
@@ -124,29 +117,26 @@ void dc_fpu_begin(const char *function_name, const int line)
 */
void dc_fpu_end(const char *function_name, const int line)
{
	int *pcpu;
	int depth;

	pcpu = get_cpu_ptr(&fpu_recursion_depth);
	*pcpu -= 1;
	if (*pcpu <= 0) {
	depth = __this_cpu_dec_return(fpu_recursion_depth);
	if (depth == 0) {
#if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH)
		kernel_fpu_end();
#elif defined(CONFIG_PPC64)
		if (cpu_has_feature(CPU_FTR_VSX_COMP)) {
		if (cpu_has_feature(CPU_FTR_VSX_COMP))
			disable_kernel_vsx();
			preempt_enable();
		} else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) {
		else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP))
			disable_kernel_altivec();
			preempt_enable();
		} else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) {
		else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE))
			disable_kernel_fp();
			preempt_enable();
		}
#elif defined(CONFIG_ARM64)
		kernel_neon_end();
#endif
	} else {
		WARN_ON_ONCE(depth < 0);
	}

	TRACE_DCN_FPU(false, function_name, line, *pcpu);
	put_cpu_ptr(&fpu_recursion_depth);
	TRACE_DCN_FPU(false, function_name, line, depth);
	preempt_enable();
}