mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 00:21:59 +00:00
drm/vmwgfx: Resource evict fixes
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
This commit is contained in:
parent
d92d985177
commit
ea029c28de
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user