diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-01-28 12:22:31 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-08 18:32:34 -0500 |
commit | 9f93ed39804a9cfe10577cfae66059fe6bc6e3a5 (patch) | |
tree | a59e77faf98a85451ea8ba54c1361f188fc6836d /drivers/gpu/drm/radeon | |
parent | 73a6d3fc104827db574e4bd206a025299fef0bb1 (diff) |
drm/radeon/kms: bogus cs recorder utilities
This add an utilities function radeon_ib_bogus_add which will
save an ib into a list of ib which can then be dumped using
debugfs. Once dumped the ib is removed from the list. This
should allow to save & capute ib for further debugging.
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 66 |
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3f353131bb38..b519d7db2dcb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -383,6 +383,7 @@ struct radeon_ib_pool { | |||
383 | struct mutex mutex; | 383 | struct mutex mutex; |
384 | struct radeon_bo *robj; | 384 | struct radeon_bo *robj; |
385 | struct list_head scheduled_ibs; | 385 | struct list_head scheduled_ibs; |
386 | struct list_head bogus_ib; | ||
386 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; | 387 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; |
387 | bool ready; | 388 | bool ready; |
388 | DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE); | 389 | DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE); |
@@ -437,6 +438,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); | |||
437 | int radeon_ib_pool_init(struct radeon_device *rdev); | 438 | int radeon_ib_pool_init(struct radeon_device *rdev); |
438 | void radeon_ib_pool_fini(struct radeon_device *rdev); | 439 | void radeon_ib_pool_fini(struct radeon_device *rdev); |
439 | int radeon_ib_test(struct radeon_device *rdev); | 440 | int radeon_ib_test(struct radeon_device *rdev); |
441 | extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); | ||
440 | /* Ring access between begin & end cannot sleep */ | 442 | /* Ring access between begin & end cannot sleep */ |
441 | void radeon_ring_free_size(struct radeon_device *rdev); | 443 | void radeon_ring_free_size(struct radeon_device *rdev); |
442 | int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw); | 444 | int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 4d12b2d17b4d..e3bee59ef6c3 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -34,6 +34,36 @@ | |||
34 | 34 | ||
35 | int radeon_debugfs_ib_init(struct radeon_device *rdev); | 35 | int radeon_debugfs_ib_init(struct radeon_device *rdev); |
36 | 36 | ||
37 | void radeon_ib_bogus_cleanup(struct radeon_device *rdev) | ||
38 | { | ||
39 | struct radeon_ib *ib, *n; | ||
40 | |||
41 | list_for_each_entry_safe(ib, n, &rdev->ib_pool.bogus_ib, list) { | ||
42 | list_del(&ib->list); | ||
43 | vfree(ib->ptr); | ||
44 | kfree(ib); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib) | ||
49 | { | ||
50 | struct radeon_ib *bib; | ||
51 | |||
52 | bib = kmalloc(sizeof(*bib), GFP_KERNEL); | ||
53 | if (bib == NULL) | ||
54 | return; | ||
55 | bib->ptr = vmalloc(ib->length_dw * 4); | ||
56 | if (bib->ptr == NULL) { | ||
57 | kfree(bib); | ||
58 | return; | ||
59 | } | ||
60 | memcpy(bib->ptr, ib->ptr, ib->length_dw * 4); | ||
61 | bib->length_dw = ib->length_dw; | ||
62 | mutex_lock(&rdev->ib_pool.mutex); | ||
63 | list_add_tail(&bib->list, &rdev->ib_pool.bogus_ib); | ||
64 | mutex_unlock(&rdev->ib_pool.mutex); | ||
65 | } | ||
66 | |||
37 | /* | 67 | /* |
38 | * IB. | 68 | * IB. |
39 | */ | 69 | */ |
@@ -163,6 +193,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
163 | 193 | ||
164 | if (rdev->ib_pool.robj) | 194 | if (rdev->ib_pool.robj) |
165 | return 0; | 195 | return 0; |
196 | INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); | ||
166 | /* Allocate 1M object buffer */ | 197 | /* Allocate 1M object buffer */ |
167 | INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); | 198 | INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); |
168 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, | 199 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, |
@@ -214,6 +245,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
214 | return; | 245 | return; |
215 | } | 246 | } |
216 | mutex_lock(&rdev->ib_pool.mutex); | 247 | mutex_lock(&rdev->ib_pool.mutex); |
248 | radeon_ib_bogus_cleanup(rdev); | ||
217 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | 249 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); |
218 | if (rdev->ib_pool.robj) { | 250 | if (rdev->ib_pool.robj) { |
219 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); | 251 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); |
@@ -372,15 +404,49 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void *data) | |||
372 | return 0; | 404 | return 0; |
373 | } | 405 | } |
374 | 406 | ||
407 | static int radeon_debugfs_ib_bogus_info(struct seq_file *m, void *data) | ||
408 | { | ||
409 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
410 | struct radeon_device *rdev = node->info_ent->data; | ||
411 | struct radeon_ib *ib; | ||
412 | unsigned i; | ||
413 | |||
414 | mutex_lock(&rdev->ib_pool.mutex); | ||
415 | if (list_empty(&rdev->ib_pool.bogus_ib)) { | ||
416 | mutex_unlock(&rdev->ib_pool.mutex); | ||
417 | seq_printf(m, "no bogus IB recorded\n"); | ||
418 | return 0; | ||
419 | } | ||
420 | ib = list_first_entry(&rdev->ib_pool.bogus_ib, struct radeon_ib, list); | ||
421 | list_del_init(&ib->list); | ||
422 | mutex_unlock(&rdev->ib_pool.mutex); | ||
423 | seq_printf(m, "IB size %05u dwords\n", ib->length_dw); | ||
424 | for (i = 0; i < ib->length_dw; i++) { | ||
425 | seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); | ||
426 | } | ||
427 | vfree(ib->ptr); | ||
428 | kfree(ib); | ||
429 | return 0; | ||
430 | } | ||
431 | |||
375 | static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; | 432 | static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; |
376 | static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; | 433 | static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; |
434 | |||
435 | static struct drm_info_list radeon_debugfs_ib_bogus_info_list[] = { | ||
436 | {"radeon_ib_bogus", radeon_debugfs_ib_bogus_info, 0, NULL}, | ||
437 | }; | ||
377 | #endif | 438 | #endif |
378 | 439 | ||
379 | int radeon_debugfs_ib_init(struct radeon_device *rdev) | 440 | int radeon_debugfs_ib_init(struct radeon_device *rdev) |
380 | { | 441 | { |
381 | #if defined(CONFIG_DEBUG_FS) | 442 | #if defined(CONFIG_DEBUG_FS) |
382 | unsigned i; | 443 | unsigned i; |
444 | int r; | ||
383 | 445 | ||
446 | radeon_debugfs_ib_bogus_info_list[0].data = rdev; | ||
447 | r = radeon_debugfs_add_files(rdev, radeon_debugfs_ib_bogus_info_list, 1); | ||
448 | if (r) | ||
449 | return r; | ||
384 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { | 450 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
385 | sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); | 451 | sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); |
386 | radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; | 452 | radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; |