Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Sebastian Andrzej Siewior and committed by
Alex Deucher
de5e73dc 9c77dcf6

+20 -30
+20 -30
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c
··· 60 60 */ 61 61 inline void dc_assert_fp_enabled(void) 62 62 { 63 - int *pcpu, depth = 0; 63 + int depth; 64 64 65 - pcpu = get_cpu_ptr(&fpu_recursion_depth); 66 - depth = *pcpu; 67 - put_cpu_ptr(&fpu_recursion_depth); 65 + depth = __this_cpu_read(fpu_recursion_depth); 68 66 69 67 ASSERT(depth >= 1); 70 68 } ··· 82 84 */ 83 85 void dc_fpu_begin(const char *function_name, const int line) 84 86 { 85 - int *pcpu; 87 + int depth; 86 88 87 - pcpu = get_cpu_ptr(&fpu_recursion_depth); 88 - *pcpu += 1; 89 + preempt_disable(); 90 + depth = __this_cpu_inc_return(fpu_recursion_depth); 89 91 90 - if (*pcpu == 1) { 92 + if (depth == 1) { 91 93 #if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) 92 94 kernel_fpu_begin(); 93 95 #elif defined(CONFIG_PPC64) 94 - if (cpu_has_feature(CPU_FTR_VSX_COMP)) { 95 - preempt_disable(); 96 + if (cpu_has_feature(CPU_FTR_VSX_COMP)) 96 97 enable_kernel_vsx(); 97 - } else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) { 98 - preempt_disable(); 98 + else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) 99 99 enable_kernel_altivec(); 100 - } else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) { 101 - preempt_disable(); 100 + else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) 102 101 enable_kernel_fp(); 103 - } 104 102 #elif defined(CONFIG_ARM64) 105 103 kernel_neon_begin(); 106 104 #endif 107 105 } 108 106 109 - TRACE_DCN_FPU(true, function_name, line, *pcpu); 110 - put_cpu_ptr(&fpu_recursion_depth); 107 + TRACE_DCN_FPU(true, function_name, line, depth); 111 108 } 112 109 113 110 /** ··· 117 124 */ 118 125 void dc_fpu_end(const char *function_name, const int line) 119 126 { 120 - int *pcpu; 127 + int depth; 121 128 122 - pcpu = get_cpu_ptr(&fpu_recursion_depth); 123 - *pcpu -= 1; 124 - if (*pcpu <= 0) { 129 + depth = __this_cpu_dec_return(fpu_recursion_depth); 130 + if (depth == 0) { 125 131 #if defined(CONFIG_X86) || defined(CONFIG_LOONGARCH) 126 132 kernel_fpu_end(); 127 133 #elif defined(CONFIG_PPC64) 128 - if (cpu_has_feature(CPU_FTR_VSX_COMP)) { 134 + if (cpu_has_feature(CPU_FTR_VSX_COMP)) 129 135 disable_kernel_vsx(); 130 - preempt_enable(); 131 - } else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) { 136 + else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) 132 137 disable_kernel_altivec(); 133 - preempt_enable(); 134 - } else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) { 138 + else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) 135 139 disable_kernel_fp(); 136 - preempt_enable(); 137 - } 138 140 #elif defined(CONFIG_ARM64) 139 141 kernel_neon_end(); 140 142 #endif 143 + } else { 144 + WARN_ON_ONCE(depth < 0); 141 145 } 142 146 143 - TRACE_DCN_FPU(false, function_name, line, *pcpu); 144 - put_cpu_ptr(&fpu_recursion_depth); 147 + TRACE_DCN_FPU(false, function_name, line, depth); 148 + preempt_enable(); 145 149 }