Commit a02cbe2e authored by Dave Airlie's avatar Dave Airlie

Merge branch 'vmwgfx-fixes-4.17' of git://people.freedesktop.org/~thomash/linux into drm-fixes

Two fixes for now, one for a long standing problem uncovered by a commit
in the 4.17 merge window, one for a regression introduced by a previous
bugfix, Cc'd stable.

* 'vmwgfx-fixes-4.17' of git://people.freedesktop.org/~thomash/linux:
  drm/vmwgfx: Fix a buffer object leak
  drm/vmwgfx: Clean up fbdev modeset locking
parents 1e5fbc0b 13f149d4
...@@ -441,11 +441,11 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set) ...@@ -441,11 +441,11 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set)
struct drm_crtc *crtc = set->crtc; struct drm_crtc *crtc = set->crtc;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct drm_crtc *tmp; struct drm_crtc *tmp;
struct drm_modeset_acquire_ctx *ctx;
struct drm_device *dev = set->crtc->dev; struct drm_device *dev = set->crtc->dev;
struct drm_modeset_acquire_ctx ctx;
int ret; int ret;
ctx = dev->mode_config.acquire_ctx; drm_modeset_acquire_init(&ctx, 0);
restart: restart:
/* /*
...@@ -458,7 +458,7 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set) ...@@ -458,7 +458,7 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set)
fb = set->fb; fb = set->fb;
ret = crtc->funcs->set_config(set, ctx); ret = crtc->funcs->set_config(set, &ctx);
if (ret == 0) { if (ret == 0) {
crtc->primary->crtc = crtc; crtc->primary->crtc = crtc;
crtc->primary->fb = fb; crtc->primary->fb = fb;
...@@ -473,20 +473,13 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set) ...@@ -473,20 +473,13 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set)
} }
if (ret == -EDEADLK) { if (ret == -EDEADLK) {
dev->mode_config.acquire_ctx = NULL; drm_modeset_backoff(&ctx);
retry_locking:
drm_modeset_backoff(ctx);
ret = drm_modeset_lock_all_ctx(dev, ctx);
if (ret)
goto retry_locking;
dev->mode_config.acquire_ctx = ctx;
goto restart; goto restart;
} }
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
return ret; return ret;
} }
...@@ -624,7 +617,6 @@ static int vmw_fb_set_par(struct fb_info *info) ...@@ -624,7 +617,6 @@ static int vmw_fb_set_par(struct fb_info *info)
} }
mutex_lock(&par->bo_mutex); mutex_lock(&par->bo_mutex);
drm_modeset_lock_all(vmw_priv->dev);
ret = vmw_fb_kms_framebuffer(info); ret = vmw_fb_kms_framebuffer(info);
if (ret) if (ret)
goto out_unlock; goto out_unlock;
...@@ -657,7 +649,6 @@ static int vmw_fb_set_par(struct fb_info *info) ...@@ -657,7 +649,6 @@ static int vmw_fb_set_par(struct fb_info *info)
drm_mode_destroy(vmw_priv->dev, old_mode); drm_mode_destroy(vmw_priv->dev, old_mode);
par->set_mode = mode; par->set_mode = mode;
drm_modeset_unlock_all(vmw_priv->dev);
mutex_unlock(&par->bo_mutex); mutex_unlock(&par->bo_mutex);
return ret; return ret;
...@@ -713,18 +704,14 @@ int vmw_fb_init(struct vmw_private *vmw_priv) ...@@ -713,18 +704,14 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
par->max_width = fb_width; par->max_width = fb_width;
par->max_height = fb_height; par->max_height = fb_height;
drm_modeset_lock_all(vmw_priv->dev);
ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width, ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width,
par->max_height, &par->con, par->max_height, &par->con,
&par->crtc, &init_mode); &par->crtc, &init_mode);
if (ret) { if (ret)
drm_modeset_unlock_all(vmw_priv->dev);
goto err_kms; goto err_kms;
}
info->var.xres = init_mode->hdisplay; info->var.xres = init_mode->hdisplay;
info->var.yres = init_mode->vdisplay; info->var.yres = init_mode->vdisplay;
drm_modeset_unlock_all(vmw_priv->dev);
/* /*
* Create buffers and alloc memory * Create buffers and alloc memory
...@@ -832,7 +819,9 @@ int vmw_fb_close(struct vmw_private *vmw_priv) ...@@ -832,7 +819,9 @@ int vmw_fb_close(struct vmw_private *vmw_priv)
cancel_delayed_work_sync(&par->local_work); cancel_delayed_work_sync(&par->local_work);
unregister_framebuffer(info); unregister_framebuffer(info);
mutex_lock(&par->bo_mutex);
(void) vmw_fb_kms_detach(par, true, true); (void) vmw_fb_kms_detach(par, true, true);
mutex_unlock(&par->bo_mutex);
vfree(par->vmalloc); vfree(par->vmalloc);
framebuffer_release(info); framebuffer_release(info);
......
...@@ -2595,6 +2595,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, ...@@ -2595,6 +2595,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
out_fence, NULL); out_fence, NULL);
vmw_dmabuf_unreference(&ctx->buf);
vmw_resource_unreserve(res, false, NULL, 0); vmw_resource_unreserve(res, false, NULL, 0);
mutex_unlock(&res->dev_priv->cmdbuf_mutex); mutex_unlock(&res->dev_priv->cmdbuf_mutex);
} }
...@@ -2680,7 +2681,9 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -2680,7 +2681,9 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
struct vmw_display_unit *du; struct vmw_display_unit *du;
struct drm_display_mode *mode; struct drm_display_mode *mode;
int i = 0; int i = 0;
int ret = 0;
mutex_lock(&dev_priv->dev->mode_config.mutex);
list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list, list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list,
head) { head) {
if (i == unit) if (i == unit)
...@@ -2691,7 +2694,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -2691,7 +2694,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
if (i != unit) { if (i != unit) {
DRM_ERROR("Could not find initial display unit.\n"); DRM_ERROR("Could not find initial display unit.\n");
return -EINVAL; ret = -EINVAL;
goto out_unlock;
} }
if (list_empty(&con->modes)) if (list_empty(&con->modes))
...@@ -2699,7 +2703,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -2699,7 +2703,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
if (list_empty(&con->modes)) { if (list_empty(&con->modes)) {
DRM_ERROR("Could not find initial display mode.\n"); DRM_ERROR("Could not find initial display mode.\n");
return -EINVAL; ret = -EINVAL;
goto out_unlock;
} }
du = vmw_connector_to_du(con); du = vmw_connector_to_du(con);
...@@ -2720,7 +2725,10 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, ...@@ -2720,7 +2725,10 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
head); head);
} }
return 0; out_unlock:
mutex_unlock(&dev_priv->dev->mode_config.mutex);
return ret;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment