Skip to content

Commit

Permalink
drm/vmwgfx: Resource evict fixes
Browse files Browse the repository at this point in the history
Fix an error message that was incorrectly blaming device resource id
shortage.

Also make sure we correctly catch resource eviction errors, that
could otherwise lead to evictable resources temporarily not being on the
LRU list.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
Cc: stable@vger.kernel.org
  • Loading branch information
Thomas Hellstrom committed Nov 13, 2013
1 parent d92d985 commit ea029c2
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <drm/drmP.h>
#include "vmwgfx_resource_priv.h"

#define VMW_RES_EVICT_ERR_COUNT 10

struct vmw_user_dma_buffer {
struct ttm_base_object base;
struct vmw_dma_buffer dma;
Expand Down Expand Up @@ -1091,8 +1093,9 @@ vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
* to a backup buffer.
*
* @res: The resource to evict.
* @interruptible: Whether to wait interruptible.
*/
int vmw_resource_do_evict(struct vmw_resource *res)
int vmw_resource_do_evict(struct vmw_resource *res, bool interruptible)
{
struct ttm_validate_buffer val_buf;
const struct vmw_res_func *func = res->func;
Expand All @@ -1102,7 +1105,8 @@ int vmw_resource_do_evict(struct vmw_resource *res)
BUG_ON(!func->may_evict);

val_buf.bo = NULL;
ret = vmw_resource_check_buffer(res, &ticket, true, &val_buf);
ret = vmw_resource_check_buffer(res, &ticket, interruptible,
&val_buf);
if (unlikely(ret != 0))
return ret;

Expand Down Expand Up @@ -1141,6 +1145,7 @@ int vmw_resource_validate(struct vmw_resource *res)
struct vmw_private *dev_priv = res->dev_priv;
struct list_head *lru_list = &dev_priv->res_lru[res->func->res_type];
struct ttm_validate_buffer val_buf;
unsigned err_count = 0;

if (likely(!res->func->may_evict))
return 0;
Expand All @@ -1155,7 +1160,7 @@ int vmw_resource_validate(struct vmw_resource *res)

write_lock(&dev_priv->resource_lock);
if (list_empty(lru_list) || !res->func->may_evict) {
DRM_ERROR("Out of device device id entries "
DRM_ERROR("Out of device device resources "
"for %s.\n", res->func->type_name);
ret = -EBUSY;
write_unlock(&dev_priv->resource_lock);
Expand All @@ -1168,7 +1173,19 @@ int vmw_resource_validate(struct vmw_resource *res)
list_del_init(&evict_res->lru_head);

write_unlock(&dev_priv->resource_lock);
vmw_resource_do_evict(evict_res);

ret = vmw_resource_do_evict(evict_res, true);
if (unlikely(ret != 0)) {
write_lock(&dev_priv->resource_lock);
list_add_tail(&evict_res->lru_head, lru_list);
write_unlock(&dev_priv->resource_lock);
if (ret == -ERESTARTSYS ||
++err_count > VMW_RES_EVICT_ERR_COUNT) {
vmw_resource_unreference(&evict_res);
goto out_no_validate;
}
}

vmw_resource_unreference(&evict_res);
} while (1);

Expand Down Expand Up @@ -1253,13 +1270,15 @@ bool vmw_resource_needs_backup(const struct vmw_resource *res)
* @type: The resource type to evict
*
* To avoid thrashing starvation or as part of the hibernation sequence,
* evict all evictable resources of a specific type.
* try to evict all evictable resources of a specific type.
*/
static void vmw_resource_evict_type(struct vmw_private *dev_priv,
enum vmw_res_type type)
{
struct list_head *lru_list = &dev_priv->res_lru[type];
struct vmw_resource *evict_res;
unsigned err_count = 0;
int ret;

do {
write_lock(&dev_priv->resource_lock);
Expand All @@ -1272,7 +1291,18 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
lru_head));
list_del_init(&evict_res->lru_head);
write_unlock(&dev_priv->resource_lock);
vmw_resource_do_evict(evict_res);

ret = vmw_resource_do_evict(evict_res, false);
if (unlikely(ret != 0)) {
write_lock(&dev_priv->resource_lock);
list_add_tail(&evict_res->lru_head, lru_list);
write_unlock(&dev_priv->resource_lock);
if (++err_count > VMW_RES_EVICT_ERR_COUNT) {
vmw_resource_unreference(&evict_res);
return;
}
}

vmw_resource_unreference(&evict_res);
} while (1);

Expand Down

0 comments on commit ea029c2

Please sign in to comment.