]> Git Repo - linux.git/commitdiff
Merge tag 'drm-msm-fixes-2023-01-16' of https://gitlab.freedesktop.org/drm/msm into...
authorDave Airlie <[email protected]>
Thu, 19 Jan 2023 21:49:00 +0000 (07:49 +1000)
committerDave Airlie <[email protected]>
Thu, 19 Jan 2023 21:49:01 +0000 (07:49 +1000)
msm-fixes for v6.3-rc5

Two GPU fixes which were meant to be part of the previous pull request,
but I'd forgotten to fetch from gitlab after the MR was merged so that
git tag was applied to the wrong commit.

- kexec shutdown fix
- fix potential double free

Signed-off-by: Dave Airlie <[email protected]>
From: Rob Clark <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGskguoVsz2wqAK2k+f32LwcVY5JC6+e2RwLqZswz3RY2Q@mail.gmail.com
1  2 
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_gpu.h

index 30ed45af76ade1de740a1f3bfcc7f00bd09b619e,4f495eecc34badc004a238fcb7ad6b3defd5fe00..3802495003258a1258650a2c73c1a0572283dfc6
@@@ -335,6 -335,8 +335,8 @@@ static void get_comm_cmdline(struct msm
        struct msm_file_private *ctx = submit->queue->ctx;
        struct task_struct *task;
  
+       WARN_ON(!mutex_is_locked(&submit->gpu->lock));
        /* Note that kstrdup will return NULL if argument is NULL: */
        *comm = kstrdup(ctx->comm, GFP_KERNEL);
        *cmd  = kstrdup(ctx->cmdline, GFP_KERNEL);
@@@ -492,21 -494,6 +494,21 @@@ static void hangcheck_timer_reset(struc
                        round_jiffies_up(jiffies + msecs_to_jiffies(priv->hangcheck_period)));
  }
  
 +static bool made_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
 +{
 +      if (ring->hangcheck_progress_retries >= DRM_MSM_HANGCHECK_PROGRESS_RETRIES)
 +              return false;
 +
 +      if (!gpu->funcs->progress)
 +              return false;
 +
 +      if (!gpu->funcs->progress(gpu, ring))
 +              return false;
 +
 +      ring->hangcheck_progress_retries++;
 +      return true;
 +}
 +
  static void hangcheck_handler(struct timer_list *t)
  {
        struct msm_gpu *gpu = from_timer(gpu, t, hangcheck_timer);
        if (fence != ring->hangcheck_fence) {
                /* some progress has been made.. ya! */
                ring->hangcheck_fence = fence;
 -      } else if (fence_before(fence, ring->fctx->last_fence)) {
 +              ring->hangcheck_progress_retries = 0;
 +      } else if (fence_before(fence, ring->fctx->last_fence) &&
 +                      !made_progress(gpu, ring)) {
                /* no progress and not done.. hung! */
                ring->hangcheck_fence = fence;
 +              ring->hangcheck_progress_retries = 0;
                DRM_DEV_ERROR(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n",
                                gpu->name, ring->id);
                DRM_DEV_ERROR(dev->dev, "%s:     completed fence: %u\n",
@@@ -848,7 -832,6 +850,7 @@@ int msm_gpu_init(struct drm_device *drm
                struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
                const char *name, struct msm_gpu_config *config)
  {
 +      struct msm_drm_private *priv = drm->dev_private;
        int i, ret, nr_rings = config->nr_rings;
        void *memptrs;
        uint64_t memptrs_iova;
        kthread_init_work(&gpu->recover_work, recover_worker);
        kthread_init_work(&gpu->fault_work, fault_worker);
  
 +      priv->hangcheck_period = DRM_MSM_HANGCHECK_DEFAULT_PERIOD;
 +
 +      /*
 +       * If progress detection is supported, halve the hangcheck timer
 +       * duration, as it takes two iterations of the hangcheck handler
 +       * to detect a hang.
 +       */
 +      if (funcs->progress)
 +              priv->hangcheck_period /= 2;
 +
        timer_setup(&gpu->hangcheck_timer, hangcheck_handler, 0);
  
        spin_lock_init(&gpu->perf_lock);
index 651786bc55e5a8a989a882840ac62857f1f41017,a89bfdc3d7f90f5db182c60aa91cdf28345baa01..732295e2568345f1fc5a6d4e62da647e186ce104
@@@ -78,15 -78,6 +78,15 @@@ struct msm_gpu_funcs 
        struct msm_gem_address_space *(*create_private_address_space)
                (struct msm_gpu *gpu);
        uint32_t (*get_rptr)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 +
 +      /**
 +       * progress: Has the GPU made progress?
 +       *
 +       * Return true if GPU position in cmdstream has advanced (or changed)
 +       * since the last call.  To avoid false negatives, this should account
 +       * for cmdstream that is buffered in this FIFO upstream of the CP fw.
 +       */
 +      bool (*progress)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
  };
  
  /* Additional state for iommu faults: */
@@@ -246,7 -237,6 +246,7 @@@ struct msm_gpu 
  #define DRM_MSM_INACTIVE_PERIOD   66 /* in ms (roughly four frames) */
  
  #define DRM_MSM_HANGCHECK_DEFAULT_PERIOD 500 /* in ms */
 +#define DRM_MSM_HANGCHECK_PROGRESS_RETRIES 3
        struct timer_list hangcheck_timer;
  
        /* Fault info for most recent iova fault: */
@@@ -376,10 -366,18 +376,18 @@@ struct msm_file_private 
         */
        int sysprof;
  
-       /** comm: Overridden task comm, see MSM_PARAM_COMM */
+       /**
+        * comm: Overridden task comm, see MSM_PARAM_COMM
+        *
+        * Accessed under msm_gpu::lock
+        */
        char *comm;
  
-       /** cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE */
+       /**
+        * cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE
+        *
+        * Accessed under msm_gpu::lock
+        */
        char *cmdline;
  
        /**
@@@ -550,7 -548,7 +558,7 @@@ static inline void gpu_rmw(struct msm_g
        msm_rmw(gpu->mmio + (reg << 2), mask, or);
  }
  
 -static inline u64 gpu_read64(struct msm_gpu *gpu, u32 lo, u32 hi)
 +static inline u64 gpu_read64(struct msm_gpu *gpu, u32 reg)
  {
        u64 val;
  
         * when the lo is read, so make sure to read the lo first to trigger
         * that
         */
 -      val = (u64) msm_readl(gpu->mmio + (lo << 2));
 -      val |= ((u64) msm_readl(gpu->mmio + (hi << 2)) << 32);
 +      val = (u64) msm_readl(gpu->mmio + (reg << 2));
 +      val |= ((u64) msm_readl(gpu->mmio + ((reg + 1) << 2)) << 32);
  
        return val;
  }
  
 -static inline void gpu_write64(struct msm_gpu *gpu, u32 lo, u32 hi, u64 val)
 +static inline void gpu_write64(struct msm_gpu *gpu, u32 reg, u64 val)
  {
        /* Why not a writeq here? Read the screed above */
 -      msm_writel(lower_32_bits(val), gpu->mmio + (lo << 2));
 -      msm_writel(upper_32_bits(val), gpu->mmio + (hi << 2));
 +      msm_writel(lower_32_bits(val), gpu->mmio + (reg << 2));
 +      msm_writel(upper_32_bits(val), gpu->mmio + ((reg + 1) << 2));
  }
  
  int msm_gpu_pm_suspend(struct msm_gpu *gpu);
This page took 0.058846 seconds and 4 git commands to generate.