From 1c80be48c70a2198f7cf04a546b3805b92293ac6 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 29 Oct 2020 20:00:59 +0100 Subject: drm/vc4: bo: Add a managed action to cleanup the cache The BO cache needs to be cleaned up using vc4_bo_cache_destroy, but it's not used consistently (vc4_drv's bind calls it in its error path, but doesn't in unbind), and we can make that automatic through a managed action. Let's remove the requirement to call vc4_bo_cache_destroy. Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.") Acked-by: Daniel Vetter Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_bo.c | 5 +++-- drivers/gpu/drm/vc4/vc4_drv.c | 1 - drivers/gpu/drm/vc4/vc4_drv.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 74ceebd62fbc..073b528f3333 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -1005,6 +1005,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, return 0; } +static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused); int vc4_bo_cache_init(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); @@ -1033,10 +1034,10 @@ int vc4_bo_cache_init(struct drm_device *dev) INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work); timer_setup(&vc4->bo_cache.time_timer, vc4_bo_cache_time_timer, 0); - return 0; + return drmm_add_action_or_reset(dev, vc4_bo_cache_destroy, NULL); } -void vc4_bo_cache_destroy(struct drm_device *dev) +static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused) { struct vc4_dev *vc4 = to_vc4_dev(dev); int i; diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index a17aa1db11b6..fad1d7c88cde 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -315,7 +315,6 @@ unbind_all: gem_destroy: vc4_gem_destroy(drm); drm_mode_config_cleanup(drm); - vc4_bo_cache_destroy(drm); dev_put: drm_dev_put(drm); return ret; diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 66d4fb16db8f..437ff036198d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -809,7 +810,6 @@ struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev, struct sg_table *sgt); void *vc4_prime_vmap(struct drm_gem_object *obj); int vc4_bo_cache_init(struct drm_device *dev); -void vc4_bo_cache_destroy(struct drm_device *dev); int vc4_bo_inc_usecnt(struct vc4_bo *bo); void vc4_bo_dec_usecnt(struct vc4_bo *bo); void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo); -- cgit v1.2.3 From e46e5330d13de67de5b614c5021730e9709de975 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 29 Oct 2020 20:01:00 +0100 Subject: drm/vc4: drv: Use managed drm_mode_config_init Using drmm_mode_config_init instead of drm_mode_config_init allows us to cleanup a bit the error path. Signed-off-by: Maxime Ripard Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-2-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_drv.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index fad1d7c88cde..44209077000d 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -281,7 +281,9 @@ static int vc4_drm_bind(struct device *dev) if (ret) goto dev_put; - drm_mode_config_init(drm); + ret = drmm_mode_config_init(drm); + if (ret) + goto dev_put; vc4_gem_init(drm); @@ -314,7 +316,6 @@ unbind_all: component_unbind_all(dev, drm); gem_destroy: vc4_gem_destroy(drm); - drm_mode_config_cleanup(drm); dev_put: drm_dev_put(drm); return ret; @@ -329,8 +330,6 @@ static void vc4_drm_unbind(struct device *dev) drm_atomic_helper_shutdown(drm); - drm_mode_config_cleanup(drm); - drm_atomic_private_obj_fini(&vc4->load_tracker); drm_atomic_private_obj_fini(&vc4->ctm_manager); -- cgit v1.2.3 From 171a072b4699b4bf79cd1bbbcd05a53d40903034 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 29 Oct 2020 20:01:01 +0100 Subject: drm/vc4: gem: Add a managed action to cleanup the job queue The job queue needs to be cleaned up using vc4_gem_destroy, but it's not used consistently (vc4_drv's bind calls it in its error path, but doesn't in unbind), and we can make that automatic through a managed action. Let's remove the requirement to call vc4_gem_destroy. Fixes: d5b1a78a772f ("drm/vc4: Add support for drawing 3D frames.") Acked-by: Daniel Vetter Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-3-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_drv.c | 8 ++++---- drivers/gpu/drm/vc4/vc4_drv.h | 3 +-- drivers/gpu/drm/vc4/vc4_gem.c | 9 +++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 44209077000d..2e418fa5b81c 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -285,11 +285,13 @@ static int vc4_drm_bind(struct device *dev) if (ret) goto dev_put; - vc4_gem_init(drm); + ret = vc4_gem_init(drm); + if (ret) + goto dev_put; ret = component_bind_all(dev, drm); if (ret) - goto gem_destroy; + goto dev_put; ret = vc4_plane_create_additional_planes(drm); if (ret) @@ -314,8 +316,6 @@ static int vc4_drm_bind(struct device *dev) unbind_all: component_unbind_all(dev, drm); -gem_destroy: - vc4_gem_destroy(drm); dev_put: drm_dev_put(drm); return ret; diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 437ff036198d..6de6c232fefb 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -874,8 +874,7 @@ extern struct platform_driver vc4_dsi_driver; extern const struct dma_fence_ops vc4_fence_ops; /* vc4_gem.c */ -void vc4_gem_init(struct drm_device *dev); -void vc4_gem_destroy(struct drm_device *dev); +int vc4_gem_init(struct drm_device *dev); int vc4_submit_cl_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 9f01ddd5b932..32367980d204 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -1263,8 +1263,8 @@ fail: return ret; } -void -vc4_gem_init(struct drm_device *dev) +static void vc4_gem_destroy(struct drm_device *dev, void *unused); +int vc4_gem_init(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); @@ -1285,10 +1285,11 @@ vc4_gem_init(struct drm_device *dev) INIT_LIST_HEAD(&vc4->purgeable.list); mutex_init(&vc4->purgeable.lock); + + return drmm_add_action_or_reset(dev, vc4_gem_destroy, NULL); } -void -vc4_gem_destroy(struct drm_device *dev) +static void vc4_gem_destroy(struct drm_device *dev, void *unused) { struct vc4_dev *vc4 = to_vc4_dev(dev); -- cgit v1.2.3 From 88e085896aa67ac250943b117a9016801011c624 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 29 Oct 2020 20:01:02 +0100 Subject: drm/vc4: Use the helper to retrieve vc4_dev when needed We have a helper to retrieve the vc4_dev structure from the drm_device one when needed, so let's use it consistently. Acked-by: Daniel Vetter Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-4-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_hvs.c | 4 ++-- drivers/gpu/drm/vc4/vc4_kms.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 4d0a833366ce..b72b2bd05a81 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -560,7 +560,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = drm->dev_private; + struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_hvs *hvs = NULL; int ret; u32 dispctrl; @@ -679,7 +679,7 @@ static void vc4_hvs_unbind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = dev_get_drvdata(master); - struct vc4_dev *vc4 = drm->dev_private; + struct vc4_dev *vc4 = to_vc4_dev(drm); struct vc4_hvs *hvs = vc4->hvs; if (drm_mm_node_allocated(&vc4->hvs->mitchell_netravali_filter)) diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 149825ff5df8..708099a24406 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -51,7 +51,7 @@ static struct vc4_ctm_state *vc4_get_ctm_state(struct drm_atomic_state *state, struct drm_private_obj *manager) { struct drm_device *dev = state->dev; - struct vc4_dev *vc4 = dev->dev_private; + struct vc4_dev *vc4 = to_vc4_dev(dev); struct drm_private_state *priv_state; int ret; -- cgit v1.2.3 From 84d7d4720c21320c0e4f9369d6a82fc112b63d8c Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 29 Oct 2020 20:01:03 +0100 Subject: drm/vc4: Use devm_drm_dev_alloc We can simplify a bit the bind code, its error path and unbind by using the managed devm_drm_dev_alloc function. Acked-by: Daniel Vetter Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-5-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_bo.c | 4 ++-- drivers/gpu/drm/vc4/vc4_drv.c | 27 ++++++++++----------------- drivers/gpu/drm/vc4/vc4_drv.h | 4 ++-- drivers/gpu/drm/vc4/vc4_gem.c | 10 +++++----- drivers/gpu/drm/vc4/vc4_v3d.c | 12 ++++++------ 5 files changed, 25 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 073b528f3333..cc74a3f3a07a 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -449,7 +449,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size, } if (IS_ERR(cma_obj)) { - struct drm_printer p = drm_info_printer(vc4->dev->dev); + struct drm_printer p = drm_info_printer(vc4->base.dev); DRM_ERROR("Failed to allocate from CMA:\n"); vc4_bo_stats_print(&p, vc4); return ERR_PTR(-ENOMEM); @@ -590,7 +590,7 @@ static void vc4_bo_cache_time_work(struct work_struct *work) { struct vc4_dev *vc4 = container_of(work, struct vc4_dev, bo_cache.time_work); - struct drm_device *dev = vc4->dev; + struct drm_device *dev = &vc4->base; mutex_lock(&vc4->bo_lock); vc4_bo_cache_free_old(dev); diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 2e418fa5b81c..17404c2a3d3e 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -257,41 +257,37 @@ static int vc4_drm_bind(struct device *dev) dev->coherent_dma_mask = DMA_BIT_MASK(32); - vc4 = devm_kzalloc(dev, sizeof(*vc4), GFP_KERNEL); - if (!vc4) - return -ENOMEM; - /* If VC4 V3D is missing, don't advertise render nodes. */ node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL); if (!node || !of_device_is_available(node)) vc4_drm_driver.driver_features &= ~DRIVER_RENDER; of_node_put(node); - drm = drm_dev_alloc(&vc4_drm_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); + vc4 = devm_drm_dev_alloc(dev, &vc4_drm_driver, struct vc4_dev, base); + if (IS_ERR(vc4)) + return PTR_ERR(vc4); + + drm = &vc4->base; platform_set_drvdata(pdev, drm); - vc4->dev = drm; - drm->dev_private = vc4; INIT_LIST_HEAD(&vc4->debugfs_list); mutex_init(&vc4->bin_bo_lock); ret = vc4_bo_cache_init(drm); if (ret) - goto dev_put; + return ret; ret = drmm_mode_config_init(drm); if (ret) - goto dev_put; + return ret; ret = vc4_gem_init(drm); if (ret) - goto dev_put; + return ret; ret = component_bind_all(dev, drm); if (ret) - goto dev_put; + return ret; ret = vc4_plane_create_additional_planes(drm); if (ret) @@ -316,8 +312,7 @@ static int vc4_drm_bind(struct device *dev) unbind_all: component_unbind_all(dev, drm); -dev_put: - drm_dev_put(drm); + return ret; } @@ -332,8 +327,6 @@ static void vc4_drm_unbind(struct device *dev) drm_atomic_private_obj_fini(&vc4->load_tracker); drm_atomic_private_obj_fini(&vc4->ctm_manager); - - drm_dev_put(drm); } static const struct component_master_ops vc4_drm_ops = { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 6de6c232fefb..19b75bebd35f 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -72,7 +72,7 @@ struct vc4_perfmon { }; struct vc4_dev { - struct drm_device *dev; + struct drm_device base; struct vc4_hvs *hvs; struct vc4_v3d *v3d; @@ -235,7 +235,7 @@ struct vc4_dev { static inline struct vc4_dev * to_vc4_dev(struct drm_device *dev) { - return (struct vc4_dev *)dev->dev_private; + return container_of(dev, struct vc4_dev, base); } struct vc4_bo { diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 32367980d204..b641252939d8 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -314,16 +314,16 @@ vc4_reset_work(struct work_struct *work) struct vc4_dev *vc4 = container_of(work, struct vc4_dev, hangcheck.reset_work); - vc4_save_hang_state(vc4->dev); + vc4_save_hang_state(&vc4->base); - vc4_reset(vc4->dev); + vc4_reset(&vc4->base); } static void vc4_hangcheck_elapsed(struct timer_list *t) { struct vc4_dev *vc4 = from_timer(vc4, t, hangcheck.timer); - struct drm_device *dev = vc4->dev; + struct drm_device *dev = &vc4->base; uint32_t ct0ca, ct1ca; unsigned long irqflags; struct vc4_exec_info *bin_exec, *render_exec; @@ -1000,7 +1000,7 @@ vc4_job_handle_completed(struct vc4_dev *vc4) list_del(&exec->head); spin_unlock_irqrestore(&vc4->job_lock, irqflags); - vc4_complete_exec(vc4->dev, exec); + vc4_complete_exec(&vc4->base, exec); spin_lock_irqsave(&vc4->job_lock, irqflags); } @@ -1258,7 +1258,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, return 0; fail: - vc4_complete_exec(vc4->dev, exec); + vc4_complete_exec(&vc4->base, exec); return ret; } diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c index f7ab979721b3..65d0dac69b0b 100644 --- a/drivers/gpu/drm/vc4/vc4_v3d.c +++ b/drivers/gpu/drm/vc4/vc4_v3d.c @@ -168,7 +168,7 @@ static void vc4_v3d_init_hw(struct drm_device *dev) int vc4_v3d_get_bin_slot(struct vc4_dev *vc4) { - struct drm_device *dev = vc4->dev; + struct drm_device *dev = &vc4->base; unsigned long irqflags; int slot; uint64_t seqno = 0; @@ -246,7 +246,7 @@ static int bin_bo_alloc(struct vc4_dev *vc4) INIT_LIST_HEAD(&list); while (true) { - struct vc4_bo *bo = vc4_bo_create(vc4->dev, size, true, + struct vc4_bo *bo = vc4_bo_create(&vc4->base, size, true, VC4_BO_TYPE_BIN); if (IS_ERR(bo)) { @@ -361,7 +361,7 @@ static int vc4_v3d_runtime_suspend(struct device *dev) struct vc4_v3d *v3d = dev_get_drvdata(dev); struct vc4_dev *vc4 = v3d->vc4; - vc4_irq_uninstall(vc4->dev); + vc4_irq_uninstall(&vc4->base); clk_disable_unprepare(v3d->clk); @@ -378,11 +378,11 @@ static int vc4_v3d_runtime_resume(struct device *dev) if (ret != 0) return ret; - vc4_v3d_init_hw(vc4->dev); + vc4_v3d_init_hw(&vc4->base); /* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */ - enable_irq(vc4->dev->irq); - vc4_irq_postinstall(vc4->dev); + enable_irq(vc4->base.irq); + vc4_irq_postinstall(&vc4->base); return 0; } -- cgit v1.2.3 From dcda7c28bff2662a44c0adaf87c08031bebeb7d8 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 29 Oct 2020 20:01:04 +0100 Subject: drm/vc4: kms: Add functions to create the state objects In order to make the vc4_kms_load code and error path a bit easier to read and extend, add functions to create state objects, and use managed actions to cleanup if needed. Signed-off-by: Maxime Ripard Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201029190104.2181730-6-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_drv.c | 3 -- drivers/gpu/drm/vc4/vc4_kms.c | 78 +++++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 17404c2a3d3e..c0185da72fd0 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -324,9 +324,6 @@ static void vc4_drm_unbind(struct device *dev) drm_dev_unregister(drm); drm_atomic_helper_shutdown(drm); - - drm_atomic_private_obj_fini(&vc4->load_tracker); - drm_atomic_private_obj_fini(&vc4->ctm_manager); } static const struct component_master_ops vc4_drm_ops = { diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 708099a24406..2b951cae04ad 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -93,6 +93,29 @@ static const struct drm_private_state_funcs vc4_ctm_state_funcs = { .atomic_destroy_state = vc4_ctm_destroy_state, }; +static void vc4_ctm_obj_fini(struct drm_device *dev, void *unused) +{ + struct vc4_dev *vc4 = to_vc4_dev(dev); + + drm_atomic_private_obj_fini(&vc4->ctm_manager); +} + +static int vc4_ctm_obj_init(struct vc4_dev *vc4) +{ + struct vc4_ctm_state *ctm_state; + + drm_modeset_lock_init(&vc4->ctm_state_lock); + + ctm_state = kzalloc(sizeof(*ctm_state), GFP_KERNEL); + if (!ctm_state) + return -ENOMEM; + + drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, &ctm_state->base, + &vc4_ctm_state_funcs); + + return drmm_add_action(&vc4->base, vc4_ctm_obj_fini, NULL); +} + /* Converts a DRM S31.32 value to the HW S0.9 format. */ static u16 vc4_ctm_s31_32_to_s0_9(u64 in) { @@ -609,6 +632,34 @@ static const struct drm_private_state_funcs vc4_load_tracker_state_funcs = { .atomic_destroy_state = vc4_load_tracker_destroy_state, }; +static void vc4_load_tracker_obj_fini(struct drm_device *dev, void *unused) +{ + struct vc4_dev *vc4 = to_vc4_dev(dev); + + if (!vc4->load_tracker_available) + return; + + drm_atomic_private_obj_fini(&vc4->load_tracker); +} + +static int vc4_load_tracker_obj_init(struct vc4_dev *vc4) +{ + struct vc4_load_tracker_state *load_state; + + if (!vc4->load_tracker_available) + return 0; + + load_state = kzalloc(sizeof(*load_state), GFP_KERNEL); + if (!load_state) + return -ENOMEM; + + drm_atomic_private_obj_init(&vc4->base, &vc4->load_tracker, + &load_state->base, + &vc4_load_tracker_state_funcs); + + return drmm_add_action(&vc4->base, vc4_load_tracker_obj_fini, NULL); +} + #define NUM_OUTPUTS 6 #define NUM_CHANNELS 3 @@ -711,8 +762,6 @@ static const struct drm_mode_config_funcs vc4_mode_funcs = { int vc4_kms_load(struct drm_device *dev) { struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_ctm_state *ctm_state; - struct vc4_load_tracker_state *load_state; bool is_vc5 = of_device_is_compatible(dev->dev->of_node, "brcm,bcm2711-vc5"); int ret; @@ -751,26 +800,13 @@ int vc4_kms_load(struct drm_device *dev) dev->mode_config.async_page_flip = true; dev->mode_config.allow_fb_modifiers = true; - drm_modeset_lock_init(&vc4->ctm_state_lock); - - ctm_state = kzalloc(sizeof(*ctm_state), GFP_KERNEL); - if (!ctm_state) - return -ENOMEM; - - drm_atomic_private_obj_init(dev, &vc4->ctm_manager, &ctm_state->base, - &vc4_ctm_state_funcs); - - if (vc4->load_tracker_available) { - load_state = kzalloc(sizeof(*load_state), GFP_KERNEL); - if (!load_state) { - drm_atomic_private_obj_fini(&vc4->ctm_manager); - return -ENOMEM; - } + ret = vc4_ctm_obj_init(vc4); + if (ret) + return ret; - drm_atomic_private_obj_init(dev, &vc4->load_tracker, - &load_state->base, - &vc4_load_tracker_state_funcs); - } + ret = vc4_load_tracker_obj_init(vc4); + if (ret) + return ret; drm_mode_config_reset(dev); -- cgit v1.2.3 From 7d2d6d01293e6d9b42a6cb410be4158571f7fe9d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sun, 1 Nov 2020 18:40:16 +0100 Subject: drm/panfrost: Fix a deadlock between the shrinker and madvise path panfrost_ioctl_madvise() and panfrost_gem_purge() acquire the mappings and shmem locks in different orders, thus leading to a potential the mappings lock first. Fixes: bdefca2d8dc0 ("drm/panfrost: Add the panfrost_gem_mapping concept") Cc: Cc: Christian Hewitt Reported-by: Christian Hewitt Signed-off-by: Boris Brezillon Reviewed-by: Steven Price Link: https://patchwork.freedesktop.org/patch/msgid/20201101174016.839110-1-boris.brezillon@collabora.com --- drivers/gpu/drm/panfrost/panfrost_gem.c | 4 +--- drivers/gpu/drm/panfrost/panfrost_gem.h | 2 +- drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c | 14 +++++++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 1a6cea0e0bd7..62d4d710a571 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -105,14 +105,12 @@ void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping) kref_put(&mapping->refcount, panfrost_gem_mapping_release); } -void panfrost_gem_teardown_mappings(struct panfrost_gem_object *bo) +void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo) { struct panfrost_gem_mapping *mapping; - mutex_lock(&bo->mappings.lock); list_for_each_entry(mapping, &bo->mappings.list, node) panfrost_gem_teardown_mapping(mapping); - mutex_unlock(&bo->mappings.lock); } int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h index b3517ff9630c..8088d5fd8480 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.h +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -82,7 +82,7 @@ struct panfrost_gem_mapping * panfrost_gem_mapping_get(struct panfrost_gem_object *bo, struct panfrost_file_priv *priv); void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); -void panfrost_gem_teardown_mappings(struct panfrost_gem_object *bo); +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); diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c index 288e46c40673..1b9f68d8e9aa 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c @@ -40,18 +40,26 @@ static bool 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); + bool ret = false; if (atomic_read(&bo->gpu_usecount)) return false; - if (!mutex_trylock(&shmem->pages_lock)) + if (!mutex_trylock(&bo->mappings.lock)) return false; - panfrost_gem_teardown_mappings(bo); + if (!mutex_trylock(&shmem->pages_lock)) + goto unlock_mappings; + + panfrost_gem_teardown_mappings_locked(bo); drm_gem_shmem_purge_locked(obj); + ret = true; mutex_unlock(&shmem->pages_lock); - return true; + +unlock_mappings: + mutex_unlock(&bo->mappings.lock); + return ret; } static unsigned long -- cgit v1.2.3 From 876b15d2c88d8c005f1aebeaa23f1e448d834757 Mon Sep 17 00:00:00 2001 From: Steven Price Date: Fri, 30 Oct 2020 14:58:33 +0000 Subject: drm/panfrost: Fix module unload When unloading the call to pm_runtime_put_sync_suspend() will attempt to turn the GPU cores off, however panfrost_device_fini() will have turned the clocks off. This leads to the hardware locking up. Instead don't call pm_runtime_put_sync_suspend() and instead simply mark the device as suspended using pm_runtime_set_suspended(). And also include this on the error path in panfrost_probe(). Fixes: aebe8c22a912 ("drm/panfrost: Fix possible suspend in panfrost_remove") Signed-off-by: Steven Price Reviewed-by: Tomeu Vizoso Signed-off-by: Boris Brezillon Link: https://patchwork.freedesktop.org/patch/msgid/20201030145833.29006-1-steven.price@arm.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 37d4cb7a5491..0fc084110e5b 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -626,6 +626,7 @@ static int panfrost_probe(struct platform_device *pdev) err_out1: pm_runtime_disable(pfdev->dev); panfrost_device_fini(pfdev); + pm_runtime_set_suspended(pfdev->dev); err_out0: drm_dev_put(ddev); return err; @@ -640,9 +641,9 @@ static int panfrost_remove(struct platform_device *pdev) panfrost_gem_shrinker_cleanup(ddev); pm_runtime_get_sync(pfdev->dev); - panfrost_device_fini(pfdev); - pm_runtime_put_sync_suspend(pfdev->dev); pm_runtime_disable(pfdev->dev); + panfrost_device_fini(pfdev); + pm_runtime_set_suspended(pfdev->dev); drm_dev_put(ddev); return 0; -- cgit v1.2.3 From 077aa5c8dd6e2b9c721e8cb3d98a3aa8ecb0e2ef Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 2 Nov 2020 17:29:08 +0100 Subject: drm/vc4: drv: Remove unused variable The commit dcda7c28bff2 ("drm/vc4: kms: Add functions to create the state objects") removed the last users of the vc4 variable, but didn't remove that variable resulting in a warning. Fixes: dcda7c28bff2 ("drm/vc4: kms: Add functions to create the state objects") Reported-by: Daniel Vetter Signed-off-by: Maxime Ripard Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201102162908.1436567-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index c0185da72fd0..839610f8092a 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -319,7 +319,6 @@ unbind_all: static void vc4_drm_unbind(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); - struct vc4_dev *vc4 = to_vc4_dev(drm); drm_dev_unregister(drm); -- cgit v1.2.3 From 9522750c66c689b739e151fcdf895420dc81efc0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 2 Nov 2020 13:32:42 -0500 Subject: Fonts: Replace discarded const qualifier Commit 6735b4632def ("Fonts: Support FONT_EXTRA_WORDS macros for built-in fonts") introduced the following error when building rpc_defconfig (only this build appears to be affected): `acorndata_8x8' referenced in section `.text' of arch/arm/boot/compressed/ll_char_wr.o: defined in discarded section `.data' of arch/arm/boot/compressed/font.o `acorndata_8x8' referenced in section `.data.rel.ro' of arch/arm/boot/compressed/font.o: defined in discarded section `.data' of arch/arm/boot/compressed/font.o make[3]: *** [/scratch/linux/arch/arm/boot/compressed/Makefile:191: arch/arm/boot/compressed/vmlinux] Error 1 make[2]: *** [/scratch/linux/arch/arm/boot/Makefile:61: arch/arm/boot/compressed/vmlinux] Error 2 make[1]: *** [/scratch/linux/arch/arm/Makefile:317: zImage] Error 2 The .data section is discarded at link time. Reinstating acorndata_8x8 as const ensures it is still available after linking. Do the same for the other 12 built-in fonts as well, for consistency purposes. Cc: Cc: Russell King Reviewed-by: Greg Kroah-Hartman Fixes: 6735b4632def ("Fonts: Support FONT_EXTRA_WORDS macros for built-in fonts") Signed-off-by: Lee Jones Co-developed-by: Peilin Ye Signed-off-by: Peilin Ye Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201102183242.2031659-1-yepeilin.cs@gmail.com --- lib/fonts/font_10x18.c | 2 +- lib/fonts/font_6x10.c | 2 +- lib/fonts/font_6x11.c | 2 +- lib/fonts/font_6x8.c | 2 +- lib/fonts/font_7x14.c | 2 +- lib/fonts/font_8x16.c | 2 +- lib/fonts/font_8x8.c | 2 +- lib/fonts/font_acorn_8x8.c | 2 +- lib/fonts/font_mini_4x6.c | 2 +- lib/fonts/font_pearl_8x8.c | 2 +- lib/fonts/font_sun12x22.c | 2 +- lib/fonts/font_sun8x16.c | 2 +- lib/fonts/font_ter16x32.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/fonts/font_10x18.c b/lib/fonts/font_10x18.c index 0e2deac97da0..e02f9df24d1e 100644 --- a/lib/fonts/font_10x18.c +++ b/lib/fonts/font_10x18.c @@ -8,7 +8,7 @@ #define FONTDATAMAX 9216 -static struct font_data fontdata_10x18 = { +static const struct font_data fontdata_10x18 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, 0x00, /* 0000000000 */ diff --git a/lib/fonts/font_6x10.c b/lib/fonts/font_6x10.c index 87da8acd07db..6e3c4b7691c8 100644 --- a/lib/fonts/font_6x10.c +++ b/lib/fonts/font_6x10.c @@ -3,7 +3,7 @@ #define FONTDATAMAX 2560 -static struct font_data fontdata_6x10 = { +static const struct font_data fontdata_6x10 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/lib/fonts/font_6x11.c b/lib/fonts/font_6x11.c index 5e975dfa10a5..2d22a24e816f 100644 --- a/lib/fonts/font_6x11.c +++ b/lib/fonts/font_6x11.c @@ -9,7 +9,7 @@ #define FONTDATAMAX (11*256) -static struct font_data fontdata_6x11 = { +static const struct font_data fontdata_6x11 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/lib/fonts/font_6x8.c b/lib/fonts/font_6x8.c index 700039a9ceae..e7442a0d183d 100644 --- a/lib/fonts/font_6x8.c +++ b/lib/fonts/font_6x8.c @@ -3,7 +3,7 @@ #define FONTDATAMAX 2048 -static struct font_data fontdata_6x8 = { +static const struct font_data fontdata_6x8 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 000000 */ diff --git a/lib/fonts/font_7x14.c b/lib/fonts/font_7x14.c index 86d298f38505..9cc7ae2e03f7 100644 --- a/lib/fonts/font_7x14.c +++ b/lib/fonts/font_7x14.c @@ -8,7 +8,7 @@ #define FONTDATAMAX 3584 -static struct font_data fontdata_7x14 = { +static const struct font_data fontdata_7x14 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 0000000 */ diff --git a/lib/fonts/font_8x16.c b/lib/fonts/font_8x16.c index 37cedd36ca5e..bab25dc59e8d 100644 --- a/lib/fonts/font_8x16.c +++ b/lib/fonts/font_8x16.c @@ -10,7 +10,7 @@ #define FONTDATAMAX 4096 -static struct font_data fontdata_8x16 = { +static const struct font_data fontdata_8x16 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/lib/fonts/font_8x8.c b/lib/fonts/font_8x8.c index 8ab695538395..109d0572368f 100644 --- a/lib/fonts/font_8x8.c +++ b/lib/fonts/font_8x8.c @@ -9,7 +9,7 @@ #define FONTDATAMAX 2048 -static struct font_data fontdata_8x8 = { +static const struct font_data fontdata_8x8 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/lib/fonts/font_acorn_8x8.c b/lib/fonts/font_acorn_8x8.c index 069b3e80c434..fb395f0d4031 100644 --- a/lib/fonts/font_acorn_8x8.c +++ b/lib/fonts/font_acorn_8x8.c @@ -5,7 +5,7 @@ #define FONTDATAMAX 2048 -static struct font_data acorndata_8x8 = { +static const struct font_data acorndata_8x8 = { { 0, 0, FONTDATAMAX, 0 }, { /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */ /* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */ diff --git a/lib/fonts/font_mini_4x6.c b/lib/fonts/font_mini_4x6.c index 1449876c6a27..592774a90917 100644 --- a/lib/fonts/font_mini_4x6.c +++ b/lib/fonts/font_mini_4x6.c @@ -43,7 +43,7 @@ __END__; #define FONTDATAMAX 1536 -static struct font_data fontdata_mini_4x6 = { +static const struct font_data fontdata_mini_4x6 = { { 0, 0, FONTDATAMAX, 0 }, { /*{*/ /* Char 0: ' ' */ diff --git a/lib/fonts/font_pearl_8x8.c b/lib/fonts/font_pearl_8x8.c index 32d65551e7ed..a6f95ebce950 100644 --- a/lib/fonts/font_pearl_8x8.c +++ b/lib/fonts/font_pearl_8x8.c @@ -14,7 +14,7 @@ #define FONTDATAMAX 2048 -static struct font_data fontdata_pearl8x8 = { +static const struct font_data fontdata_pearl8x8 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/lib/fonts/font_sun12x22.c b/lib/fonts/font_sun12x22.c index 641a6b4dca42..a5b65bd49604 100644 --- a/lib/fonts/font_sun12x22.c +++ b/lib/fonts/font_sun12x22.c @@ -3,7 +3,7 @@ #define FONTDATAMAX 11264 -static struct font_data fontdata_sun12x22 = { +static const struct font_data fontdata_sun12x22 = { { 0, 0, FONTDATAMAX, 0 }, { /* 0 0x00 '^@' */ 0x00, 0x00, /* 000000000000 */ diff --git a/lib/fonts/font_sun8x16.c b/lib/fonts/font_sun8x16.c index 193fe6d988e0..e577e76a6a7c 100644 --- a/lib/fonts/font_sun8x16.c +++ b/lib/fonts/font_sun8x16.c @@ -3,7 +3,7 @@ #define FONTDATAMAX 4096 -static struct font_data fontdata_sun8x16 = { +static const struct font_data fontdata_sun8x16 = { { 0, 0, FONTDATAMAX, 0 }, { /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, diff --git a/lib/fonts/font_ter16x32.c b/lib/fonts/font_ter16x32.c index 91b9c283bd9c..f7c3abb6b99e 100644 --- a/lib/fonts/font_ter16x32.c +++ b/lib/fonts/font_ter16x32.c @@ -4,7 +4,7 @@ #define FONTDATAMAX 16384 -static struct font_data fontdata_ter16x32 = { +static const struct font_data fontdata_ter16x32 = { { 0, 0, FONTDATAMAX, 0 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x7f, 0xfc, -- cgit v1.2.3