drm/msm/gpu: Add submit queue queries
authorJordan Crouse <jcrouse@codeaurora.org>
Fri, 22 Mar 2019 20:21:22 +0000 (14:21 -0600)
committerRob Clark <robdclark@chromium.org>
Fri, 19 Apr 2019 18:50:06 +0000 (11:50 -0700)
Add the capability to query information from a submit queue.
The first available parameter is for querying the number of GPU faults
(hangs) that can be attributed to the queue.

This is useful for implementing context robustness. A user context can
regularly query the number of faults to see if it is responsible for any
and if so it can invalidate itself.

This is also helpful for testing by confirming to the user  driver if a
particular command stream caused a fault (or not as the case may be).

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_submitqueue.c
include/uapi/drm/msm_drm.h

index 0bdd93648761d634a48150fc594d0a3008720913..37f18b55d11f8bacd1a2a358623231cb2a3ec1e4 100644 (file)
  *           MSM_GEM_INFO ioctl.
  * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
  *           GEM object's debug name
+ * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
  */
 #define MSM_VERSION_MAJOR      1
-#define MSM_VERSION_MINOR      4
+#define MSM_VERSION_MINOR      5
 #define MSM_VERSION_PATCHLEVEL 0
 
 static const struct drm_mode_config_funcs mode_config_funcs = {
@@ -964,6 +965,11 @@ static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data,
                args->flags, &args->id);
 }
 
+static int msm_ioctl_submitqueue_query(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       return msm_submitqueue_query(dev, file->driver_priv, data);
+}
 
 static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data,
                struct drm_file *file)
@@ -984,6 +990,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
        DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE,  msm_ioctl_gem_madvise,  DRM_AUTH|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   DRM_AUTH|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_AUTH|DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_AUTH|DRM_RENDER_ALLOW),
 };
 
 static const struct vm_operations_struct vm_ops = {
index c56dade2c1dca01f3f819119a64be221ec2539a8..f09d12ddb3ac3c6edeba6c0d74100919f66eb987 100644 (file)
@@ -420,6 +420,8 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
                u32 id);
 int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
                u32 prio, u32 flags, u32 *id);
+int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
+               struct drm_msm_submitqueue_query *args);
 int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
 void msm_submitqueue_close(struct msm_file_private *ctx);
 
index 194847a220b61b9dec0b23d4449574516866e1cd..2b76657badd5765ecfd15754580119e74389b8b3 100644 (file)
@@ -443,8 +443,9 @@ static void recover_worker(struct work_struct *work)
        if (submit) {
                struct task_struct *task;
 
-               /* Increment the fault count */
+               /* Increment the fault counts */
                gpu->global_faults++;
+               submit->queue->faults++;
 
                task = get_pid_task(submit->pid, PIDTYPE_PID);
                if (task) {
index 5115f75b5b7f38c5d1ce81fa5edf38525331dbf4..f160ec40a39b5836d176c4640ed497b58401c9f6 100644 (file)
@@ -120,6 +120,47 @@ int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx)
        return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL);
 }
 
+static int msm_submitqueue_query_faults(struct msm_gpu_submitqueue *queue,
+               struct drm_msm_submitqueue_query *args)
+{
+       size_t size = min_t(size_t, args->len, sizeof(queue->faults));
+       int ret;
+
+       /* If a zero length was passed in, return the data size we expect */
+       if (!args->len) {
+               args->len = sizeof(queue->faults);
+               return 0;
+       }
+
+       /* Set the length to the actual size of the data */
+       args->len = size;
+
+       ret = copy_to_user(u64_to_user_ptr(args->data), &queue->faults, size);
+
+       return ret ? -EFAULT : 0;
+}
+
+int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
+               struct drm_msm_submitqueue_query *args)
+{
+       struct msm_gpu_submitqueue *queue;
+       int ret = -EINVAL;
+
+       if (args->pad)
+               return -EINVAL;
+
+       queue = msm_submitqueue_get(ctx, args->id);
+       if (!queue)
+               return -ENOENT;
+
+       if (args->param == MSM_SUBMITQUEUE_PARAM_FAULTS)
+               ret = msm_submitqueue_query_faults(queue, args);
+
+       msm_submitqueue_put(queue);
+
+       return ret;
+}
+
 int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id)
 {
        struct msm_gpu_submitqueue *entry;
index 178d7b407f3a37a5a3ccc2e7fa6abd88b4f0d1fe..0b85ed6a3710fa9f6748d78c1dc80dfcae77c00b 100644 (file)
@@ -288,6 +288,16 @@ struct drm_msm_submitqueue {
        __u32 id;      /* out, identifier */
 };
 
+#define MSM_SUBMITQUEUE_PARAM_FAULTS   0
+
+struct drm_msm_submitqueue_query {
+       __u64 data;
+       __u32 id;
+       __u32 param;
+       __u32 len;
+       __u32 pad;
+};
+
 #define DRM_MSM_GET_PARAM              0x00
 /* placeholder:
 #define DRM_MSM_SET_PARAM              0x01
@@ -304,6 +314,7 @@ struct drm_msm_submitqueue {
  */
 #define DRM_MSM_SUBMITQUEUE_NEW        0x0A
 #define DRM_MSM_SUBMITQUEUE_CLOSE      0x0B
+#define DRM_MSM_SUBMITQUEUE_QUERY      0x0C
 
 #define DRM_IOCTL_MSM_GET_PARAM        DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
 #define DRM_IOCTL_MSM_GEM_NEW          DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
@@ -315,6 +326,7 @@ struct drm_msm_submitqueue {
 #define DRM_IOCTL_MSM_GEM_MADVISE      DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
 #define DRM_IOCTL_MSM_SUBMITQUEUE_NEW    DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
 #define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_QUERY  DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_QUERY, struct drm_msm_submitqueue_query)
 
 #if defined(__cplusplus)
 }