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

drm/amd/display: Add DC_FP helper to check FPU state

To fully isolate FPU operations in a single place, we must avoid
situations where compilers spill FP values to registers due to FP enable
in a specific C file. Note that even if we isolate all FPU functions in
a single file and call its interface from other files, the compiler
might enable the use of FPU before we call DC_FP_START. Nevertheless, it
is the programmer's responsibility to invoke DC_FP_START/END in the
correct place. To highlight situations where developers forgot to use
the FP protection before calling the DC FPU interface functions, we
introduce a helper that checks if the function is invoked under FP
protection. If not, it will trigger a kernel warning.

Changes cince V3:
- Rebase

Changes cince V2 (Christian):
- Do not use this_cpu_* between get/put_cpu_ptr().
- In the kernel documentation, better describe restrictions.
- Make dc_assert_fp_enabled trigger the ASSERT message.

Changes since V1:
- Remove fp_enable variables
- Rename dc_is_fp_enabled to dc_assert_fp_enabled
- Replace wrong variable type

Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Anson Jacob <Anson.Jacob@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Hersen Wu <hersenxs.wu@amd.com>
Cc: Aric Cyr <aric.cyr@amd.com>
Cc: Jun Lei <jun.lei@amd.com>
Cc: Dmytro Laktyushkin <dmytro.laktyushkin@amd.com>
Cc: Qingqing Zhuo <qingqing.zhuo@amd.com>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Rodrigo Siqueira and committed by
Alex Deucher
0ea7ee82 2d8471dc

+40
+19
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c
··· 47 47 static DEFINE_PER_CPU(int, fpu_recursion_depth); 48 48 49 49 /** 50 + * dc_assert_fp_enabled - Check if FPU protection is enabled 51 + * 52 + * This function tells if the code is already under FPU protection or not. A 53 + * function that works as an API for a set of FPU operations can use this 54 + * function for checking if the caller invoked it after DC_FP_START(). For 55 + * example, take a look at dcn2x.c file. 56 + */ 57 + inline void dc_assert_fp_enabled(void) 58 + { 59 + int *pcpu, depth = 0; 60 + 61 + pcpu = get_cpu_ptr(&fpu_recursion_depth); 62 + depth = *pcpu; 63 + put_cpu_ptr(&fpu_recursion_depth); 64 + 65 + ASSERT(depth > 1); 66 + } 67 + 68 + /** 50 69 * dc_fpu_begin - Enables FPU protection 51 70 * @function_name: A string containing the function name for debug purposes 52 71 * (usually __func__)
+1
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.h
··· 27 27 #ifndef __DC_FPU_H__ 28 28 #define __DC_FPU_H__ 29 29 30 + void dc_assert_fp_enabled(void); 30 31 void dc_fpu_begin(const char *function_name, const int line); 31 32 void dc_fpu_end(const char *function_name, const int line); 32 33
+2
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
··· 2357 2357 } 2358 2358 2359 2359 /* populate writeback information */ 2360 + DC_FP_START(); 2360 2361 dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes); 2362 + DC_FP_END(); 2361 2363 2362 2364 return pipe_cnt; 2363 2365 }
+18
drivers/gpu/drm/amd/display/dc/dml/dcn2x/dcn2x.c
··· 43 43 * that deals with FP register is contained within this call. 44 44 * 3. All function that needs to be accessed outside this file requires a 45 45 * public interface that not uses any FPU reference. 46 + * 4. Developers **must not** use DC_FP_START/END in this file, but they need 47 + * to ensure that the caller invokes it before access any function available 48 + * in this file. For this reason, public functions in this file must invoke 49 + * dc_assert_fp_enabled(); 50 + * 51 + * Let's expand a little bit more the idea in the code pattern. To fully 52 + * isolate FPU operations in a single place, we must avoid situations where 53 + * compilers spill FP values to registers due to FP enable in a specific C 54 + * file. Note that even if we isolate all FPU functions in a single file and 55 + * call its interface from other files, the compiler might enable the use of 56 + * FPU before we call DC_FP_START. Nevertheless, it is the programmer's 57 + * responsibility to invoke DC_FP_START/END in the correct place. To highlight 58 + * situations where developers forgot to use the FP protection before calling 59 + * the DC FPU interface functions, we introduce a helper that checks if the 60 + * function is invoked under FP protection. If not, it will trigger a kernel 61 + * warning. 46 62 */ 47 63 48 64 void dcn20_populate_dml_writeback_from_context(struct dc *dc, ··· 66 50 display_e2e_pipe_params_st *pipes) 67 51 { 68 52 int pipe_cnt, i; 53 + 54 + dc_assert_fp_enabled(); 69 55 70 56 for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) { 71 57 struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];