[Intel-xe] [RFC PATCH v2 1/3] drm/xe: Introduce function pointers in xe_gt.c with local structure
Jani Nikula
jani.nikula at linux.intel.com
Wed Mar 15 09:52:23 UTC 2023
On Tue, 14 Mar 2023, Francois Dugast <francois.dugast at intel.com> wrote:
> A local structure of function pointers is used as a minimal
> hardware abstraction layer to split between common and platform
> specific code. This structure is initialized once with the
> functions matching the platform, then it is used in the common
> code with no need for switch or if/else to detect the platform.
> For now only the function setup_private_ppat() is refactored.
>
> Signed-off-by: Francois Dugast <francois.dugast at intel.com>
> ---
> drivers/gpu/drm/xe/xe_device_types.h | 1 +
> drivers/gpu/drm/xe/xe_gt.c | 46 +++++++++++++++++++---------
> 2 files changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
> index 034e0956f4ea..411e7a62d28a 100644
> --- a/drivers/gpu/drm/xe/xe_device_types.h
> +++ b/drivers/gpu/drm/xe/xe_device_types.h
> @@ -311,6 +311,7 @@ struct xe_device {
> u32 lvds_channel_mode;
> } params;
> #endif
> + struct xe_gt_platform_funcs *gt_funcs;
IMO this should be a const pointer.
> };
>
> /**
> diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
> index daa433d0f2f5..3b092f951378 100644
> --- a/drivers/gpu/drm/xe/xe_gt.c
> +++ b/drivers/gpu/drm/xe/xe_gt.c
> @@ -42,6 +42,10 @@
> #include "xe_wa.h"
> #include "xe_wopcm.h"
>
> +struct xe_gt_platform_funcs {
> + void (*setup_private_ppat)(struct xe_gt *gt);
> +};
> +
> struct xe_gt *xe_find_full_gt(struct xe_gt *gt)
> {
> struct xe_gt *search;
> @@ -157,18 +161,6 @@ static void mtl_setup_private_ppat(struct xe_gt *gt)
> MTL_PPAT_0_WB | MTL_3_COH_2W);
> }
>
> -static void setup_private_ppat(struct xe_gt *gt)
> -{
> - struct xe_device *xe = gt_to_xe(gt);
> -
> - if (xe->info.platform == XE_METEORLAKE)
> - mtl_setup_private_ppat(gt);
> - else if (xe->info.platform == XE_PVC)
> - pvc_setup_private_ppat(gt);
> - else
> - tgl_setup_private_ppat(gt);
> -}
IMO keep this as a wrapper that calls the function pointer.
> -
> static int gt_ttm_mgr_init(struct xe_gt *gt)
> {
> struct xe_device *xe = gt_to_xe(gt);
> @@ -380,6 +372,28 @@ int xe_gt_record_default_lrcs(struct xe_gt *gt)
> int xe_gt_init_early(struct xe_gt *gt)
> {
> int err;
> + struct xe_device *xe = gt_to_xe(gt);
> +
> + xe->gt_funcs = kzalloc(sizeof(*xe->gt_funcs), GFP_KERNEL);
> + switch (xe->info.platform) {
> + case XE_METEORLAKE:
> + xe->gt_funcs->setup_private_ppat = mtl_setup_private_ppat;
> + break;
> + case XE_PVC:
> + xe->gt_funcs->setup_private_ppat = pvc_setup_private_ppat;
> + break;
> + case XE_ROCKETLAKE:
> + case XE_DG1:
> + case XE_DG2:
> + case XE_ALDERLAKE_S:
> + case XE_ALDERLAKE_P:
> + case XE_TIGERLAKE:
> + xe->gt_funcs->setup_private_ppat = tgl_setup_private_ppat;
> + break;
> + default:
> + DRM_ERROR("Unsupported platform\n");
> + break;
> + }
IMO you should always aim to have static const initialized structs with
the function pointers, assign the const pointer to the struct, and avoid
assigning individual function pointers members.
It's a bad practise to allocate the function pointer struct.
>
> xe_force_wake_init_gt(gt, gt_to_fw(gt));
>
> @@ -441,13 +455,15 @@ int xe_gt_init_noalloc(struct xe_gt *gt)
> static int gt_fw_domain_init(struct xe_gt *gt)
> {
> int err, i;
> + struct xe_device *xe = gt_to_xe(gt);
>
> xe_device_mem_access_get(gt_to_xe(gt));
> err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
> if (err)
> goto err_hw_fence_irq;
>
> - setup_private_ppat(gt);
> + if (xe->gt_funcs->setup_private_ppat)
> + xe->gt_funcs->setup_private_ppat(gt);
IME it's better to keep functions like setup_private_ppat() as wrappers
to the function calls. The caller does not need to know the
implementation details i.e. whether it's a function pointer or not.
BR,
Jani.
>
> if (!xe_gt_is_media_type(gt)) {
> err = xe_ggtt_init(gt, gt->mem.ggtt);
> @@ -630,8 +646,10 @@ static int do_gt_restart(struct xe_gt *gt)
> struct xe_hw_engine *hwe;
> enum xe_hw_engine_id id;
> int err;
> + struct xe_device *xe = gt_to_xe(gt);
>
> - setup_private_ppat(gt);
> + if (xe->gt_funcs->setup_private_ppat)
> + xe->gt_funcs->setup_private_ppat(gt);
>
> xe_gt_mcr_set_implicit_defaults(gt);
> xe_reg_sr_apply_mmio(>->reg_sr, gt);
--
Jani Nikula, Intel Open Source Graphics Center
More information about the Intel-xe
mailing list