Commit 796b556c authored by Dave Airlie's avatar Dave Airlie

Merge tag 'vmwgfx-fixes-2021-04-14' of gitlab.freedesktop.org:zack/vmwgfx into drm-fixes

vmwgfx fixes for regressions in 5.12

Here's a set of 3 patches fixing ugly regressions
in the vmwgfx driver. We broke lock initialization
code and ended up using spinlocks before initialization
breaking lockdep.
Also there was a bit of a fallout from drm changes
which made the core validate that unreferenced buffers
have been unpinned. vmwgfx pinning code predates a lot
of the core drm and wasn't written to account for those
semantics. Fortunately changes required to fix it
are not too intrusive.
The changes have been validated by our internal ci.
Signed-off-by: default avatarZack Rusin <zackr@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Zack Rusin <zackr@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/f7add0a2-162e-3bd2-b1be-344a94f2acbf@vmware.com
parents 4d2e1288 2ef4fb92
...@@ -481,11 +481,15 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size) ...@@ -481,11 +481,15 @@ static int vmw_cotable_resize(struct vmw_resource *res, size_t new_size)
vmw_bo_unreference(&old_buf); vmw_bo_unreference(&old_buf);
res->id = vcotbl->type; res->id = vcotbl->type;
/* Release the pin acquired in vmw_bo_init */
ttm_bo_unpin(bo);
return 0; return 0;
out_map_new: out_map_new:
ttm_bo_kunmap(&old_map); ttm_bo_kunmap(&old_map);
out_wait: out_wait:
ttm_bo_unpin(bo);
ttm_bo_unreserve(bo); ttm_bo_unreserve(bo);
vmw_bo_unreference(&buf); vmw_bo_unreference(&buf);
......
...@@ -712,17 +712,8 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) ...@@ -712,17 +712,8 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
dev_priv->last_read_seqno = (uint32_t) -100; dev_priv->last_read_seqno = (uint32_t) -100;
dev_priv->drm.dev_private = dev_priv; dev_priv->drm.dev_private = dev_priv;
ret = vmw_setup_pci_resources(dev_priv, pci_id);
if (ret)
return ret;
ret = vmw_detect_version(dev_priv);
if (ret)
goto out_no_pci_or_version;
mutex_init(&dev_priv->cmdbuf_mutex); mutex_init(&dev_priv->cmdbuf_mutex);
mutex_init(&dev_priv->release_mutex);
mutex_init(&dev_priv->binding_mutex); mutex_init(&dev_priv->binding_mutex);
mutex_init(&dev_priv->global_kms_state_mutex);
ttm_lock_init(&dev_priv->reservation_sem); ttm_lock_init(&dev_priv->reservation_sem);
spin_lock_init(&dev_priv->resource_lock); spin_lock_init(&dev_priv->resource_lock);
spin_lock_init(&dev_priv->hw_lock); spin_lock_init(&dev_priv->hw_lock);
...@@ -730,6 +721,14 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) ...@@ -730,6 +721,14 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
spin_lock_init(&dev_priv->cap_lock); spin_lock_init(&dev_priv->cap_lock);
spin_lock_init(&dev_priv->cursor_lock); spin_lock_init(&dev_priv->cursor_lock);
ret = vmw_setup_pci_resources(dev_priv, pci_id);
if (ret)
return ret;
ret = vmw_detect_version(dev_priv);
if (ret)
goto out_no_pci_or_version;
for (i = vmw_res_context; i < vmw_res_max; ++i) { for (i = vmw_res_context; i < vmw_res_max; ++i) {
idr_init(&dev_priv->res_idr[i]); idr_init(&dev_priv->res_idr[i]);
INIT_LIST_HEAD(&dev_priv->res_lru[i]); INIT_LIST_HEAD(&dev_priv->res_lru[i]);
......
...@@ -529,7 +529,6 @@ struct vmw_private { ...@@ -529,7 +529,6 @@ struct vmw_private {
struct vmw_overlay *overlay_priv; struct vmw_overlay *overlay_priv;
struct drm_property *hotplug_mode_update_property; struct drm_property *hotplug_mode_update_property;
struct drm_property *implicit_placement_property; struct drm_property *implicit_placement_property;
struct mutex global_kms_state_mutex;
spinlock_t cursor_lock; spinlock_t cursor_lock;
struct drm_atomic_state *suspend_state; struct drm_atomic_state *suspend_state;
...@@ -592,7 +591,6 @@ struct vmw_private { ...@@ -592,7 +591,6 @@ struct vmw_private {
bool refuse_hibernation; bool refuse_hibernation;
bool suspend_locked; bool suspend_locked;
struct mutex release_mutex;
atomic_t num_fifo_resources; atomic_t num_fifo_resources;
/* /*
...@@ -1524,9 +1522,8 @@ static inline void vmw_bo_unreference(struct vmw_buffer_object **buf) ...@@ -1524,9 +1522,8 @@ static inline void vmw_bo_unreference(struct vmw_buffer_object **buf)
struct vmw_buffer_object *tmp_buf = *buf; struct vmw_buffer_object *tmp_buf = *buf;
*buf = NULL; *buf = NULL;
if (tmp_buf != NULL) { if (tmp_buf != NULL)
ttm_bo_put(&tmp_buf->base); ttm_bo_put(&tmp_buf->base);
}
} }
static inline struct vmw_buffer_object * static inline struct vmw_buffer_object *
......
...@@ -94,6 +94,16 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob, ...@@ -94,6 +94,16 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob,
struct vmw_piter data_iter, struct vmw_piter data_iter,
unsigned long num_data_pages); unsigned long num_data_pages);
static inline void vmw_bo_unpin_unlocked(struct ttm_buffer_object *bo)
{
int ret = ttm_bo_reserve(bo, false, true, NULL);
BUG_ON(ret != 0);
ttm_bo_unpin(bo);
ttm_bo_unreserve(bo);
}
/* /*
* vmw_setup_otable_base - Issue an object table base setup command to * vmw_setup_otable_base - Issue an object table base setup command to
* the device * the device
...@@ -277,6 +287,7 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv, ...@@ -277,6 +287,7 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv,
&batch->otables[i]); &batch->otables[i]);
} }
vmw_bo_unpin_unlocked(batch->otable_bo);
ttm_bo_put(batch->otable_bo); ttm_bo_put(batch->otable_bo);
batch->otable_bo = NULL; batch->otable_bo = NULL;
return ret; return ret;
...@@ -340,6 +351,7 @@ static void vmw_otable_batch_takedown(struct vmw_private *dev_priv, ...@@ -340,6 +351,7 @@ static void vmw_otable_batch_takedown(struct vmw_private *dev_priv,
BUG_ON(ret != 0); BUG_ON(ret != 0);
vmw_bo_fence_single(bo, NULL); vmw_bo_fence_single(bo, NULL);
ttm_bo_unpin(bo);
ttm_bo_unreserve(bo); ttm_bo_unreserve(bo);
ttm_bo_put(batch->otable_bo); ttm_bo_put(batch->otable_bo);
...@@ -528,6 +540,7 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob, ...@@ -528,6 +540,7 @@ static void vmw_mob_pt_setup(struct vmw_mob *mob,
void vmw_mob_destroy(struct vmw_mob *mob) void vmw_mob_destroy(struct vmw_mob *mob)
{ {
if (mob->pt_bo) { if (mob->pt_bo) {
vmw_bo_unpin_unlocked(mob->pt_bo);
ttm_bo_put(mob->pt_bo); ttm_bo_put(mob->pt_bo);
mob->pt_bo = NULL; mob->pt_bo = NULL;
} }
...@@ -643,6 +656,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, ...@@ -643,6 +656,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
out_no_cmd_space: out_no_cmd_space:
vmw_fifo_resource_dec(dev_priv); vmw_fifo_resource_dec(dev_priv);
if (pt_set_up) { if (pt_set_up) {
vmw_bo_unpin_unlocked(mob->pt_bo);
ttm_bo_put(mob->pt_bo); ttm_bo_put(mob->pt_bo);
mob->pt_bo = NULL; mob->pt_bo = NULL;
} }
......
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