diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2018-03-22 05:35:18 -0400 |
---|---|---|
committer | Thomas Hellstrom <thellstrom@vmware.com> | 2018-03-22 07:08:24 -0400 |
commit | 20fb5a635a0c8478ac98f15cfafc2ea83df29565 (patch) | |
tree | 21801e5254a8e7ee292d8e25e541415fadb0b134 /drivers | |
parent | 89dc15b76fd3b57d0b7d3bd3556bd6fa514e0257 (diff) |
drm/vmwgfx: Unpin the screen object backup buffer when not used
We were relying on the pinned screen object backup buffer to be destroyed
when not used. But if we hold a copy of the atomic state, like when
hibernating, the backup buffer might not be destroyed since it's
refcounted by the atomic state. This causes us to hibernate with a
buffer pinned in VRAM.
Fix this by only having the buffer pinned when it is actually used by a
screen object.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 3b7bf7ca18b9..419185f60278 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
@@ -405,7 +405,11 @@ vmw_sou_primary_plane_cleanup_fb(struct drm_plane *plane, | |||
405 | struct drm_plane_state *old_state) | 405 | struct drm_plane_state *old_state) |
406 | { | 406 | { |
407 | struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); | 407 | struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); |
408 | struct drm_crtc *crtc = plane->state->crtc ? | ||
409 | plane->state->crtc : old_state->crtc; | ||
408 | 410 | ||
411 | if (vps->dmabuf) | ||
412 | vmw_dmabuf_unpin(vmw_priv(crtc->dev), vps->dmabuf, false); | ||
409 | vmw_dmabuf_unreference(&vps->dmabuf); | 413 | vmw_dmabuf_unreference(&vps->dmabuf); |
410 | vps->dmabuf_size = 0; | 414 | vps->dmabuf_size = 0; |
411 | 415 | ||
@@ -443,10 +447,17 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, | |||
443 | } | 447 | } |
444 | 448 | ||
445 | size = new_state->crtc_w * new_state->crtc_h * 4; | 449 | size = new_state->crtc_w * new_state->crtc_h * 4; |
450 | dev_priv = vmw_priv(crtc->dev); | ||
446 | 451 | ||
447 | if (vps->dmabuf) { | 452 | if (vps->dmabuf) { |
448 | if (vps->dmabuf_size == size) | 453 | if (vps->dmabuf_size == size) { |
449 | return 0; | 454 | /* |
455 | * Note that this might temporarily up the pin-count | ||
456 | * to 2, until cleanup_fb() is called. | ||
457 | */ | ||
458 | return vmw_dmabuf_pin_in_vram(dev_priv, vps->dmabuf, | ||
459 | true); | ||
460 | } | ||
450 | 461 | ||
451 | vmw_dmabuf_unreference(&vps->dmabuf); | 462 | vmw_dmabuf_unreference(&vps->dmabuf); |
452 | vps->dmabuf_size = 0; | 463 | vps->dmabuf_size = 0; |
@@ -456,7 +467,6 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, | |||
456 | if (!vps->dmabuf) | 467 | if (!vps->dmabuf) |
457 | return -ENOMEM; | 468 | return -ENOMEM; |
458 | 469 | ||
459 | dev_priv = vmw_priv(crtc->dev); | ||
460 | vmw_svga_enable(dev_priv); | 470 | vmw_svga_enable(dev_priv); |
461 | 471 | ||
462 | /* After we have alloced the backing store might not be able to | 472 | /* After we have alloced the backing store might not be able to |
@@ -467,13 +477,16 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane, | |||
467 | &vmw_vram_ne_placement, | 477 | &vmw_vram_ne_placement, |
468 | false, &vmw_dmabuf_bo_free); | 478 | false, &vmw_dmabuf_bo_free); |
469 | vmw_overlay_resume_all(dev_priv); | 479 | vmw_overlay_resume_all(dev_priv); |
470 | 480 | if (ret) { | |
471 | if (ret != 0) | ||
472 | vps->dmabuf = NULL; /* vmw_dmabuf_init frees on error */ | 481 | vps->dmabuf = NULL; /* vmw_dmabuf_init frees on error */ |
473 | else | 482 | return ret; |
474 | vps->dmabuf_size = size; | 483 | } |
475 | 484 | ||
476 | return ret; | 485 | /* |
486 | * TTM already thinks the buffer is pinned, but make sure the | ||
487 | * pin_count is upped. | ||
488 | */ | ||
489 | return vmw_dmabuf_pin_in_vram(dev_priv, vps->dmabuf, true); | ||
477 | } | 490 | } |
478 | 491 | ||
479 | 492 | ||