summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2007-02-12 20:32:03 +0100
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2007-02-12 20:32:03 +0100
commitb0c5339ed69c6ff08b7817f870e895aae2ef04c7 (patch)
treeba02dd34d7ab721298de2ce16a9c774713817ad5
parentf02f83ee08a2bb87700544a9b67f475532e84af4 (diff)
More bugfixes.
-rw-r--r--linux-core/drm_bo.c58
-rw-r--r--linux-core/drm_bo_move.c9
2 files changed, 34 insertions, 33 deletions
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 814175cd..48cb5ef4 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -692,8 +692,6 @@ out:
return ret;
}
-
-
static int drm_bo_mem_force_space(drm_device_t *dev,
drm_bo_mem_reg_t *mem,
uint32_t mem_type,
@@ -744,7 +742,6 @@ static int drm_bo_mem_force_space(drm_device_t *dev,
return 0;
}
-
static int drm_bo_mt_compatible(drm_mem_type_manager_t *man,
uint32_t mem_type,
uint32_t mask,
@@ -777,7 +774,6 @@ static int drm_bo_mt_compatible(drm_mem_type_manager_t *man,
return 1;
}
-
int drm_bo_mem_space(drm_buffer_object_t *bo,
drm_bo_mem_reg_t *mem,
int no_wait)
@@ -1817,10 +1813,8 @@ static int drm_bo_leave_list(drm_buffer_object_t *bo,
if (bo->pinned_node == bo->mem.mm_node)
bo->pinned_node = NULL;
if (bo->pinned_node != NULL) {
- mutex_lock(&dev->struct_mutex);
drm_mm_put_block(bo->pinned_node);
bo->pinned_node = NULL;
- mutex_unlock(&dev->struct_mutex);
}
mutex_unlock(&dev->struct_mutex);
}
@@ -1831,8 +1825,9 @@ static int drm_bo_leave_list(drm_buffer_object_t *bo,
bo->mem.flags &= ~DRM_BO_FLAG_NO_EVICT;
bo->mem.mask &= ~DRM_BO_FLAG_NO_EVICT;
}
-
- ret = drm_bo_evict(bo, mem_type, 0);
+
+ if (bo->mem.mem_type == mem_type)
+ ret = drm_bo_evict(bo, mem_type, 0);
if (ret){
if (allow_errors){
@@ -1862,29 +1857,40 @@ static int drm_bo_force_list_clean(drm_device_t * dev,
int allow_errors,
int pinned_list)
{
- struct list_head *list;
+ struct list_head *list, *next;
drm_buffer_object_t *entry;
int ret;
+ int do_retry;
- list = head->next;
- while(list != head) {
+ /*
+ * We need to
+ * restart if a node disappears from under us.
+ * Nodes cannot be added since the hardware lock is needed
+ * For this operation.
+ */
+
+retry:
+ list_for_each_safe(list, next, head) {
if (pinned_list)
entry = list_entry(list, drm_buffer_object_t,
pinned_lru);
else
entry = list_entry(list, drm_buffer_object_t,
lru);
-
+ atomic_inc(&entry->usage);
ret = drm_bo_leave_list(entry, mem_type, free_pinned,
allow_errors);
-
+
+ do_retry = list->next != next;
+ drm_bo_usage_deref_locked(entry);
+
if (ret)
return ret;
-
- list = head->next;
+
+ if (do_retry)
+ goto retry;
}
- return 0;
-
+ return 0;
}
int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
@@ -1909,12 +1915,7 @@ int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
ret = 0;
if (mem_type > 0) {
- /*
- * Throw out unfenced buffers.
- */
-
drm_bo_force_list_clean(dev, &bm->unfenced, mem_type, 1, 0, 0);
-
drm_bo_force_list_clean(dev, &man->lru, mem_type, 1, 0, 0);
drm_bo_force_list_clean(dev, &man->pinned, mem_type, 1, 0, 1);
@@ -1928,6 +1929,12 @@ int drm_bo_clean_mm(drm_device_t * dev, unsigned mem_type)
return ret;
}
+/**
+ *Evict all buffers of a particular mem_type, but leave memory manager
+ *regions for NO_MOVE buffers intact. New buffers cannot be added at this
+ *point since we have the hardware lock.
+ */
+
static int drm_bo_lock_mm(drm_device_t * dev, unsigned mem_type)
{
int ret;
@@ -1942,11 +1949,8 @@ static int drm_bo_lock_mm(drm_device_t * dev, unsigned mem_type)
ret = drm_bo_force_list_clean(dev, &bm->unfenced, mem_type, 0, 1, 0);
if (ret)
return ret;
- ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 1);
- if (ret)
- return ret;
- ret =
- drm_bo_force_list_clean(dev, &man->pinned, mem_type, 0, 1, 1);
+ ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 0);
+
return ret;
}
diff --git a/linux-core/drm_bo_move.c b/linux-core/drm_bo_move.c
index c6fe4ec2..1d142087 100644
--- a/linux-core/drm_bo_move.c
+++ b/linux-core/drm_bo_move.c
@@ -365,7 +365,8 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo,
*/
if (1)
#else
- if (evict)
+ if (evict || ((bo->mem.mm_node == bo->pinned_node) &&
+ bo->mem.mm_node != NULL))
#endif
{
ret = drm_bo_wait(bo, 0, 1, 0);
@@ -402,11 +403,7 @@ int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo,
mutex_lock(&dev->struct_mutex);
list_del_init(&old_obj->lru);
DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
-
- if (old_obj->mem.mm_node == bo->pinned_node)
- old_obj->mem.mm_node = NULL;
- else
- drm_bo_add_to_lru(old_obj);
+ drm_bo_add_to_lru(old_obj);
drm_bo_usage_deref_locked(old_obj);
mutex_unlock(&dev->struct_mutex);