On Fri, 2009-04-10 at 10:14 +0200, Thomas Hellström wrote:
> Jerome Glisse wrote:
> > On Wed, 2009-04-08 at 16:47 +0200, Thomas Hellstrom wrote:
> >
> >> Jerome Glisse wrote:
> >>
> >>> Hi Thomas,
> >>>
> >>> I think we should not ttm_bo_unreserve the bo in
> >>> ttm_bo_move_accel_cleanup i am seeing double unreserve
> >>> which likely lead to kernel list corruption and i
> >>> think it's due to that one (i am checking through
> >>> printk but the log is enormous and my script is not
> >>> yet done with parsing it)
> >>>
> >>> I checked code path in via using ttm_bo_move_accel_cleanup
> >>> and none seems to reserve the buffer before calling
> >>> ttm_bo_move_accel_cleanup.
> >>>
> >>>
> >>>
> >> Jerome,
> >>
> >> All buffers that are touched by the move code need to be reserved.
> >> What happens in the above case is that the buffer is copied in its
> >> reserved state,
> >> and thus there will be an unreserve for each copy.
> >>
> >> Please make sure, however, that you got all of the
> >> buffer_object_transfer fixes from the newttm branch,
> >> in particular the one where we clear the fbo->swap list head.
> >>
> >> /Thomas
> >>
> >
> > There is a bug in cleanup:
> > if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
> > ghost_obj->ttm = NULL;
> > else
> > ghost_obj = NULL;
> > Used to be
> > if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
> > ghost_obj->ttm = NULL;
> > else
> > bo->ttm = NULL;
> >
> > And i think it's the correct one. Note that current one lead
> > to oups because then you unreserve a NULL ptr.
> >
> >
> Jerome,
> You're right. Does that fix your list corruption?
>
> /Thomas
I have no more list corruption but my tree have few other fixes
it would be nice if you could check if my not missunderstanding
vm code (patch attached).
Also i was reviewing the bo move code and i think we should only
call ttm_tt_bind if mem_type is TTM_TT, right now you call bind
if mem_type != SYSTEM, so far i never saw somethings else than
TTM_TT being bind but better be safe than sorry.
A related question is what does ttm do when moving a bo from
vram to system ? My understanding is that it creates a tt object
and bind it but can the driver move callback ever get
old_memtype = VRAM & new_memtype=SYSTEM ?
Btw i try to isolate all my ttm stuff in my drm-next-ttm branch
on fdo:
http://cgit.freedesktop.org/~glisse/drm-next/
Cheers,
Jerome
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: built-in.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .built-in.o.cmd
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: Makefile
Only in ttm/: Makefile.am
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: modules.order
diff -u ttm/ttm_agp_backend.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_agp_backend.c
--- ttm/ttm_agp_backend.c 2009-04-07 22:22:48.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_agp_backend.c 2009-04-08 19:22:08.000000000 +0200
@@ -35,6 +35,7 @@
#ifdef TTM_HAS_AGP
#include "ttm/ttm_placement_common.h"
#include <linux/agp_backend.h>
+#include <linux/module.h>
#include <asm/agp.h>
#include <asm/io.h>
@@ -145,5 +146,6 @@
agp_be->backend.bdev = bdev;
return &agp_be->backend;
}
+EXPORT_SYMBOL(ttm_agp_backend_init);
#endif
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_agp_backend.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_agp_backend.o.cmd
Only in ttm/: ttm_bo_api.h
diff -u ttm/ttm_bo.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_bo.c
--- ttm/ttm_bo.c 2009-04-08 17:20:36.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_bo.c 2009-04-10 16:14:31.000000000 +0200
@@ -37,6 +37,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/file.h>
+#include <linux/module.h>
#define TTM_ASSERT_LOCKED(param)
#define TTM_DEBUG(fmt, arg...)
@@ -63,6 +64,7 @@
BUG_ON(bo->sync_obj != NULL);
BUG_ON(bo->mem.mm_node != NULL);
BUG_ON(!list_empty(&bo->lru));
+ BUG_ON(!list_empty(&bo->swap));
BUG_ON(!list_empty(&bo->ddestroy));
if (bo->ttm)
@@ -171,6 +173,7 @@
return 0;
}
+EXPORT_SYMBOL(ttm_bo_reserve);
static void ttm_bo_ref_bug(struct kref *list_kref)
{
@@ -208,6 +211,7 @@
wake_up_all(&bo->event_queue);
spin_unlock(&bdev->lru_lock);
}
+EXPORT_SYMBOL(ttm_bo_unreserve);
/*
* Call bo->mutex locked.
@@ -535,6 +539,7 @@
kref_put(&bo->kref, ttm_bo_release);
write_unlock(&bdev->vm_lock);
}
+EXPORT_SYMBOL(ttm_bo_unref);
static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
bool interruptible, bool no_wait)
@@ -813,6 +818,7 @@
ret = (has_eagain) ? -ERESTART : -ENOMEM;
return ret;
}
+EXPORT_SYMBOL(ttm_bo_mem_space);
/*
* Call bo->mutex locked.
@@ -916,6 +922,36 @@
return 1;
}
+static void ttm_bo_device_print_free_tt_size(struct ttm_bo_device *bdev)
+{
+ unsigned max_size = 0;
+ unsigned free_size = 0;
+ struct drm_mm_node *entry;
+ struct list_head *list;
+ struct list_head *free_stack;
+
+ if (!bdev->man[TTM_PL_TT].has_type || !bdev->man[TTM_PL_TT].use_type) {
+ return;
+ }
+
+ spin_lock(&bdev->lru_lock);
+ free_stack = &bdev->man[TTM_PL_TT].manager.fl_entry;
+ list_for_each(list, free_stack) {
+ entry = list_entry(list, struct drm_mm_node, fl_entry);
+ if (entry->size > max_size) {
+ max_size = entry->size;
+ }
+ free_size += entry->size;
+ }
+ spin_unlock(&bdev->lru_lock);
+ max_size = max_size << PAGE_SHIFT;
+ free_size = free_size << PAGE_SHIFT;
+ printk(KERN_ERR "Aperture biggest free block %ub (%ukb, %uMb)\n",
+ max_size, max_size >> 10, max_size >> 20);
+ printk(KERN_ERR "Aperture total free size %u bytes (%ukb, %uMb)\n",
+ free_size, free_size >> 10, free_size >> 20);
+}
+
int ttm_buffer_object_validate(struct ttm_buffer_object *bo,
bool interruptible, bool no_wait)
{
@@ -937,12 +973,18 @@
interruptible, no_wait);
if (ret) {
if (ret != -ERESTART)
- printk(KERN_ERR "Failed moving buffer. "
- "Proposed placement 0x%08x\n",
+ printk(KERN_ERR "Failed moving buffer of %lub"
+ "(%lukb, %luMb). Proposed placement "
+ "0x%08x\n",
+ bo->num_pages << PAGE_SHIFT,
+ (bo->num_pages << PAGE_SHIFT) >> 10,
+ (bo->num_pages << PAGE_SHIFT) >> 20,
bo->mem.proposed_flags);
- if (ret == -ENOMEM)
+ if (ret == -ENOMEM) {
printk(KERN_ERR "Out of aperture space or "
"DRM memory quota.\n");
+ ttm_bo_device_print_free_tt_size(bo->bdev);
+ }
return ret;
}
}
@@ -967,6 +1009,7 @@
return 0;
}
+EXPORT_SYMBOL(ttm_buffer_object_validate);
int
ttm_bo_check_placement(struct ttm_buffer_object *bo,
@@ -1084,6 +1127,7 @@
return ret;
}
+EXPORT_SYMBOL(ttm_buffer_object_init);
static inline size_t ttm_bo_size(struct ttm_bo_device *bdev,
unsigned long num_pages)
@@ -1227,6 +1271,7 @@
return ret;
}
+EXPORT_SYMBOL(ttm_bo_clean_mm);
int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type)
{
@@ -1289,6 +1334,7 @@
return 0;
}
+EXPORT_SYMBOL(ttm_bo_init_mm);
int ttm_bo_device_release(struct ttm_bo_device *bdev)
{
@@ -1331,6 +1377,7 @@
__free_page(bdev->dummy_read_page);
return ret;
}
+EXPORT_SYMBOL(ttm_bo_device_release);
/*
* This function is intended to be called on drm driver load.
@@ -1392,6 +1439,7 @@
out_err0:
return ret;
}
+EXPORT_SYMBOL(ttm_bo_device_init);
/*
* buffer object vm functions.
@@ -1558,6 +1606,7 @@
out:
return 0;
}
+EXPORT_SYMBOL(ttm_bo_wait);
void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
{
Only in ttm/: ttm_bo_driver.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_bo.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_bo.o.cmd
diff -u ttm/ttm_bo_util.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_bo_util.c
--- ttm/ttm_bo_util.c 2009-04-08 17:20:36.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_bo_util.c 2009-04-10 16:31:43.000000000 +0200
@@ -36,7 +36,9 @@
#include <linux/io.h>
#include <linux/highmem.h>
#include <linux/wait.h>
+#include <linux/vmalloc.h>
#include <linux/version.h>
+#include <linux/module.h>
void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
{
@@ -45,10 +47,12 @@
if (old_mem->mm_node) {
spin_lock(&bo->bdev->lru_lock);
drm_mm_put_block(old_mem->mm_node);
+ old_mem->mm_node = NULL;
spin_unlock(&bo->bdev->lru_lock);
}
old_mem->mm_node = NULL;
}
+EXPORT_SYMBOL(ttm_bo_move_ttm);
int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
bool evict, bool no_wait, struct ttm_mem_reg *new_mem)
@@ -252,6 +256,7 @@
ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
return ret;
}
+EXPORT_SYMBOL(ttm_bo_move_memcpy);
static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
{
@@ -436,6 +441,7 @@
return ttm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map);
}
}
+EXPORT_SYMBOL(ttm_bo_kmap);
void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
{
@@ -459,6 +465,7 @@
map->virtual = NULL;
map->page = NULL;
}
+EXPORT_SYMBOL(ttm_bo_kunmap);
int ttm_bo_pfn_prot(struct ttm_buffer_object *bo,
unsigned long dst_offset,
@@ -537,9 +544,10 @@
if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
ghost_obj->ttm = NULL;
else
- ghost_obj = NULL;
+ bo->ttm = NULL;
bo->priv_flags |= TTM_BO_PRIV_FLAG_MOVING;
+
ttm_bo_unreserve(ghost_obj);
ttm_bo_unref(&ghost_obj);
}
@@ -550,3 +558,4 @@
ttm_flag_masked(&save_flags, new_mem->flags, TTM_PL_MASK_MEMTYPE);
return 0;
}
+EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_bo_util.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_bo_util.o.cmd
diff -u ttm/ttm_bo_vm.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_bo_vm.c
--- ttm/ttm_bo_vm.c 2009-04-08 17:20:36.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_bo_vm.c 2009-04-08 19:22:08.000000000 +0200
@@ -31,11 +31,12 @@
*/
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_placement_common.h"
+#include <ttm/ttm_bo_driver.h>
+#include <ttm/ttm_placement_common.h>
#include <linux/mm.h>
#include <linux/version.h>
#include <linux/rbtree.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25))
@@ -439,6 +440,7 @@
ttm_bo_unref(&bo);
return ret;
}
+EXPORT_SYMBOL(ttm_bo_mmap);
int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
{
@@ -483,8 +485,10 @@
if (unlikely(bo == NULL))
return -EFAULT;
- if (unlikely(driver->verify_access))
- return -EPERM;
+ if (unlikely(driver->verify_access)) {
+ ret = -EPERM;
+ goto out_unref;
+ }
ret = driver->verify_access(bo, filp);
if (unlikely(ret != 0))
@@ -521,8 +525,10 @@
}
ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
- if (unlikely(ret != 0))
+ if (unlikely(ret != 0)) {
+ ttm_bo_unreserve(bo);
goto out_unref;
+ }
virtual = ttm_kmap_obj_virtual(&map, &dummy);
virtual += page_offset;
@@ -589,8 +595,10 @@
}
ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
- if (unlikely(ret != 0))
+ if (unlikely(ret != 0)) {
+ ttm_bo_unreserve(bo);
return ret;
+ }
virtual = ttm_kmap_obj_virtual(&map, &dummy);
virtual += page_offset;
@@ -602,7 +610,6 @@
ttm_bo_kunmap(&map);
ttm_bo_unreserve(bo);
- ttm_bo_unref(&bo);
if (unlikely(ret != 0))
return ret;
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_bo_vm.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_bo_vm.o.cmd
Only in ttm/: ttm_execbuf_util.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_execbuf_util.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_execbuf_util.o.cmd
Only in ttm/: ttm_fence_api.h
Only in ttm/: ttm_fence_driver.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_fence.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_fence.o.cmd
Only in ttm/: ttm_fence_user.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_fence_user.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_fence_user.o.cmd
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm.ko
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm.ko.cmd
diff -u ttm/ttm_lock.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_lock.c
--- ttm/ttm_lock.c 2009-04-07 22:22:48.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_lock.c 2009-04-08 19:22:08.000000000 +0200
@@ -30,11 +30,12 @@
* Authors: Thomas Hellstr�m <thomas-at-tungstengraphics-dot-com>
*/
-#include "ttm/ttm_lock.h"
+#include <ttm/ttm_lock.h>
#include <asm/atomic.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/sched.h>
+#include <linux/module.h>
void ttm_lock_init(struct ttm_lock *lock)
{
@@ -44,12 +45,14 @@
lock->kill_takers = false;
lock->signal = SIGKILL;
}
+EXPORT_SYMBOL(ttm_lock_init);
void ttm_read_unlock(struct ttm_lock *lock)
{
if (atomic_dec_and_test(&lock->readers))
wake_up_all(&lock->queue);
}
+EXPORT_SYMBOL(ttm_read_unlock);
int ttm_read_lock(struct ttm_lock *lock, bool interruptible)
{
@@ -88,6 +91,7 @@
return 0;
}
+EXPORT_SYMBOL(ttm_read_lock);
static int __ttm_write_unlock(struct ttm_lock *lock)
{
Only in ttm/: ttm_lock.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_lock.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_lock.o.cmd
diff -u ttm/ttm_memory.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_memory.c
--- ttm/ttm_memory.c 2009-04-07 22:22:48.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_memory.c 2009-04-08 19:22:08.000000000 +0200
@@ -32,6 +32,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/mm.h>
+#include <linux/module.h>
#define TTM_MEMORY_ALLOC_RETRIES 4
@@ -126,6 +127,7 @@
return 0;
}
+EXPORT_SYMBOL(ttm_mem_global_init);
void ttm_mem_global_release(struct ttm_mem_global *glob)
{
@@ -135,6 +137,7 @@
destroy_workqueue(glob->swap_queue);
glob->swap_queue = NULL;
}
+EXPORT_SYMBOL(ttm_mem_global_release);
static inline void ttm_check_swapping(struct ttm_mem_global *glob)
{
Only in ttm/: ttm_memory.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_memory.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_memory.o.cmd
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm.mod.c
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm.mod.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm.mod.o.cmd
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_module.c
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_module.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_module.o.cmd
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm.o
Only in ttm/: ttm_object.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_object.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_object.o.cmd
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm.o.cmd
Only in ttm/: ttm_pat_compat.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_pat_compat.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_pat_compat.o.cmd
Only in ttm/: ttm_placement_common.h
Only in ttm/: ttm_placement_user.h
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_placement_user.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_placement_user.o.cmd
diff -u ttm/ttm_tt.c /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_tt.c
--- ttm/ttm_tt.c 2009-04-07 22:22:48.000000000 +0200
+++ /home/glisse/fdo/linux/drivers/gpu/drm/ttm/ttm_tt.c 2009-04-10 16:31:43.000000000 +0200
@@ -85,7 +85,7 @@
return;
}
#else
- if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1, 1) != 0)
+ if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1) != 0)
printk(KERN_ERR "Timed out waiting for drm cache flush.\n");
#endif
}
@@ -500,6 +500,7 @@
ttm->page_flags |= TTM_PAGE_FLAG_USER_DIRTY;
return 0;
}
+EXPORT_SYMBOL(ttm_tt_bind);
static int ttm_tt_swapin(struct ttm_tt *ttm)
{
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: ttm_tt.o
Only in /home/glisse/fdo/linux/drivers/gpu/drm/ttm/: .ttm_tt.o.cmd
Only in ttm/: ttm_userobj_api.h
------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel