diff options
author | Thomas Hellstrom <thomas@tungstengraphics.com> | 2006-05-26 16:39:39 +0000 |
---|---|---|
committer | Thomas Hellstrom <thomas@tungstengraphics.com> | 2006-05-26 16:39:39 +0000 |
commit | ef87f0dca8a87b21e7dc5a6a48f90d313ce5baf2 (patch) | |
tree | 8daa8e585dc5a5044c6b6d09b902bffb97fb7b1f | |
parent | 0b68227d3dcf5e5019f091c5cd93f16b9197014f (diff) |
Remove the core memory manager spinlock. It is not needed and it is buggy.
(Reported by Dave Airlie)
-rw-r--r-- | linux-core/drmP.h | 9 | ||||
-rw-r--r-- | linux-core/drm_mm.c | 18 | ||||
-rw-r--r-- | linux-core/drm_ttm.c | 30 |
3 files changed, 17 insertions, 40 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index bd30a461..18859623 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -563,7 +563,6 @@ typedef struct drm_mm_node { } drm_mm_node_t; typedef struct drm_mm { - spinlock_t mm_lock; drm_mm_node_t root_node; } drm_mm_t; @@ -1142,10 +1141,10 @@ extern void drm_ttm_fence_regions(drm_device_t * dev); * Basic memory manager support (drm_mm.c) */ -extern drm_mm_node_t * drm_mm_get_block_locked(drm_mm_node_t * parent, unsigned long size, - unsigned alignment); -extern void drm_mm_put_block_locked(drm_mm_t *mm, drm_mm_node_t *cur); -extern drm_mm_node_t *drm_mm_search_free_locked(const drm_mm_t *mm, unsigned long size, +extern drm_mm_node_t * drm_mm_get_block(drm_mm_node_t * parent, unsigned long size, + unsigned alignment); +extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur); +extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, unsigned alignment, int best_match); extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); extern void drm_mm_takedown(drm_mm_t *mm); diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index 2a230b2c..276c9370 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -40,8 +40,8 @@ #include "drmP.h" -drm_mm_node_t *drm_mm_get_block_locked(drm_mm_node_t * parent, - unsigned long size, unsigned alignment) +drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, + unsigned long size, unsigned alignment) { drm_mm_node_t *child; @@ -77,7 +77,7 @@ drm_mm_node_t *drm_mm_get_block_locked(drm_mm_node_t * parent, * Otherwise add to the free stack. */ -void drm_mm_put_block_locked(drm_mm_t * mm, drm_mm_node_t * cur) +void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) { drm_mm_node_t *list_root = &mm->root_node; @@ -120,9 +120,9 @@ void drm_mm_put_block_locked(drm_mm_t * mm, drm_mm_node_t * cur) } } -drm_mm_node_t *drm_mm_search_free_locked(const drm_mm_t * mm, - unsigned long size, - unsigned alignment, int best_match) +drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, + unsigned long size, + unsigned alignment, int best_match) { struct list_head *list; const struct list_head *free_stack = &mm->root_node.fl_entry; @@ -168,15 +168,9 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) child->size = size; child->free = TRUE; - mm->mm_lock = SPIN_LOCK_UNLOCKED; - - spin_lock(&mm->mm_lock); - list_add(&child->fl_entry, &mm->root_node.fl_entry); list_add(&child->ml_entry, &mm->root_node.ml_entry); - spin_unlock(&mm->mm_lock); - return 0; } diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index 090dd784..a52e2606 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -624,10 +624,8 @@ static int remove_ttm_region(drm_ttm_backend_list_t * entry, int ret_if_busy) } entry->mm_node = NULL; mm_node->private = NULL; - spin_lock(&mm->mm.mm_lock); list_del(&mm_priv->lru); - drm_mm_put_block_locked(&mm->mm, mm_node); - spin_unlock(&mm->mm.mm_lock); + drm_mm_put_block(&mm->mm, mm_node); drm_free(mm_priv, sizeof(*mm_priv), DRM_MEM_MM); return 0; } @@ -1097,15 +1095,12 @@ int drm_add_ttm(drm_device_t * dev, unsigned size, drm_map_list_t ** maplist) static int drm_ttm_evict_aged(drm_ttm_mm_t * mm) { struct list_head *list; - spinlock_t *mm_lock = &mm->mm.mm_lock; drm_ttm_mm_priv_t *evict_priv; uint32_t evict_fence; drm_device_t *dev = mm->dev; drm_mm_node_t *evict_node; int evicted = FALSE; - spin_lock(mm_lock); - do { list = mm->lru_head.next; @@ -1131,11 +1126,10 @@ static int drm_ttm_evict_aged(drm_ttm_mm_t * mm) drm_evict_ttm_region(evict_priv->region); list_del_init(list); evict_node->private = NULL; - drm_mm_put_block_locked(&mm->mm, evict_node); + drm_mm_put_block(&mm->mm, evict_node); evict_priv->region->mm_node = NULL; drm_free(evict_priv, sizeof(*evict_priv), DRM_MEM_MM); } while (TRUE); - spin_unlock(mm_lock); return evicted; } @@ -1158,7 +1152,6 @@ void drm_ttm_fence_regions(drm_device_t * dev) static int check_aged = 0; memset(emitted, 0, sizeof(int) * DRM_FENCE_TYPES); - spin_lock(&mm->mm.mm_lock); list_for_each_prev(list, &mm->lru_head) { drm_ttm_mm_priv_t *entry = @@ -1181,8 +1174,6 @@ void drm_ttm_fence_regions(drm_device_t * dev) entry->fence_valid = TRUE; } - spin_unlock(&mm->mm.mm_lock); - if (!(check_aged++ & 0x0F) && drm_ttm_evict_aged(mm)) { dev->mm_driver->mm_sarea->evict_tt_seq = dev->mm_driver->mm_sarea->validation_seq + 1; @@ -1199,11 +1190,10 @@ EXPORT_SYMBOL(drm_ttm_fence_regions); * May sleep while waiting for a fence. */ -static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry) +static int drm_ttm_evict_lru(drm_ttm_backend_list_t * entry) { struct list_head *list; drm_ttm_mm_t *mm = entry->mm; - spinlock_t *mm_lock = &mm->mm.mm_lock; drm_ttm_mm_priv_t *evict_priv; uint32_t evict_fence; drm_device_t *dev = mm->dev; @@ -1235,13 +1225,11 @@ static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry) evict_fence)) break; - spin_unlock(mm_lock); up(&dev->struct_sem); ret = drm_wait_buf_busy(evict_priv->region); down(&dev->struct_sem); - spin_lock(mm_lock); if (ret) { DRM_ERROR("Evict wait timed out\n"); @@ -1253,7 +1241,7 @@ static int drm_ttm_evict_lru_sl(drm_ttm_backend_list_t * entry) drm_evict_ttm_region(evict_priv->region); list_del_init(list); evict_node->private = NULL; - drm_mm_put_block_locked(&mm->mm, evict_node); + drm_mm_put_block(&mm->mm, evict_node); evict_priv->region->mm_node = NULL; drm_free(evict_priv, sizeof(*evict_priv), DRM_MEM_MM); @@ -1267,7 +1255,6 @@ static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry, { drm_mm_node_t *mm_node = entry->mm_node; drm_ttm_mm_t *mm = entry->mm; - spinlock_t *mm_lock = &mm->mm.mm_lock; drm_ttm_mm_priv_t *mm_priv; unsigned num_pages; int ret; @@ -1283,14 +1270,12 @@ static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry, num_pages = (entry->owner) ? entry->num_pages : entry->anon_locked; drm_ttm_destroy_delayed(entry->mm, TRUE); - spin_lock(mm_lock); while (!mm_node) { mm_node = - drm_mm_search_free_locked(&entry->mm->mm, num_pages, 0, 0); + drm_mm_search_free(&entry->mm->mm, num_pages, 0, 0); if (!mm_node) { - ret = drm_ttm_evict_lru_sl(entry); + ret = drm_ttm_evict_lru(entry); if (ret) { - spin_unlock(mm_lock); return ret; } action->evicted_tt = TRUE; @@ -1298,7 +1283,7 @@ static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry, } if (!entry->mm_node) { - mm_node = drm_mm_get_block_locked(mm_node, num_pages, 0); + mm_node = drm_mm_get_block(mm_node, num_pages, 0); mm_node->private = mm_priv; mm_priv->region = entry; entry->mm_node = mm_node; @@ -1326,7 +1311,6 @@ static int drm_validate_ttm_region(drm_ttm_backend_list_t * entry, break; } - spin_unlock(mm_lock); *aper_offset = mm_node->start; return 0; } |