FAILED: patch "[PATCH] drm/panfrost: Make sure MMU context lifetime is not bound to" failed to apply to 5.4-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7fdc48cc63a30fa3480d18bdd8c5fff2b9b15212 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <[email protected]>
Date: Mon, 21 Jun 2021 15:38:56 +0200
Subject: [PATCH] drm/panfrost: Make sure MMU context lifetime is not bound to
panfrost_priv
Jobs can be in-flight when the file descriptor is closed (either because the process did not terminate properly, or because it didn't wait for all GPU jobs to be finished), and apparently panfrost_job_close() does not cancel already running jobs. Let's refcount the MMU context object so it's lifetime is no longer bound to the FD lifetime and running jobs can finish properly without generating spurious page faults.
drivers/gpu/drm/panfrost/panfrost_device.h +5 -3
@@ -121,8 +121,12 @@ struct panfrost_device { };struct panfrost_mmu { +struct panfrost_device *pfdev; +struct kref refcount;struct io_pgtable_cfg pgtbl_cfg;struct io_pgtable_ops *pgtbl_ops; +struct drm_mm mm; +spinlock_t mm_lock;int as;atomic_t as_count;struct list_head list;
@@ -133,9 +137,7 @@ struct panfrost_file_priv {struct drm_sched_entity sched_entity[NUM_JOB_SLOTS ]; -struct panfrost_mmu mmu; -struct drm_mm mm; -spinlock_t mm_lock; +struct panfrost_mmu *mmu; };static inline struct panfrost_device *to_panfrost_device (struct drm_device *ddev)
drivers/gpu/drm/panfrost/panfrost_drv.c +9 -41
80 lines not on this page · raw message
drivers/gpu/drm/panfrost/panfrost_gem.c +9 -11
@@ -60,7 +60,7 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo,mutex_lock (&bo->mappings.lock);list_for_each_entry (iter, &bo->mappings.list, node) { -if (iter->mmu == &priv->mmu) { +if (iter->mmu == priv->mmu) {kref_get (&iter->refcount); mapping = iter;break ;
@@ -74,16 +74,13 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo,static void panfrost_gem_teardown_mapping (struct panfrost_gem_mapping *mapping) { -struct panfrost_file_priv *priv; -if (mapping->active)panfrost_mmu_unmap (mapping); - priv = container_of(mapping->mmu, struct panfrost_file_priv, mmu); -spin_lock (&priv->mm_lock); +spin_lock (&mapping->mmu->mm_lock);if (drm_mm_node_allocated (&mapping->mmnode))drm_mm_remove_node (&mapping->mmnode); -spin_unlock (&priv->mm_lock); +spin_unlock (&mapping->mmu->mm_lock); }static void panfrost_gem_mapping_release (struct kref *kref)
@@ -94,6 +91,7 @@ static void panfrost_gem_mapping_release(struct kref *kref)panfrost_gem_teardown_mapping (mapping);drm_gem_object_put (&mapping->obj->base.base); +panfrost_mmu_ctx_put (mapping->mmu);kfree (mapping); }
@@ -143,11 +141,11 @@ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)else align = size >=SZ_2M ?SZ_2M >>PAGE_SHIFT :0 ; - mapping->mmu = &priv->mmu; -spin_lock (&priv->mm_lock); - ret =drm_mm_insert_node_generic (&priv->mm, &mapping->mmnode, + mapping->mmu =panfrost_mmu_ctx_get (priv->mmu); +spin_lock (&mapping->mmu->mm_lock); + ret =drm_mm_insert_node_generic (&mapping->mmu->mm, &mapping->mmnode, size >>PAGE_SHIFT , align, color,0 ); -spin_unlock (&priv->mm_lock); +spin_unlock (&mapping->mmu->mm_lock);if (ret) goto err;
@@ -176,7 +174,7 @@ void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)mutex_lock (&bo->mappings.lock);list_for_each_entry (iter, &bo->mappings.list, node) { -if (iter->mmu == &priv->mmu) { +if (iter->mmu == priv->mmu) { mapping = iter;list_del (&iter->node);break ;
drivers/gpu/drm/panfrost/panfrost_job.c +2 -2
@@ -165,7 +165,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)return ; } - cfg =panfrost_mmu_as_get (pfdev, &job->file_priv->mmu); + cfg =panfrost_mmu_as_get (pfdev, job->file_priv->mmu);job_write (pfdev,JS_HEAD_NEXT_LO (js), jc_head &0xFFFFFFFF );job_write (pfdev,JS_HEAD_NEXT_HI (js), jc_head >>32 );
@@ -516,7 +516,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data)if (job) { pfdev->jobs[j] =NULL ; -panfrost_mmu_as_put (pfdev, &job->file_priv->mmu); +panfrost_mmu_as_put (pfdev, job->file_priv->mmu);panfrost_devfreq_record_idle (&pfdev->pfdevfreq);dma_fence_signal_locked (job->done_fence);
drivers/gpu/drm/panfrost/panfrost_mmu.c +108 -52
201 lines not on this page · raw message
drivers/gpu/drm/panfrost/panfrost_mmu.h +3 -2
@@ -18,7 +18,8 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev);u32 panfrost_mmu_as_get (struct panfrost_device *pfdev,struct panfrost_mmu *mmu);void panfrost_mmu_as_put (struct panfrost_device *pfdev,struct panfrost_mmu *mmu); -int panfrost_mmu_pgtable_alloc (struct panfrost_file_priv *priv); -void panfrost_mmu_pgtable_free (struct panfrost_file_priv *priv); +struct panfrost_mmu *panfrost_mmu_ctx_get (struct panfrost_mmu *mmu); +void panfrost_mmu_ctx_put (struct panfrost_mmu *mmu); +struct panfrost_mmu *panfrost_mmu_ctx_create (struct panfrost_device *pfdev);#endif