drm/nouveau: allow a nouveau_mm to be created with holes
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Родитель
987eec10dd
Коммит
a12036ba2c
|
@ -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;
|
||||||
|
|
||||||
heap = kzalloc(sizeof(*heap), GFP_KERNEL);
|
if (block) {
|
||||||
if (!heap)
|
mutex_init(&mm->mutex);
|
||||||
|
INIT_LIST_HEAD(&mm->nodes);
|
||||||
|
INIT_LIST_HEAD(&mm->free);
|
||||||
|
mm->block_size = block;
|
||||||
|
mm->heap_nodes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = kzalloc(sizeof(*node), GFP_KERNEL);
|
||||||
|
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);
|
list_add_tail(&node->nl_entry, &mm->nodes);
|
||||||
mm->block_size = block;
|
list_add_tail(&node->fl_entry, &mm->free);
|
||||||
INIT_LIST_HEAD(&mm->nodes);
|
mm->heap_nodes++;
|
||||||
INIT_LIST_HEAD(&mm->free);
|
|
||||||
|
|
||||||
list_add(&heap->nl_entry, &mm->nodes);
|
|
||||||
list_add(&heap->fl_entry, &mm->free);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)) {
|
list_for_each_entry(node, &mm->nodes, nl_entry) {
|
||||||
printk(KERN_ERR "nouveau_mm not empty at destroy time!\n");
|
if (nodes++ == mm->heap_nodes) {
|
||||||
list_for_each_entry(node, &mm->nodes, nl_entry) {
|
printk(KERN_ERR "nouveau_mm in use at destroy time!\n");
|
||||||
printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n",
|
list_for_each_entry(node, &mm->nodes, nl_entry) {
|
||||||
node->type, node->offset, node->length);
|
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 {
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче