diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 10:30:17 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-16 10:30:17 -0800 |
commit | c5113e3d66d7c7140fe854c7638a27eb3a23fd7d (patch) | |
tree | 9247edfcfa87132e15a277d6f2359b303c24da29 /drivers/gpu/drm/ttm/ttm_bo.c | |
parent | 9b2831704e9250269032e3b8c2ffdfca09fd2851 (diff) | |
parent | d785d78bbdb53580b12c40e820af5a3281ce2fc8 (diff) |
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm/radeon/kms: fix r100->r500 CS checker for compressed textures. (v2)
drm/radeon/kms: allow for texture tiling
drm/radeon/kms: init pm on all chipsets
drm/radeon/kms: HDMI support for R600 KMS
drm/radeon/kms: make sure mc is initialized before mapping blit bo
drm/radeon/kms: Return to userspace on ERESTARTSYS
drm/radeon/gem: don't leak a gem object if reserve fails on get tiling (v2)
drm/radeon/kms: don't report allocate failure on ERESTARTSYS
drm/radeon/kms: Check if bo we got from ttm are radeon object or not
drm/radeon/kms: If no placement is supplied fallback to system
drm/ttm: Fix memory type manager debug information printing
drm/ttm: Fix printk format & compute bo->mem.size at bo initialization
drm/ttm: Fix potential ttm_mem_evict_first races.
drm/ttm: Delayed delete fixes.
drm/ttm: fix two bugs in new placement routines.
drm/ttm: fix incorrect logic in ttm_bo_io path
drm/nouveau: remove use of -ERESTART
nouveau: Fix endianness with new context program loader
drm/nouveau: fix build with CONFIG_AGP=n
drm/nouveau: fix ch7006 build
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo.c')
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 1fbb2eea5e8..2920f9a279e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -71,34 +71,34 @@ static inline int ttm_mem_type_from_flags(uint32_t flags, uint32_t *mem_type) return -EINVAL; } -static void ttm_mem_type_manager_debug(struct ttm_bo_global *glob, - struct ttm_mem_type_manager *man) +static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type) { + struct ttm_mem_type_manager *man = &bdev->man[mem_type]; + printk(KERN_ERR TTM_PFX " has_type: %d\n", man->has_type); printk(KERN_ERR TTM_PFX " use_type: %d\n", man->use_type); printk(KERN_ERR TTM_PFX " flags: 0x%08X\n", man->flags); printk(KERN_ERR TTM_PFX " gpu_offset: 0x%08lX\n", man->gpu_offset); printk(KERN_ERR TTM_PFX " io_offset: 0x%08lX\n", man->io_offset); printk(KERN_ERR TTM_PFX " io_size: %ld\n", man->io_size); - printk(KERN_ERR TTM_PFX " size: %ld\n", (unsigned long)man->size); + printk(KERN_ERR TTM_PFX " size: %llu\n", man->size); printk(KERN_ERR TTM_PFX " available_caching: 0x%08X\n", man->available_caching); printk(KERN_ERR TTM_PFX " default_caching: 0x%08X\n", man->default_caching); - spin_lock(&glob->lru_lock); - drm_mm_debug_table(&man->manager, TTM_PFX); - spin_unlock(&glob->lru_lock); + if (mem_type != TTM_PL_SYSTEM) { + spin_lock(&bdev->glob->lru_lock); + drm_mm_debug_table(&man->manager, TTM_PFX); + spin_unlock(&bdev->glob->lru_lock); + } } static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, struct ttm_placement *placement) { - struct ttm_bo_device *bdev = bo->bdev; - struct ttm_bo_global *glob = bo->glob; - struct ttm_mem_type_manager *man; int i, ret, mem_type; - printk(KERN_ERR TTM_PFX "No space for %p (%ld pages, %ldK, %ldM)\n", + printk(KERN_ERR TTM_PFX "No space for %p (%lu pages, %luK, %luM)\n", bo, bo->mem.num_pages, bo->mem.size >> 10, bo->mem.size >> 20); for (i = 0; i < placement->num_placement; i++) { @@ -106,10 +106,9 @@ static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, &mem_type); if (ret) return; - man = &bdev->man[mem_type]; printk(KERN_ERR TTM_PFX " placement[%d]=0x%08X (%d)\n", i, placement->placement[i], mem_type); - ttm_mem_type_manager_debug(glob, man); + ttm_mem_type_debug(bo->bdev, mem_type); } } @@ -465,6 +464,8 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) spin_unlock(&bo->lock); spin_lock(&glob->lru_lock); + put_count = ttm_bo_del_from_lru(bo); + ret = ttm_bo_reserve_locked(bo, false, false, false, 0); BUG_ON(ret); if (bo->ttm) @@ -472,20 +473,19 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) if (!list_empty(&bo->ddestroy)) { list_del_init(&bo->ddestroy); - kref_put(&bo->list_kref, ttm_bo_ref_bug); + ++put_count; } if (bo->mem.mm_node) { bo->mem.mm_node->private = NULL; drm_mm_put_block(bo->mem.mm_node); bo->mem.mm_node = NULL; } - put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); atomic_set(&bo->reserved, 0); while (put_count--) - kref_put(&bo->list_kref, ttm_bo_release_list); + kref_put(&bo->list_kref, ttm_bo_ref_bug); return 0; } @@ -684,19 +684,45 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo; int ret, put_count = 0; +retry: spin_lock(&glob->lru_lock); + if (list_empty(&man->lru)) { + spin_unlock(&glob->lru_lock); + return -EBUSY; + } + bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru); kref_get(&bo->list_kref); - ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, false, 0); - if (likely(ret == 0)) - put_count = ttm_bo_del_from_lru(bo); + + ret = ttm_bo_reserve_locked(bo, false, true, false, 0); + + if (unlikely(ret == -EBUSY)) { + spin_unlock(&glob->lru_lock); + if (likely(!no_wait)) + ret = ttm_bo_wait_unreserved(bo, interruptible); + + kref_put(&bo->list_kref, ttm_bo_release_list); + + /** + * We *need* to retry after releasing the lru lock. + */ + + if (unlikely(ret != 0)) + return ret; + goto retry; + } + + put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); - if (unlikely(ret != 0)) - return ret; + + BUG_ON(ret != 0); + while (put_count--) kref_put(&bo->list_kref, ttm_bo_ref_bug); + ret = ttm_bo_evict(bo, interruptible, no_wait); ttm_bo_unreserve(bo); + kref_put(&bo->list_kref, ttm_bo_release_list); return ret; } @@ -849,7 +875,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, int i, ret; mem->mm_node = NULL; - for (i = 0; i <= placement->num_placement; ++i) { + for (i = 0; i < placement->num_placement; ++i) { ret = ttm_mem_type_from_flags(placement->placement[i], &mem_type); if (ret) @@ -900,8 +926,8 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, if (!type_found) return -EINVAL; - for (i = 0; i <= placement->num_busy_placement; ++i) { - ret = ttm_mem_type_from_flags(placement->placement[i], + for (i = 0; i < placement->num_busy_placement; ++i) { + ret = ttm_mem_type_from_flags(placement->busy_placement[i], &mem_type); if (ret) return ret; @@ -911,7 +937,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, if (!ttm_bo_mt_compatible(man, bo->type == ttm_bo_type_user, mem_type, - placement->placement[i], + placement->busy_placement[i], &cur_flags)) continue; @@ -921,7 +947,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, * Use the access and other non-mapping-related flag bits from * the memory placement flags to the current flags */ - ttm_flag_masked(&cur_flags, placement->placement[i], + ttm_flag_masked(&cur_flags, placement->busy_placement[i], ~TTM_PL_MASK_MEMTYPE); ret = ttm_bo_mem_force_space(bo, mem_type, placement, mem, @@ -1115,6 +1141,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, bo->glob = bdev->glob; bo->type = type; bo->num_pages = num_pages; + bo->mem.size = num_pages << PAGE_SHIFT; bo->mem.mem_type = TTM_PL_SYSTEM; bo->mem.num_pages = bo->num_pages; bo->mem.mm_node = NULL; |