On 12/30/2024 9:30 PM, Rob Clark wrote:
> From: Rob Clark <robdcl...@chromium.org>
> 
> Debugging incorrect UAPI usage tends to be a bit painful, so add a
> helper macro to make it easier to add debug logging which can be enabled
> at runtime via drm.debug.
> 
> Signed-off-by: Rob Clark <robdcl...@chromium.org>
> ---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c | 21 ++++----
>  drivers/gpu/drm/msm/msm_drv.c           |  2 +-
>  drivers/gpu/drm/msm/msm_drv.h           |  7 +++
>  drivers/gpu/drm/msm/msm_gem_submit.c    | 64 +++++++++++--------------
>  drivers/gpu/drm/msm/msm_submitqueue.c   |  2 +-
>  5 files changed, 47 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index 076be0473eb5..9649c0bd0a38 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -310,10 +310,11 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
> msm_file_private *ctx,
>                    uint32_t param, uint64_t *value, uint32_t *len)
>  {
>       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
> +     struct drm_device *drm = gpu->dev;
>  
>       /* No pointer params yet */
>       if (*len != 0)
> -             return -EINVAL;
> +             return UERR(EINVAL, drm, "invalid len");
>  
>       switch (param) {
>       case MSM_PARAM_GPU_ID:
> @@ -365,12 +366,12 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
> msm_file_private *ctx,
>               return 0;
>       case MSM_PARAM_VA_START:
>               if (ctx->aspace == gpu->aspace)
> -                     return -EINVAL;
> +                     return UERR(EINVAL, drm, "requires per-process 
> pgtables");
>               *value = ctx->aspace->va_start;
>               return 0;
>       case MSM_PARAM_VA_SIZE:
>               if (ctx->aspace == gpu->aspace)
> -                     return -EINVAL;
> +                     return UERR(EINVAL, drm, "requires per-process 
> pgtables");
>               *value = ctx->aspace->va_size;
>               return 0;
>       case MSM_PARAM_HIGHEST_BANK_BIT:
> @@ -386,14 +387,15 @@ int adreno_get_param(struct msm_gpu *gpu, struct 
> msm_file_private *ctx,
>               *value = adreno_gpu->ubwc_config.macrotile_mode;
>               return 0;
>       default:
> -             DBG("%s: invalid param: %u", gpu->name, param);
> -             return -EINVAL;
> +             return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, 
> param);
>       }
>  }
>  
>  int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
>                    uint32_t param, uint64_t value, uint32_t len)
>  {
> +     struct drm_device *drm = gpu->dev;
> +
>       switch (param) {
>       case MSM_PARAM_COMM:
>       case MSM_PARAM_CMDLINE:
> @@ -401,11 +403,11 @@ int adreno_set_param(struct msm_gpu *gpu, struct 
> msm_file_private *ctx,
>                * that should be a reasonable upper bound
>                */
>               if (len > PAGE_SIZE)
> -                     return -EINVAL;
> +                     return UERR(EINVAL, drm, "invalid len");
>               break;
>       default:
>               if (len != 0)
> -                     return -EINVAL;
> +                     return UERR(EINVAL, drm, "invalid len");
>       }
>  
>       switch (param) {
> @@ -434,11 +436,10 @@ int adreno_set_param(struct msm_gpu *gpu, struct 
> msm_file_private *ctx,
>       }
>       case MSM_PARAM_SYSPROF:
>               if (!capable(CAP_SYS_ADMIN))
> -                     return -EPERM;
> +                     return UERR(EPERM, drm, "invalid permissions");
>               return msm_file_private_set_sysprof(ctx, gpu, value);
>       default:
> -             DBG("%s: invalid param: %u", gpu->name, param);
> -             return -EINVAL;
> +             return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, 
> param);
>       }
>  }
>  
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index c2dd8ef6d6dc..2aefb8becda0 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -538,7 +538,7 @@ static int msm_ioctl_gem_info_set_iova(struct drm_device 
> *dev,
>  
>       /* Only supported if per-process address space is supported: */
>       if (priv->gpu->aspace == ctx->aspace)
> -             return -EOPNOTSUPP;
> +             return UERR(EOPNOTSUPP, dev, "requires per-process pgtables");
>  
>       if (should_fail(&fail_gem_iova, obj->size))
>               return -ENOMEM;
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index d8c9a1b19263..fee31680a6d5 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -28,6 +28,7 @@
>  
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
> +#include <drm/drm_print.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/display/drm_dsc.h>
>  #include <drm/msm_drm.h>
> @@ -506,6 +507,12 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
>                          clockid_t clock_id,
>                          enum hrtimer_mode mode);
>  
> +/* Helper for returning a UABI error with optional logging which can make
> + * it easier for userspace to understand what it is doing wrong.
> + */
> +#define UERR(err, drm, fmt, ...) \
> +     ({ DRM_DEV_DEBUG_DRIVER((drm)->dev, fmt, ##__VA_ARGS__); -(err); })
> +
>  #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
>  #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
>  
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
> b/drivers/gpu/drm/msm/msm_gem_submit.c
> index fba78193127d..be6e793f34bd 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -20,8 +20,8 @@
>  /* For userspace errors, use DRM_UT_DRIVER.. so that userspace can enable
>   * error msgs for debugging, but we don't spam dmesg by default
>   */
> -#define SUBMIT_ERROR(submit, fmt, ...) \
> -     DRM_DEV_DEBUG_DRIVER((submit)->dev->dev, fmt, ##__VA_ARGS__)
> +#define SUBMIT_ERROR(err, submit, fmt, ...) \
> +     UERR(err, (submit)->dev, fmt, ##__VA_ARGS__)
>  
>  /*
>   * Cmdstream submission:
> @@ -142,8 +142,7 @@ static int submit_lookup_objects(struct msm_gem_submit 
> *submit,
>  
>               if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) ||
>                       !(submit_bo.flags & MANDATORY_FLAGS)) {
> -                     SUBMIT_ERROR(submit, "invalid flags: %x\n", 
> submit_bo.flags);
> -                     ret = -EINVAL;
> +                     ret = SUBMIT_ERROR(EINVAL, submit, "invalid flags: 
> %x\n", submit_bo.flags);
>                       i = 0;
>                       goto out;
>               }
> @@ -162,8 +161,7 @@ static int submit_lookup_objects(struct msm_gem_submit 
> *submit,
>                */
>               obj = idr_find(&file->object_idr, submit->bos[i].handle);
>               if (!obj) {
> -                     SUBMIT_ERROR(submit, "invalid handle %u at index %u\n", 
> submit->bos[i].handle, i);
> -                     ret = -EINVAL;
> +                     ret = SUBMIT_ERROR(EINVAL, submit, "invalid handle %u 
> at index %u\n", submit->bos[i].handle, i);
>                       goto out_unlock;
>               }
>  
> @@ -206,14 +204,12 @@ static int submit_lookup_cmds(struct msm_gem_submit 
> *submit,
>               case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
>                       break;
>               default:
> -                     SUBMIT_ERROR(submit, "invalid type: %08x\n", 
> submit_cmd.type);
> -                     return -EINVAL;
> +                     return SUBMIT_ERROR(EINVAL, submit, "invalid type: 
> %08x\n", submit_cmd.type);
>               }
>  
>               if (submit_cmd.size % 4) {
> -                     SUBMIT_ERROR(submit, "non-aligned cmdstream buffer 
> size: %u\n",
> -                                  submit_cmd.size);
> -                     ret = -EINVAL;
> +                     ret = SUBMIT_ERROR(EINVAL, submit, "non-aligned 
> cmdstream buffer size: %u\n",
> +                                        submit_cmd.size);
>                       goto out;
>               }
>  
> @@ -371,9 +367,8 @@ static int submit_bo(struct msm_gem_submit *submit, 
> uint32_t idx,
>               struct drm_gem_object **obj, uint64_t *iova)
>  {
>       if (idx >= submit->nr_bos) {
> -             SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n",
> -                          idx, submit->nr_bos);
> -             return -EINVAL;
> +             return SUBMIT_ERROR(EINVAL, submit, "invalid buffer index: %u 
> (out of %u)\n",
> +                                 idx, submit->nr_bos);
>       }
>  
>       if (obj)
> @@ -392,10 +387,8 @@ static int submit_reloc(struct msm_gem_submit *submit, 
> struct drm_gem_object *ob
>       uint32_t *ptr;
>       int ret = 0;
>  
> -     if (offset % 4) {
> -             SUBMIT_ERROR(submit, "non-aligned cmdstream buffer: %u\n", 
> offset);
> -             return -EINVAL;
> -     }
> +     if (offset % 4)
> +             return SUBMIT_ERROR(EINVAL, submit, "non-aligned cmdstream 
> buffer: %u\n", offset);
>  
>       /* For now, just map the entire thing.  Eventually we probably
>        * to do it page-by-page, w/ kmap() if not vmap()d..
> @@ -414,9 +407,8 @@ static int submit_reloc(struct msm_gem_submit *submit, 
> struct drm_gem_object *ob
>               uint64_t iova;
>  
>               if (submit_reloc.submit_offset % 4) {
> -                     SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n",
> -                                  submit_reloc.submit_offset);
> -                     ret = -EINVAL;
> +                     ret = SUBMIT_ERROR(EINVAL, submit, "non-aligned reloc 
> offset: %u\n",
> +                                        submit_reloc.submit_offset);
>                       goto out;
>               }
>  
> @@ -425,8 +417,7 @@ static int submit_reloc(struct msm_gem_submit *submit, 
> struct drm_gem_object *ob
>  
>               if ((off >= (obj->size / 4)) ||
>                               (off < last_offset)) {
> -                     SUBMIT_ERROR(submit, "invalid offset %u at reloc %u\n", 
> off, i);
> -                     ret = -EINVAL;
> +                     ret = SUBMIT_ERROR(EINVAL, submit, "invalid offset %u 
> at reloc %u\n", off, i);
>                       goto out;
>               }
>  
> @@ -513,12 +504,12 @@ static struct drm_syncobj **msm_parse_deps(struct 
> msm_gem_submit *submit,
>  
>               if (syncobj_desc.point &&
>                   !drm_core_check_feature(submit->dev, 
> DRIVER_SYNCOBJ_TIMELINE)) {
> -                     ret = -EOPNOTSUPP;
> +                     ret = SUBMIT_ERROR(EOPNOTSUPP, submit, "syncobj 
> timeline unsupported");
>                       break;
>               }
>  
>               if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) {
> -                     ret = -EINVAL;
> +                     ret = -SUBMIT_ERROR(EINVAL, submit, "invalid syncobj 
> flags");
>                       break;
>               }
>  
> @@ -531,7 +522,7 @@ static struct drm_syncobj **msm_parse_deps(struct 
> msm_gem_submit *submit,
>                       syncobjs[i] =
>                               drm_syncobj_find(file, syncobj_desc.handle);
>                       if (!syncobjs[i]) {
> -                             ret = -EINVAL;
> +                             ret = SUBMIT_ERROR(EINVAL, submit, "invalid 
> syncobj handle");

Just to be more useful, probably we can print the index or the handle
here. Anyway

Reviewed-by: Akhil P Oommen <quic_akhi...@quicinc.com>


-Akhil.


Reply via email to