diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-12 14:48:28 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-09-15 22:22:13 +1000 |
commit | d7bda18c9102b65078c132fd7d7ffd835058f021 (patch) | |
tree | 936a1812a017665ca04de5f98a5e893905501251 /drivers/gpu/drm/nouveau/core/core | |
parent | drm/nouveau/core/mm: modify test for if building a mm with holes in it (diff) | |
download | linux-dev-d7bda18c9102b65078c132fd7d7ffd835058f021.tar.xz linux-dev-d7bda18c9102b65078c132fd7d7ffd835058f021.zip |
drm/nouveau/core/mm: dump mm when trying to tear one down that still has allocations
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/core')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/core/mm.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/mm.c b/drivers/gpu/drm/nouveau/core/core/mm.c index cdd0c9ad0eff..8a77a8bf9cc0 100644 --- a/drivers/gpu/drm/nouveau/core/core/mm.c +++ b/drivers/gpu/drm/nouveau/core/core/mm.c @@ -28,6 +28,24 @@ #define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \ list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry) +static void +nouveau_mm_dump(struct nouveau_mm *mm, const char *header) +{ + struct nouveau_mm_node *node; + + printk(KERN_ERR "nouveau: %s\n", header); + printk(KERN_ERR "nouveau: node list:\n"); + list_for_each_entry(node, &mm->nodes, nl_entry) { + printk(KERN_ERR "nouveau: \t%08x %08x %d\n", + node->offset, node->length, node->type); + } + printk(KERN_ERR "nouveau: free list:\n"); + list_for_each_entry(node, &mm->free, fl_entry) { + printk(KERN_ERR "nouveau: \t%08x %08x %d\n", + node->offset, node->length, node->type); + } +} + void nouveau_mm_free(struct nouveau_mm *mm, struct nouveau_mm_node **pthis) { @@ -239,18 +257,23 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) int nouveau_mm_fini(struct nouveau_mm *mm) { - if (nouveau_mm_initialised(mm)) { - struct nouveau_mm_node *node, *heap = - list_first_entry(&mm->nodes, typeof(*heap), nl_entry); - int nodes = 0; + struct nouveau_mm_node *node, *temp; + int nodes = 0; - list_for_each_entry(node, &mm->nodes, nl_entry) { - if (WARN_ON(nodes++ == mm->heap_nodes)) - return -EBUSY; - } + if (!nouveau_mm_initialised(mm)) + return 0; - kfree(heap); + list_for_each_entry(node, &mm->nodes, nl_entry) { + if (++nodes > mm->heap_nodes) { + nouveau_mm_dump(mm, "mm not clean!"); + return -EBUSY; + } } + list_for_each_entry_safe(node, temp, &mm->nodes, nl_entry) { + list_del(&node->nl_entry); + kfree(node); + } + mm->heap_nodes = 0; return 0; } |