[PATCH 46/55] drm: Track framebuffer references at the point of assignment
Chris Wilson
chris at chris-wilson.co.uk
Mon Sep 19 10:37:00 UTC 2016
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 2 +-
drivers/gpu/drm/armada/armada_crtc.c | 9 +--
drivers/gpu/drm/bochs/bochs_kms.c | 2 +-
drivers/gpu/drm/drm_atomic.c | 42 --------------
drivers/gpu/drm/drm_atomic_helper.c | 35 +-----------
drivers/gpu/drm/drm_crtc.c | 89 ++++++++---------------------
drivers/gpu/drm/drm_crtc_helper.c | 18 +++---
drivers/gpu/drm/drm_fb_helper.c | 17 +++---
drivers/gpu/drm/i915/intel_display.c | 16 +++---
drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +-
drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 2 +-
drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_display.c | 2 +-
drivers/gpu/drm/qxl/qxl_display.c | 4 +-
drivers/gpu/drm/radeon/radeon_display.c | 3 +-
drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 2 +-
drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 +-
drivers/gpu/drm/udl/udl_modeset.c | 2 +-
drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 4 +-
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 10 ++--
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 +-
include/drm/drm_atomic.h | 3 -
include/drm/drm_crtc.h | 20 +++++--
24 files changed, 92 insertions(+), 204 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 9af8d3c7ae8b..0d324b955008 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -225,7 +225,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_PENDING, work: %p,\n",
amdgpu_crtc->crtc_id, amdgpu_crtc, work);
/* update crtc fb */
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
amdgpu_flip_work_func(&work->flip_work.work);
return 0;
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 2f58e9e2a59c..03464dd46174 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1023,13 +1023,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
return ret;
}
- /*
- * Don't take a reference on the new framebuffer;
- * drm_mode_page_flip_ioctl() has already grabbed a reference and
- * will _not_ drop that reference on successful return from this
- * function. Simply mark this new framebuffer as the current one.
- */
- dcrtc->crtc.primary->fb = fb;
+ drm_plane_set_fb(dcrtc->crtc.primary, fb);
/*
* Finally, if the display is blanked, we won't receive an
@@ -1038,6 +1032,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
if (dpms_blanked(dcrtc->dpms))
armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary));
+ drm_framebuffer_unreference(fb);
return 0;
}
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 207a2cbcc113..8d6789e745ff 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -103,7 +103,7 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb = crtc->primary->fb;
unsigned long irqflags;
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
if (event) {
spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index f06418c91abe..c29df30f4d8f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1552,45 +1552,6 @@ static int atomic_set_prop(struct drm_atomic_state *state,
return ret;
}
-/**
- * drm_atomic_clean_old_fb -- Unset old_fb pointers and set plane->fb pointers.
- *
- * @dev: drm device to check.
- * @plane_mask: plane mask for planes that were updated.
- * @ret: return value, can be -EDEADLK for a retry.
- *
- * Before doing an update plane->old_fb is set to plane->fb,
- * but before dropping the locks old_fb needs to be set to NULL
- * and plane->fb updated. This is a common operation for each
- * atomic update, so this call is split off as a helper.
- */
-void drm_atomic_clean_old_fb(struct drm_device *dev,
- unsigned plane_mask,
- int ret)
-{
- struct drm_plane *plane;
-
- /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
- * locks (ie. while it is still safe to deref plane->state). We
- * need to do this here because the driver entry points cannot
- * distinguish between legacy and atomic ioctls.
- */
- drm_for_each_plane_mask(plane, dev, plane_mask) {
- if (ret == 0) {
- struct drm_framebuffer *new_fb = plane->state->fb;
- if (new_fb)
- drm_framebuffer_reference(new_fb);
- plane->fb = new_fb;
- plane->crtc = plane->state->crtc;
-
- if (plane->old_fb)
- drm_framebuffer_unreference(plane->old_fb);
- }
- plane->old_fb = NULL;
- }
-}
-EXPORT_SYMBOL(drm_atomic_clean_old_fb);
-
int drm_mode_atomic_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
@@ -1717,7 +1678,6 @@ retry:
!(arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)) {
plane = obj_to_plane(obj);
plane_mask |= (1 << drm_plane_index(plane));
- plane->old_fb = plane->fb;
}
drm_mode_object_unreference(obj);
}
@@ -1750,8 +1710,6 @@ retry:
}
out:
- drm_atomic_clean_old_fb(dev, plane_mask, ret);
-
if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
/*
* TEST_ONLY and PAGE_FLIP_EVENT are mutually exclusive,
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 35a6f841c385..d2ce5d1593b0 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2043,6 +2043,9 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
}
for_each_plane_in_state(state, plane, plane_state, i) {
+ drm_plane_set_fb(plane, plane_state->fb);
+ plane->crtc = plane_state->crtc;
+
plane->state->state = state;
swap(state->planes[i].state, plane->state);
plane->state->state = NULL;
@@ -2120,14 +2123,6 @@ fail:
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
-
- /*
- * Someone might have exchanged the framebuffer while we dropped locks
- * in the backoff code. We need to fix up the fb refcount tracking the
- * core does for us.
- */
- plane->old_fb = plane->fb;
-
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_update_plane);
@@ -2188,14 +2183,6 @@ fail:
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
-
- /*
- * Someone might have exchanged the framebuffer while we dropped locks
- * in the backoff code. We need to fix up the fb refcount tracking the
- * core does for us.
- */
- plane->old_fb = plane->fb;
-
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
@@ -2323,14 +2310,6 @@ fail:
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
-
- /*
- * Someone might have exchanged the framebuffer while we dropped locks
- * in the backoff code. We need to fix up the fb refcount tracking the
- * core does for us.
- */
- crtc->primary->old_fb = crtc->primary->fb;
-
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_set_config);
@@ -2801,14 +2780,6 @@ fail:
backoff:
drm_atomic_state_clear(state);
drm_atomic_legacy_backoff(state);
-
- /*
- * Someone might have exchanged the framebuffer while we dropped locks
- * in the backoff code. We need to fix up the fb refcount tracking the
- * core does for us.
- */
- plane->old_fb = plane->fb;
-
goto retry;
}
EXPORT_SYMBOL(drm_atomic_helper_page_flip);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 4af6a7525587..dd62b1e05c40 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -485,17 +485,13 @@ void drm_plane_force_disable(struct drm_plane *plane)
if (!plane->fb)
return;
- plane->old_fb = plane->fb;
ret = plane->funcs->disable_plane(plane);
if (ret) {
DRM_ERROR("failed to disable plane with busy fb\n");
- plane->old_fb = NULL;
return;
}
/* disconnect the plane from the fb and crtc: */
- drm_framebuffer_unreference(plane->old_fb);
- plane->old_fb = NULL;
- plane->fb = NULL;
+ drm_plane_set_fb(plane, NULL);
plane->crtc = NULL;
}
EXPORT_SYMBOL(drm_plane_force_disable);
@@ -1045,13 +1041,10 @@ static int __setplane_internal(struct drm_plane *plane,
/* No fb means shut it down */
if (!fb) {
- plane->old_fb = plane->fb;
ret = plane->funcs->disable_plane(plane);
if (!ret) {
+ drm_plane_set_fb(plane, NULL);
plane->crtc = NULL;
- plane->fb = NULL;
- } else {
- plane->old_fb = NULL;
}
goto out;
}
@@ -1087,25 +1080,15 @@ static int __setplane_internal(struct drm_plane *plane,
if (ret)
goto out;
- plane->old_fb = plane->fb;
ret = plane->funcs->update_plane(plane, crtc, fb,
crtc_x, crtc_y, crtc_w, crtc_h,
src_x, src_y, src_w, src_h);
if (!ret) {
plane->crtc = crtc;
- plane->fb = fb;
- fb = NULL;
- } else {
- plane->old_fb = NULL;
+ drm_plane_set_fb(plane, fb);
}
out:
- if (fb)
- drm_framebuffer_unreference(fb);
- if (plane->old_fb)
- drm_framebuffer_unreference(plane->old_fb);
- plane->old_fb = NULL;
-
return ret;
}
@@ -1149,6 +1132,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
struct drm_plane *plane;
struct drm_crtc *crtc = NULL;
struct drm_framebuffer *fb = NULL;
+ int ret;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
@@ -1184,11 +1168,16 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
* setplane_internal will take care of deref'ing either the old or new
* framebuffer depending on success.
*/
- return setplane_internal(plane, crtc, fb,
- plane_req->crtc_x, plane_req->crtc_y,
- plane_req->crtc_w, plane_req->crtc_h,
- plane_req->src_x, plane_req->src_y,
- plane_req->src_w, plane_req->src_h);
+ ret = setplane_internal(plane, crtc, fb,
+ plane_req->crtc_x, plane_req->crtc_y,
+ plane_req->crtc_w, plane_req->crtc_h,
+ plane_req->src_x, plane_req->src_y,
+ plane_req->src_w, plane_req->src_h);
+
+ if (fb)
+ drm_framebuffer_unreference(fb);
+
+ return ret;
}
/**
@@ -1204,32 +1193,13 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
int drm_mode_set_config_internal(struct drm_mode_set *set)
{
struct drm_crtc *crtc = set->crtc;
- struct drm_framebuffer *fb;
- struct drm_crtc *tmp;
+ struct drm_framebuffer *fb = set->fb;
int ret;
- /*
- * NOTE: ->set_config can also disable other crtcs (if we steal all
- * connectors from it), hence we need to refcount the fbs across all
- * crtcs. Atomic modeset will have saner semantics ...
- */
- drm_for_each_crtc(tmp, crtc->dev)
- tmp->primary->old_fb = tmp->primary->fb;
-
- fb = set->fb;
-
ret = crtc->funcs->set_config(set);
if (ret == 0) {
crtc->primary->crtc = crtc;
- crtc->primary->fb = fb;
- }
-
- drm_for_each_crtc(tmp, crtc->dev) {
- if (tmp->primary->fb)
- drm_framebuffer_reference(tmp->primary->fb);
- if (tmp->primary->old_fb)
- drm_framebuffer_unreference(tmp->primary->old_fb);
- tmp->primary->old_fb = NULL;
+ drm_plane_set_fb(crtc->primary, fb);
}
return ret;
@@ -1336,14 +1306,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
- if (!crtc->primary->fb) {
+ /* Make refcounting symmetric with the lookup path. */
+ fb = drm_plane_get_fb(crtc->primary);
+ if (!fb) {
DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
ret = -EINVAL;
goto out;
}
- fb = crtc->primary->fb;
- /* Make refcounting symmetric with the lookup path. */
- drm_framebuffer_reference(fb);
} else {
fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
if (!fb) {
@@ -1527,9 +1496,7 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
fb = NULL;
}
} else {
- fb = crtc->cursor->fb;
- if (fb)
- drm_framebuffer_reference(fb);
+ fb = drm_plane_get_fb(crtc->cursor);
}
if (req->flags & DRM_MODE_CURSOR_MOVE) {
@@ -1561,6 +1528,9 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
crtc->cursor_y = req->y;
}
+ if (fb)
+ drm_framebuffer_unreference(fb);
+
return ret;
}
@@ -2028,30 +1998,17 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}
}
- crtc->primary->old_fb = crtc->primary->fb;
if (crtc->funcs->page_flip_target)
ret = crtc->funcs->page_flip_target(crtc, fb, e,
page_flip->flags,
target_vblank);
else
ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
- if (ret) {
- /* Keep the old fb, don't unref it. */
- crtc->primary->old_fb = NULL;
- } else {
- crtc->primary->fb = fb;
- /* Unref only the old framebuffer. */
- fb = NULL;
- }
-
out:
if (ret && crtc->funcs->page_flip_target)
drm_crtc_vblank_put(crtc);
if (fb)
drm_framebuffer_unreference(fb);
- if (crtc->primary->old_fb)
- drm_framebuffer_unreference(crtc->primary->old_fb);
- crtc->primary->old_fb = NULL;
drm_modeset_unlock_crtc(crtc);
return ret;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 5d2cb138eba6..9818fd8c5988 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -177,7 +177,7 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
(*crtc_funcs->disable)(crtc);
else
(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
}
}
}
@@ -579,7 +579,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
save_set.mode = &set->crtc->mode;
save_set.x = set->crtc->x;
save_set.y = set->crtc->y;
- save_set.fb = set->crtc->primary->fb;
+ save_set.fb = drm_plane_get_fb(set->crtc->primary);
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
@@ -700,13 +700,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
DRM_DEBUG_KMS("attempting to set mode from"
" userspace\n");
drm_mode_debug_printmodeline(set->mode);
- set->crtc->primary->fb = set->fb;
+ drm_plane_set_fb(set->crtc->primary, set->fb);
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y,
save_set.fb)) {
DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
set->crtc->base.id, set->crtc->name);
- set->crtc->primary->fb = save_set.fb;
+ drm_plane_set_fb(set->crtc->primary,
+ save_set.fb);
ret = -EINVAL;
goto fail;
}
@@ -721,17 +722,18 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
} else if (fb_changed) {
set->crtc->x = set->x;
set->crtc->y = set->y;
- set->crtc->primary->fb = set->fb;
+ drm_plane_set_fb(set->crtc->primary, set->fb);
ret = crtc_funcs->mode_set_base(set->crtc,
set->x, set->y, save_set.fb);
if (ret != 0) {
set->crtc->x = save_set.x;
set->crtc->y = save_set.y;
- set->crtc->primary->fb = save_set.fb;
+ drm_plane_set_fb(set->crtc->primary, save_set.fb);
goto fail;
}
}
+ drm_framebuffer_unreference(save_set.fb);
kfree(save_connector_encoders);
kfree(save_encoder_crtcs);
return 0;
@@ -763,6 +765,7 @@ fail:
save_set.y, save_set.fb))
DRM_ERROR("failed to restore config after modeset failure\n");
+ drm_framebuffer_unreference(save_set.fb);
kfree(save_connector_encoders);
kfree(save_encoder_crtcs);
return ret;
@@ -924,7 +927,8 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
continue;
ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
- crtc->x, crtc->y, crtc->primary->fb);
+ crtc->x, crtc->y,
+ crtc->primary->fb);
/* Restoring the old config should never fail! */
if (ret == false)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 05a711ecf97a..c29ef878843a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -270,7 +270,7 @@ static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
drm_for_each_crtc(c, dev) {
if (crtc->base.id == c->base.id)
- return c->primary->fb;
+ return drm_plane_get_fb(c->primary);
}
return NULL;
@@ -290,21 +290,24 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
for (i = 0; i < helper->crtc_count; i++) {
struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
- crtc = mode_set->crtc;
- funcs = crtc->helper_private;
- fb = drm_mode_config_fb(crtc);
+ crtc = mode_set->crtc;
if (!crtc->enabled)
continue;
+ fb = drm_mode_config_fb(crtc);
if (!fb) {
DRM_ERROR("no fb to restore??\n");
continue;
}
drm_fb_helper_restore_lut_atomic(mode_set->crtc);
+
+ funcs = crtc->helper_private;
funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
crtc->y, LEAVE_ATOMIC_MODE_SET);
+
+ drm_framebuffer_unreference(fb);
}
return 0;
@@ -337,7 +340,6 @@ retry:
plane_state->rotation = DRM_ROTATE_0;
- plane->old_fb = plane->fb;
plane_mask |= 1 << drm_plane_index(plane);
/* disable non-primary: */
@@ -360,8 +362,6 @@ retry:
ret = drm_atomic_commit(state);
fail:
- drm_atomic_clean_old_fb(dev, plane_mask, ret);
-
if (ret == -EDEADLK)
goto backoff;
@@ -1347,7 +1347,6 @@ retry:
plane = mode_set->crtc->primary;
plane_mask |= (1 << drm_plane_index(plane));
- plane->old_fb = plane->fb;
}
ret = drm_atomic_commit(state);
@@ -1358,8 +1357,6 @@ retry:
info->var.yoffset = var->yoffset;
fail:
- drm_atomic_clean_old_fb(dev, plane_mask, ret);
-
if (ret == -EDEADLK)
goto backoff;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e80af54c959f..4aa68602dc01 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2823,8 +2823,8 @@ valid_fb:
if (i915_gem_object_is_tiled(obj))
dev_priv->preserve_bios_swizzle = true;
- drm_framebuffer_reference(fb);
- primary->fb = primary->state->fb = fb;
+ drm_plane_set_fb(primary, fb);
+ update_state_fb(primary);
mutex_lock(&dev->struct_mutex);
intel_state->vma =
@@ -2835,6 +2835,8 @@ valid_fb:
intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
atomic_or(to_intel_plane(primary)->frontbuffer_bit,
&obj->frontbuffer_bits);
+
+ drm_framebuffer_unreference(fb);
}
static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
@@ -12186,7 +12188,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
/* Reference the objects for the scheduled work. */
drm_framebuffer_reference(work->old_fb);
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
update_state_fb(crtc->primary);
work->pending_flip_obj = i915_gem_object_get(obj);
@@ -12291,7 +12293,7 @@ cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count);
mutex_unlock(&dev->struct_mutex);
cleanup:
- crtc->primary->fb = old_fb;
+ drm_plane_set_fb(crtc->primary, old_fb);
update_state_fb(crtc->primary);
i915_gem_object_put(obj);
@@ -13069,7 +13071,6 @@ intel_modeset_update_crtc_state(struct drm_atomic_state *state)
if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
struct drm_plane_state *plane_state = crtc->primary->state;
- crtc->primary->fb = plane_state->fb;
crtc->x = plane_state->src_x >> 16;
crtc->y = plane_state->src_y >> 16;
}
@@ -16976,10 +16977,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
if (IS_ERR(vma)) {
DRM_ERROR("failed to pin boot fb on pipe %d\n",
to_intel_crtc(c)->pipe);
- drm_framebuffer_unreference(c->primary->fb);
- c->primary->fb = NULL;
- c->primary->crtc = c->primary->state->crtc = NULL;
+ drm_plane_set_fb(c->primary, NULL);
update_state_fb(c->primary);
+ c->primary->crtc = c->primary->state->crtc = NULL;
c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 6b21cb27e1cc..a2d3ba237f45 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1392,7 +1392,7 @@ static void mga_crtc_disable(struct drm_crtc *crtc)
mgag200_bo_push_sysram(bo);
mgag200_bo_unreserve(bo);
}
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
}
/* These provide the minimum set of functions required to handle a CRTC */
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index 7c9626d92019..386fbe221401 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -180,7 +180,7 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane,
mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe),
msm_framebuffer_iova(fb, mdp4_kms->id, 3));
- plane->fb = fb;
+ drm_plane_set_fb(plane, fb);
}
static void mdp4_write_csc_config(struct mdp4_kms *mdp4_kms,
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index ba8f43278a44..d95f155248dd 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -408,7 +408,7 @@ static void set_scanout_locked(struct drm_plane *plane,
mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe),
msm_framebuffer_iova(fb, mdp5_kms->id, 3));
- plane->fb = fb;
+ drm_plane_set_fb(plane, fb);
}
/* Note: mdp5_plane->pipe_lock must be locked */
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index afbf557b23d4..d7ea64579455 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -802,7 +802,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
mutex_unlock(&cli->mutex);
/* Update the crtc struct and cleanup */
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
nouveau_bo_fence(old_bo, fence, false);
ttm_bo_unreserve(&old_bo->bo);
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 3aef12742a53..078bb5e10501 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -236,7 +236,6 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
int one_clip_rect = 1;
int ret = 0;
- crtc->primary->fb = fb;
bo_old->is_primary = false;
bo->is_primary = true;
@@ -248,6 +247,7 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
if (ret)
return ret;
+ drm_plane_set_fb(crtc->primary, fb);
qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0,
&norect, one_clip_rect, inc);
@@ -701,7 +701,7 @@ static void qxl_crtc_disable(struct drm_crtc *crtc)
ret = qxl_bo_reserve(bo, false);
qxl_bo_unpin(bo);
qxl_bo_unreserve(bo);
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
}
qxl_monitors_config_set(qdev, qcrtc->index, 0, 0, 0, 0, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 890171f08987..97eca0583792 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -581,8 +581,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
radeon_crtc->flip_work = work;
/* update crtc fb */
- crtc->primary->fb = fb;
-
+ drm_plane_set_fb(crtc->primary, fb);
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
queue_work(radeon_crtc->flip_queue, &work->flip_work);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index 6547b1db460a..fc5df59976cd 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -462,7 +462,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
}
spin_unlock_irqrestore(&dev->event_lock, flags);
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
shmob_drm_crtc_update_base(scrtc);
if (event) {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 208768922030..c45140ea824d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -246,9 +246,7 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc,
return -EBUSY;
}
- drm_framebuffer_reference(fb);
-
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags);
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index f2b2481cad52..05133ef8942c 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -380,7 +380,7 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
if (event)
drm_crtc_send_vblank_event(crtc, event);
spin_unlock_irqrestore(&dev->event_lock, flags);
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
return 0;
}
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 2682f07d8f1e..4f0a8ffe5d90 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -777,7 +777,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
* is released.
*/
drm_atomic_set_fb_for_plane(plane->state, fb);
- plane->fb = fb;
+ drm_plane_set_fb(plane, fb);
vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno,
vc4_async_page_flip_complete);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 23ec673d5e16..61a3cce08dfe 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -260,7 +260,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
connector->encoder = NULL;
encoder->crtc = NULL;
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
crtc->enabled = false;
vmw_ldu_del_active(dev_priv, ldu);
@@ -281,7 +281,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
vmw_svga_enable(dev_priv);
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
encoder->crtc = crtc;
connector->encoder = encoder;
crtc->x = set->x;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index f42359084adc..573c7407c32c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -310,7 +310,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
connector->encoder = NULL;
encoder->crtc = NULL;
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
crtc->x = 0;
crtc->y = 0;
crtc->enabled = false;
@@ -371,7 +371,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
connector->encoder = NULL;
encoder->crtc = NULL;
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
crtc->x = 0;
crtc->y = 0;
crtc->enabled = false;
@@ -384,7 +384,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
connector->encoder = encoder;
encoder->crtc = crtc;
crtc->mode = *mode;
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
crtc->x = set->x;
crtc->y = set->y;
crtc->enabled = true;
@@ -407,7 +407,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
if (!vmw_kms_crtc_flippable(dev_priv, crtc))
return -EINVAL;
- crtc->primary->fb = fb;
+ drm_plane_set_fb(crtc->primary, fb);
/* do a full screen dirty update */
vclips.x = crtc->x;
@@ -454,7 +454,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
return ret;
out_no_fence:
- crtc->primary->fb = old_fb;
+ drm_plane_set_fb(crtc->primary, old_fb);
return ret;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 94ad8d2acf9a..01c4d574fa78 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -486,7 +486,7 @@ static int vmw_stdu_bind_fb(struct vmw_private *dev_priv,
new_display_srf = NULL;
}
- crtc->primary->fb = new_fb;
+ drm_plane_set_fb(crtc->primary, new_fb);
stdu->content_fb_type = new_content_type;
return 0;
@@ -580,7 +580,7 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
if (ret)
return ret;
- crtc->primary->fb = NULL;
+ drm_plane_set_fb(crtc->primary, NULL);
crtc->enabled = false;
encoder->crtc = NULL;
connector->encoder = NULL;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 1c6210e7a791..d61425c28985 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -200,9 +200,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
void drm_atomic_legacy_backoff(struct drm_atomic_state *state);
-void
-drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret);
-
int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
int __must_check drm_atomic_commit(struct drm_atomic_state *state);
int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 9ed4c5dadc74..5dafa9c3e454 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -961,8 +961,6 @@ enum drm_plane_type {
* @format_default: driver hasn't supplied supported formats for the plane
* @crtc: currently bound CRTC
* @fb: currently bound fb
- * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by
- * drm_mode_set_config_internal() to implement correct refcounting.
* @funcs: helper functions
* @properties: property tracking for this plane
* @type: type of plane (overlay, primary, cursor)
@@ -995,8 +993,6 @@ struct drm_plane {
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
- struct drm_framebuffer *old_fb;
-
const struct drm_plane_funcs *funcs;
struct drm_object_properties properties;
@@ -2251,4 +2247,20 @@ void drm_bridge_mode_set(struct drm_bridge *bridge,
void drm_bridge_pre_enable(struct drm_bridge *bridge);
void drm_bridge_enable(struct drm_bridge *bridge);
+static inline void drm_plane_set_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb)
+{
+ if (plane->fb != fb)
+ drm_framebuffer_assign(&plane->fb, fb);
+}
+
+static inline struct drm_framebuffer *
+drm_plane_get_fb(struct drm_plane *plane)
+{
+ struct drm_framebuffer *fb = plane->fb;
+ if (fb)
+ drm_framebuffer_reference(fb);
+ return fb;
+}
+
#endif /* __DRM_CRTC_H__ */
--
2.9.3
More information about the Intel-gfx-trybot
mailing list