Commit a12036ba authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: allow a nouveau_mm to be created with holes

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 987eec10
...@@ -129,21 +129,25 @@ nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc, ...@@ -129,21 +129,25 @@ nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc,
int int
nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
{ {
struct nouveau_mm_node *heap; struct nouveau_mm_node *node;
if (block) {
mutex_init(&mm->mutex);
INIT_LIST_HEAD(&mm->nodes);
INIT_LIST_HEAD(&mm->free);
mm->block_size = block;
mm->heap_nodes = 0;
}
heap = kzalloc(sizeof(*heap), GFP_KERNEL); node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!heap) if (!node)
return -ENOMEM; return -ENOMEM;
heap->offset = roundup(offset, block); node->offset = roundup(offset, mm->block_size);
heap->length = rounddown(offset + length, block) - heap->offset; node->length = rounddown(offset + length, mm->block_size) - node->offset;
mutex_init(&mm->mutex);
mm->block_size = block;
INIT_LIST_HEAD(&mm->nodes);
INIT_LIST_HEAD(&mm->free);
list_add(&heap->nl_entry, &mm->nodes); list_add_tail(&node->nl_entry, &mm->nodes);
list_add(&heap->fl_entry, &mm->free); list_add_tail(&node->fl_entry, &mm->free);
mm->heap_nodes++;
return 0; return 0;
} }
...@@ -152,15 +156,18 @@ nouveau_mm_fini(struct nouveau_mm *mm) ...@@ -152,15 +156,18 @@ nouveau_mm_fini(struct nouveau_mm *mm)
{ {
struct nouveau_mm_node *node, *heap = struct nouveau_mm_node *node, *heap =
list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry); list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry);
int nodes = 0;
if (!list_is_singular(&mm->nodes)) {
printk(KERN_ERR "nouveau_mm not empty at destroy time!\n"); list_for_each_entry(node, &mm->nodes, nl_entry) {
list_for_each_entry(node, &mm->nodes, nl_entry) { if (nodes++ == mm->heap_nodes) {
printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n", printk(KERN_ERR "nouveau_mm in use at destroy time!\n");
node->type, node->offset, node->length); list_for_each_entry(node, &mm->nodes, nl_entry) {
printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n",
node->type, node->offset, node->length);
}
WARN_ON(1);
return -EBUSY;
} }
WARN_ON(1);
return -EBUSY;
} }
kfree(heap); kfree(heap);
......
...@@ -42,6 +42,7 @@ struct nouveau_mm { ...@@ -42,6 +42,7 @@ struct nouveau_mm {
struct mutex mutex; struct mutex mutex;
u32 block_size; u32 block_size;
int heap_nodes;
}; };
int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment