Message ID | 20220314224253.236359-9-dmitry.osipenko@collabora.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add memory shrinker to VirtIO-GPU DRM driver | expand |
On Tue, Mar 15, 2022 at 01:42:53AM +0300, Dmitry Osipenko wrote: > Replace Panfrost's memory shrinker with a generic DRM memory shrinker. > > Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> > --- > drivers/gpu/drm/panfrost/Makefile | 1 - > drivers/gpu/drm/panfrost/panfrost_device.h | 4 ---- > drivers/gpu/drm/panfrost/panfrost_drv.c | 19 ++------------- > drivers/gpu/drm/panfrost/panfrost_gem.c | 27 ++++++++++++++-------- > drivers/gpu/drm/panfrost/panfrost_gem.h | 9 -------- > drivers/gpu/drm/panfrost/panfrost_job.c | 22 +++++++++++++++++- > 6 files changed, 40 insertions(+), 42 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile > index b71935862417..ecf0864cb515 100644 > --- a/drivers/gpu/drm/panfrost/Makefile > +++ b/drivers/gpu/drm/panfrost/Makefile > @@ -5,7 +5,6 @@ panfrost-y := \ > panfrost_device.o \ > panfrost_devfreq.o \ > panfrost_gem.o \ > - panfrost_gem_shrinker.o \ > panfrost_gpu.o \ > panfrost_job.o \ > panfrost_mmu.o \ I'm not sure you actually deleted gem_shrinker anywhere in this patch? Diff stat is too small.
On 3/15/22 02:26, Alyssa Rosenzweig wrote: > On Tue, Mar 15, 2022 at 01:42:53AM +0300, Dmitry Osipenko wrote: >> Replace Panfrost's memory shrinker with a generic DRM memory shrinker. >> >> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> >> --- >> drivers/gpu/drm/panfrost/Makefile | 1 - >> drivers/gpu/drm/panfrost/panfrost_device.h | 4 ---- >> drivers/gpu/drm/panfrost/panfrost_drv.c | 19 ++------------- >> drivers/gpu/drm/panfrost/panfrost_gem.c | 27 ++++++++++++++-------- >> drivers/gpu/drm/panfrost/panfrost_gem.h | 9 -------- >> drivers/gpu/drm/panfrost/panfrost_job.c | 22 +++++++++++++++++- >> 6 files changed, 40 insertions(+), 42 deletions(-) >> >> diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile >> index b71935862417..ecf0864cb515 100644 >> --- a/drivers/gpu/drm/panfrost/Makefile >> +++ b/drivers/gpu/drm/panfrost/Makefile >> @@ -5,7 +5,6 @@ panfrost-y := \ >> panfrost_device.o \ >> panfrost_devfreq.o \ >> panfrost_gem.o \ >> - panfrost_gem_shrinker.o \ >> panfrost_gpu.o \ >> panfrost_job.o \ >> panfrost_mmu.o \ > > I'm not sure you actually deleted gem_shrinker anywhere in this patch? > Diff stat is too small. Indeed, I was also confused by the diffstat once noticed it after the patches were sent out. And yes, I missed to git-add the panfrost_gem_shrinker.c by accident. Good catch, thank you! I'll correct it in in the v3. Meanwhile, will be great if you or somebody else could test this Panfrost patch. I don't have any h/w with Mali on hands yet and only compile-tested it.
On 14/03/2022 22:42, Dmitry Osipenko wrote: > Replace Panfrost's memory shrinker with a generic DRM memory shrinker. > > Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> > --- I gave this a spin on my Firefly-RK3288 board and everything seems to work. So feel free to add a: Tested-by: Steven Price <steven.price@arm.com> As Alyssa has already pointed out you need to remove the panfrost_gem_shrinker.c file. But otherwise everything looks fine, and I'm very happy to see the shrinker code gone ;) Thanks, Steve > drivers/gpu/drm/panfrost/Makefile | 1 - > drivers/gpu/drm/panfrost/panfrost_device.h | 4 ---- > drivers/gpu/drm/panfrost/panfrost_drv.c | 19 ++------------- > drivers/gpu/drm/panfrost/panfrost_gem.c | 27 ++++++++++++++-------- > drivers/gpu/drm/panfrost/panfrost_gem.h | 9 -------- > drivers/gpu/drm/panfrost/panfrost_job.c | 22 +++++++++++++++++- > 6 files changed, 40 insertions(+), 42 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile > index b71935862417..ecf0864cb515 100644 > --- a/drivers/gpu/drm/panfrost/Makefile > +++ b/drivers/gpu/drm/panfrost/Makefile > @@ -5,7 +5,6 @@ panfrost-y := \ > panfrost_device.o \ > panfrost_devfreq.o \ > panfrost_gem.o \ > - panfrost_gem_shrinker.o \ > panfrost_gpu.o \ > panfrost_job.o \ > panfrost_mmu.o \ > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h > index 8b25278f34c8..fe04b21fc044 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -115,10 +115,6 @@ struct panfrost_device { > atomic_t pending; > } reset; > > - struct mutex shrinker_lock; > - struct list_head shrinker_list; > - struct shrinker shrinker; > - > struct panfrost_devfreq pfdevfreq; > }; > > diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c > index 94b6f0a19c83..b014dadcf51f 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_drv.c > +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c > @@ -160,7 +160,6 @@ panfrost_lookup_bos(struct drm_device *dev, > break; > } > > - atomic_inc(&bo->gpu_usecount); > job->mappings[i] = mapping; > } > > @@ -390,7 +389,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, > { > struct panfrost_file_priv *priv = file_priv->driver_priv; > struct drm_panfrost_madvise *args = data; > - struct panfrost_device *pfdev = dev->dev_private; > struct drm_gem_object *gem_obj; > struct panfrost_gem_object *bo; > int ret = 0; > @@ -403,7 +401,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, > > bo = to_panfrost_bo(gem_obj); > > - mutex_lock(&pfdev->shrinker_lock); > mutex_lock(&bo->mappings.lock); > if (args->madv == PANFROST_MADV_DONTNEED) { > struct panfrost_gem_mapping *first; > @@ -429,17 +426,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, > > args->retained = drm_gem_shmem_madvise(&bo->base, args->madv); > > - if (args->retained) { > - if (args->madv == PANFROST_MADV_DONTNEED) > - list_add_tail(&bo->base.madv_list, > - &pfdev->shrinker_list); > - else if (args->madv == PANFROST_MADV_WILLNEED) > - list_del_init(&bo->base.madv_list); > - } > - > out_unlock_mappings: > mutex_unlock(&bo->mappings.lock); > - mutex_unlock(&pfdev->shrinker_lock); > > drm_gem_object_put(gem_obj); > return ret; > @@ -570,9 +558,6 @@ static int panfrost_probe(struct platform_device *pdev) > ddev->dev_private = pfdev; > pfdev->ddev = ddev; > > - mutex_init(&pfdev->shrinker_lock); > - INIT_LIST_HEAD(&pfdev->shrinker_list); > - > err = panfrost_device_init(pfdev); > if (err) { > if (err != -EPROBE_DEFER) > @@ -594,7 +579,7 @@ static int panfrost_probe(struct platform_device *pdev) > if (err < 0) > goto err_out1; > > - panfrost_gem_shrinker_init(ddev); > + drm_gem_shmem_shrinker_register(ddev); > > return 0; > > @@ -612,8 +597,8 @@ static int panfrost_remove(struct platform_device *pdev) > struct panfrost_device *pfdev = platform_get_drvdata(pdev); > struct drm_device *ddev = pfdev->ddev; > > + drm_gem_shmem_shrinker_unregister(ddev); > drm_dev_unregister(ddev); > - panfrost_gem_shrinker_cleanup(ddev); > > pm_runtime_get_sync(pfdev->dev); > pm_runtime_disable(pfdev->dev); > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c > index 293e799e2fe8..d164d05ed84e 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.c > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c > @@ -19,16 +19,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) > struct panfrost_gem_object *bo = to_panfrost_bo(obj); > struct panfrost_device *pfdev = obj->dev->dev_private; > > - /* > - * Make sure the BO is no longer inserted in the shrinker list before > - * taking care of the destruction itself. If we don't do that we have a > - * race condition between this function and what's done in > - * panfrost_gem_shrinker_scan(). > - */ > - mutex_lock(&pfdev->shrinker_lock); > - list_del_init(&bo->base.madv_list); > - mutex_unlock(&pfdev->shrinker_lock); > - > /* > * If we still have mappings attached to the BO, there's a problem in > * our refcounting. > @@ -195,6 +185,22 @@ static int panfrost_gem_pin(struct drm_gem_object *obj) > return drm_gem_shmem_pin(&bo->base); > } > > +static unsigned long panfrost_gem_purge(struct drm_gem_object *obj) > +{ > + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); > + struct panfrost_gem_object *bo = to_panfrost_bo(obj); > + > + if (!mutex_trylock(&bo->mappings.lock)) > + return 0; > + > + panfrost_gem_teardown_mappings_locked(bo); > + drm_gem_shmem_purge_locked(&bo->base); > + > + mutex_unlock(&bo->mappings.lock); > + > + return shmem->base.size >> PAGE_SHIFT; > +} > + > static const struct drm_gem_object_funcs panfrost_gem_funcs = { > .free = panfrost_gem_free_object, > .open = panfrost_gem_open, > @@ -207,6 +213,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = { > .vunmap = drm_gem_shmem_object_vunmap, > .mmap = drm_gem_shmem_object_mmap, > .vm_ops = &drm_gem_shmem_vm_ops, > + .purge = panfrost_gem_purge, > }; > > /** > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h > index 8088d5fd8480..09da064f1c07 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.h > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h > @@ -30,12 +30,6 @@ struct panfrost_gem_object { > struct mutex lock; > } mappings; > > - /* > - * Count the number of jobs referencing this BO so we don't let the > - * shrinker reclaim this object prematurely. > - */ > - atomic_t gpu_usecount; > - > bool noexec :1; > bool is_heap :1; > }; > @@ -84,7 +78,4 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, > void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); > void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); > > -void panfrost_gem_shrinker_init(struct drm_device *dev); > -void panfrost_gem_shrinker_cleanup(struct drm_device *dev); > - > #endif /* __PANFROST_GEM_H__ */ > diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c > index a6925dbb6224..e767e526e897 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_job.c > +++ b/drivers/gpu/drm/panfrost/panfrost_job.c > @@ -267,6 +267,22 @@ static void panfrost_attach_object_fences(struct drm_gem_object **bos, > dma_resv_add_excl_fence(bos[i]->resv, fence); > } > > +static bool panfrost_objects_alive(struct drm_gem_object **bos, int bo_count) > +{ > + struct panfrost_gem_object *bo; > + bool alive = true; > + > + while (alive && bo_count--) { > + bo = to_panfrost_bo(bos[bo_count]); > + > + mutex_lock(&bo->mappings.lock); > + alive = !bo->base.madv; > + mutex_unlock(&bo->mappings.lock); > + } > + > + return alive; > +} > + > int panfrost_job_push(struct panfrost_job *job) > { > struct panfrost_device *pfdev = job->pfdev; > @@ -278,6 +294,11 @@ int panfrost_job_push(struct panfrost_job *job) > if (ret) > return ret; > > + if (!panfrost_objects_alive(job->bos, job->bo_count)) { > + ret = -ENOMEM; > + goto unlock; > + } > + > mutex_lock(&pfdev->sched_lock); > drm_sched_job_arm(&job->base); > > @@ -319,7 +340,6 @@ static void panfrost_job_cleanup(struct kref *ref) > if (!job->mappings[i]) > break; > > - atomic_dec(&job->mappings[i]->obj->gpu_usecount); > panfrost_gem_mapping_put(job->mappings[i]); > } > kvfree(job->mappings);
On 3/16/22 18:04, Steven Price wrote: > On 14/03/2022 22:42, Dmitry Osipenko wrote: >> Replace Panfrost's memory shrinker with a generic DRM memory shrinker. >> >> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> >> --- > I gave this a spin on my Firefly-RK3288 board and everything seems to > work. So feel free to add a: > > Tested-by: Steven Price <steven.price@arm.com> > > As Alyssa has already pointed out you need to remove the > panfrost_gem_shrinker.c file. But otherwise everything looks fine, and > I'm very happy to see the shrinker code gone ;) Awesome, thank you.
On 3/17/22 02:04, Dmitry Osipenko wrote: > > On 3/16/22 18:04, Steven Price wrote: >> On 14/03/2022 22:42, Dmitry Osipenko wrote: >>> Replace Panfrost's memory shrinker with a generic DRM memory shrinker. >>> >>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> >>> --- >> I gave this a spin on my Firefly-RK3288 board and everything seems to >> work. So feel free to add a: >> >> Tested-by: Steven Price <steven.price@arm.com> >> >> As Alyssa has already pointed out you need to remove the >> panfrost_gem_shrinker.c file. But otherwise everything looks fine, and >> I'm very happy to see the shrinker code gone ;) > > Awesome, thank you. Steven, could you please tell me how exactly you tested the shrinker? I realized that today's IGT doesn't have any tests for the Panfrost's madvise ioctl. You may invoke "echo 2 > /proc/sys/vm/drop_caches" manually in order to trigger shrinker while 3d app is running actively (like a game or benchmark). Nothing crashing will be a good enough indicator that it works okay. I may get an RK board next week and then will be able to test it by myself, so please don't hurry.
On 18/03/2022 14:41, Dmitry Osipenko wrote: > > On 3/17/22 02:04, Dmitry Osipenko wrote: >> >> On 3/16/22 18:04, Steven Price wrote: >>> On 14/03/2022 22:42, Dmitry Osipenko wrote: >>>> Replace Panfrost's memory shrinker with a generic DRM memory shrinker. >>>> >>>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> >>>> --- >>> I gave this a spin on my Firefly-RK3288 board and everything seems to >>> work. So feel free to add a: >>> >>> Tested-by: Steven Price <steven.price@arm.com> >>> >>> As Alyssa has already pointed out you need to remove the >>> panfrost_gem_shrinker.c file. But otherwise everything looks fine, and >>> I'm very happy to see the shrinker code gone ;) >> >> Awesome, thank you. > > Steven, could you please tell me how exactly you tested the shrinker? > > I realized that today's IGT doesn't have any tests for the Panfrost's > madvise ioctl. > > You may invoke "echo 2 > /proc/sys/vm/drop_caches" manually in order to > trigger shrinker while 3d app is running actively (like a game or > benchmark). Nothing crashing will be a good enough indicator that it > works okay. > > I may get an RK board next week and then will be able to test it by > myself, so please don't hurry. I have to admit it wasn't a very thorough test. I run glmark on the board with the following hack: diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index b014dadcf51f..194dec00695a 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -279,6 +279,14 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, if (ret) goto out_cleanup_job; + { + struct shrink_control sc = { + .nr_to_scan = 1000 + }; + dev->shmem_shrinker->base.scan_objects(&dev->shmem_shrinker->base, + &sc); + } + ret = panfrost_job_push(job); if (ret) goto out_cleanup_job; That hack was specifically because I had some doubts about the removal of the 'gpu_usecount' counter and wanted to ensure that purging as the job is submitted wouldn't cause problems. The drop_caches file should also work AFAIK. Steve
On 3/18/22 17:47, Steven Price wrote: > On 18/03/2022 14:41, Dmitry Osipenko wrote: >> >> On 3/17/22 02:04, Dmitry Osipenko wrote: >>> >>> On 3/16/22 18:04, Steven Price wrote: >>>> On 14/03/2022 22:42, Dmitry Osipenko wrote: >>>>> Replace Panfrost's memory shrinker with a generic DRM memory shrinker. >>>>> >>>>> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> >>>>> --- >>>> I gave this a spin on my Firefly-RK3288 board and everything seems to >>>> work. So feel free to add a: >>>> >>>> Tested-by: Steven Price <steven.price@arm.com> >>>> >>>> As Alyssa has already pointed out you need to remove the >>>> panfrost_gem_shrinker.c file. But otherwise everything looks fine, and >>>> I'm very happy to see the shrinker code gone ;) >>> >>> Awesome, thank you. >> >> Steven, could you please tell me how exactly you tested the shrinker? >> >> I realized that today's IGT doesn't have any tests for the Panfrost's >> madvise ioctl. >> >> You may invoke "echo 2 > /proc/sys/vm/drop_caches" manually in order to >> trigger shrinker while 3d app is running actively (like a game or >> benchmark). Nothing crashing will be a good enough indicator that it >> works okay. >> >> I may get an RK board next week and then will be able to test it by >> myself, so please don't hurry. > > I have to admit it wasn't a very thorough test. I run glmark on the > board with the following hack: > > diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c > index b014dadcf51f..194dec00695a 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_drv.c > +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c > @@ -279,6 +279,14 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, > if (ret) > goto out_cleanup_job; > > + { > + struct shrink_control sc = { > + .nr_to_scan = 1000 > + }; > + dev->shmem_shrinker->base.scan_objects(&dev->shmem_shrinker->base, > + &sc); > + } > + > ret = panfrost_job_push(job); > if (ret) > goto out_cleanup_job; > > That hack was specifically because I had some doubts about the removal > of the 'gpu_usecount' counter and wanted to ensure that purging as the > job is submitted wouldn't cause problems. > > The drop_caches file should also work AFAIK. Yours variant of testing looks okay, thanks. We check BO's reservation dma-fence status in the shrinker's scan(), so BO won't be purged until the last job has completed using the BO. The 'gpu_usecount' is redundant now, and thus, I removed it.
diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile index b71935862417..ecf0864cb515 100644 --- a/drivers/gpu/drm/panfrost/Makefile +++ b/drivers/gpu/drm/panfrost/Makefile @@ -5,7 +5,6 @@ panfrost-y := \ panfrost_device.o \ panfrost_devfreq.o \ panfrost_gem.o \ - panfrost_gem_shrinker.o \ panfrost_gpu.o \ panfrost_job.o \ panfrost_mmu.o \ diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index 8b25278f34c8..fe04b21fc044 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -115,10 +115,6 @@ struct panfrost_device { atomic_t pending; } reset; - struct mutex shrinker_lock; - struct list_head shrinker_list; - struct shrinker shrinker; - struct panfrost_devfreq pfdevfreq; }; diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 94b6f0a19c83..b014dadcf51f 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -160,7 +160,6 @@ panfrost_lookup_bos(struct drm_device *dev, break; } - atomic_inc(&bo->gpu_usecount); job->mappings[i] = mapping; } @@ -390,7 +389,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, { struct panfrost_file_priv *priv = file_priv->driver_priv; struct drm_panfrost_madvise *args = data; - struct panfrost_device *pfdev = dev->dev_private; struct drm_gem_object *gem_obj; struct panfrost_gem_object *bo; int ret = 0; @@ -403,7 +401,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, bo = to_panfrost_bo(gem_obj); - mutex_lock(&pfdev->shrinker_lock); mutex_lock(&bo->mappings.lock); if (args->madv == PANFROST_MADV_DONTNEED) { struct panfrost_gem_mapping *first; @@ -429,17 +426,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, args->retained = drm_gem_shmem_madvise(&bo->base, args->madv); - if (args->retained) { - if (args->madv == PANFROST_MADV_DONTNEED) - list_add_tail(&bo->base.madv_list, - &pfdev->shrinker_list); - else if (args->madv == PANFROST_MADV_WILLNEED) - list_del_init(&bo->base.madv_list); - } - out_unlock_mappings: mutex_unlock(&bo->mappings.lock); - mutex_unlock(&pfdev->shrinker_lock); drm_gem_object_put(gem_obj); return ret; @@ -570,9 +558,6 @@ static int panfrost_probe(struct platform_device *pdev) ddev->dev_private = pfdev; pfdev->ddev = ddev; - mutex_init(&pfdev->shrinker_lock); - INIT_LIST_HEAD(&pfdev->shrinker_list); - err = panfrost_device_init(pfdev); if (err) { if (err != -EPROBE_DEFER) @@ -594,7 +579,7 @@ static int panfrost_probe(struct platform_device *pdev) if (err < 0) goto err_out1; - panfrost_gem_shrinker_init(ddev); + drm_gem_shmem_shrinker_register(ddev); return 0; @@ -612,8 +597,8 @@ static int panfrost_remove(struct platform_device *pdev) struct panfrost_device *pfdev = platform_get_drvdata(pdev); struct drm_device *ddev = pfdev->ddev; + drm_gem_shmem_shrinker_unregister(ddev); drm_dev_unregister(ddev); - panfrost_gem_shrinker_cleanup(ddev); pm_runtime_get_sync(pfdev->dev); pm_runtime_disable(pfdev->dev); diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 293e799e2fe8..d164d05ed84e 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -19,16 +19,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) struct panfrost_gem_object *bo = to_panfrost_bo(obj); struct panfrost_device *pfdev = obj->dev->dev_private; - /* - * Make sure the BO is no longer inserted in the shrinker list before - * taking care of the destruction itself. If we don't do that we have a - * race condition between this function and what's done in - * panfrost_gem_shrinker_scan(). - */ - mutex_lock(&pfdev->shrinker_lock); - list_del_init(&bo->base.madv_list); - mutex_unlock(&pfdev->shrinker_lock); - /* * If we still have mappings attached to the BO, there's a problem in * our refcounting. @@ -195,6 +185,22 @@ static int panfrost_gem_pin(struct drm_gem_object *obj) return drm_gem_shmem_pin(&bo->base); } +static unsigned long panfrost_gem_purge(struct drm_gem_object *obj) +{ + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + struct panfrost_gem_object *bo = to_panfrost_bo(obj); + + if (!mutex_trylock(&bo->mappings.lock)) + return 0; + + panfrost_gem_teardown_mappings_locked(bo); + drm_gem_shmem_purge_locked(&bo->base); + + mutex_unlock(&bo->mappings.lock); + + return shmem->base.size >> PAGE_SHIFT; +} + static const struct drm_gem_object_funcs panfrost_gem_funcs = { .free = panfrost_gem_free_object, .open = panfrost_gem_open, @@ -207,6 +213,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = { .vunmap = drm_gem_shmem_object_vunmap, .mmap = drm_gem_shmem_object_mmap, .vm_ops = &drm_gem_shmem_vm_ops, + .purge = panfrost_gem_purge, }; /** diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h index 8088d5fd8480..09da064f1c07 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.h +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -30,12 +30,6 @@ struct panfrost_gem_object { struct mutex lock; } mappings; - /* - * Count the number of jobs referencing this BO so we don't let the - * shrinker reclaim this object prematurely. - */ - atomic_t gpu_usecount; - bool noexec :1; bool is_heap :1; }; @@ -84,7 +78,4 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); -void panfrost_gem_shrinker_init(struct drm_device *dev); -void panfrost_gem_shrinker_cleanup(struct drm_device *dev); - #endif /* __PANFROST_GEM_H__ */ diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index a6925dbb6224..e767e526e897 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -267,6 +267,22 @@ static void panfrost_attach_object_fences(struct drm_gem_object **bos, dma_resv_add_excl_fence(bos[i]->resv, fence); } +static bool panfrost_objects_alive(struct drm_gem_object **bos, int bo_count) +{ + struct panfrost_gem_object *bo; + bool alive = true; + + while (alive && bo_count--) { + bo = to_panfrost_bo(bos[bo_count]); + + mutex_lock(&bo->mappings.lock); + alive = !bo->base.madv; + mutex_unlock(&bo->mappings.lock); + } + + return alive; +} + int panfrost_job_push(struct panfrost_job *job) { struct panfrost_device *pfdev = job->pfdev; @@ -278,6 +294,11 @@ int panfrost_job_push(struct panfrost_job *job) if (ret) return ret; + if (!panfrost_objects_alive(job->bos, job->bo_count)) { + ret = -ENOMEM; + goto unlock; + } + mutex_lock(&pfdev->sched_lock); drm_sched_job_arm(&job->base); @@ -319,7 +340,6 @@ static void panfrost_job_cleanup(struct kref *ref) if (!job->mappings[i]) break; - atomic_dec(&job->mappings[i]->obj->gpu_usecount); panfrost_gem_mapping_put(job->mappings[i]); } kvfree(job->mappings);
Replace Panfrost's memory shrinker with a generic DRM memory shrinker. Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> --- drivers/gpu/drm/panfrost/Makefile | 1 - drivers/gpu/drm/panfrost/panfrost_device.h | 4 ---- drivers/gpu/drm/panfrost/panfrost_drv.c | 19 ++------------- drivers/gpu/drm/panfrost/panfrost_gem.c | 27 ++++++++++++++-------- drivers/gpu/drm/panfrost/panfrost_gem.h | 9 -------- drivers/gpu/drm/panfrost/panfrost_job.c | 22 +++++++++++++++++- 6 files changed, 40 insertions(+), 42 deletions(-)