aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-06-23 20:23:20 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:04:00 -0400
commita12036ba2c0a190c93e5238c5f32fdb8c023c068 (patch)
tree604f365447a806e07f31589a655b1c0a8494f669
parent987eec10dd76624d0edacdc7ecc7e1a6fc877373 (diff)
drm/nouveau: allow a nouveau_mm to be created with holes
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mm.c47
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mm.h1
2 files changed, 28 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c
index 75b5dd93a32f..b29ffb3d1408 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mm.c
@@ -129,21 +129,25 @@ nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc,
129int 129int
130nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) 130nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
131{ 131{
132 struct nouveau_mm_node *heap; 132 struct nouveau_mm_node *node;
133
134 if (block) {
135 mutex_init(&mm->mutex);
136 INIT_LIST_HEAD(&mm->nodes);
137 INIT_LIST_HEAD(&mm->free);
138 mm->block_size = block;
139 mm->heap_nodes = 0;
140 }
133 141
134 heap = kzalloc(sizeof(*heap), GFP_KERNEL); 142 node = kzalloc(sizeof(*node), GFP_KERNEL);
135 if (!heap) 143 if (!node)
136 return -ENOMEM; 144 return -ENOMEM;
137 heap->offset = roundup(offset, block); 145 node->offset = roundup(offset, mm->block_size);
138 heap->length = rounddown(offset + length, block) - heap->offset; 146 node->length = rounddown(offset + length, mm->block_size) - node->offset;
139
140 mutex_init(&mm->mutex);
141 mm->block_size = block;
142 INIT_LIST_HEAD(&mm->nodes);
143 INIT_LIST_HEAD(&mm->free);
144 147
145 list_add(&heap->nl_entry, &mm->nodes); 148 list_add_tail(&node->nl_entry, &mm->nodes);
146 list_add(&heap->fl_entry, &mm->free); 149 list_add_tail(&node->fl_entry, &mm->free);
150 mm->heap_nodes++;
147 return 0; 151 return 0;
148} 152}
149 153
@@ -152,15 +156,18 @@ nouveau_mm_fini(struct nouveau_mm *mm)
152{ 156{
153 struct nouveau_mm_node *node, *heap = 157 struct nouveau_mm_node *node, *heap =
154 list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry); 158 list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry);
155 159 int nodes = 0;
156 if (!list_is_singular(&mm->nodes)) { 160
157 printk(KERN_ERR "nouveau_mm not empty at destroy time!\n"); 161 list_for_each_entry(node, &mm->nodes, nl_entry) {
158 list_for_each_entry(node, &mm->nodes, nl_entry) { 162 if (nodes++ == mm->heap_nodes) {
159 printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n", 163 printk(KERN_ERR "nouveau_mm in use at destroy time!\n");
160 node->type, node->offset, node->length); 164 list_for_each_entry(node, &mm->nodes, nl_entry) {
165 printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n",
166 node->type, node->offset, node->length);
167 }
168 WARN_ON(1);
169 return -EBUSY;
161 } 170 }
162 WARN_ON(1);
163 return -EBUSY;
164 } 171 }
165 172
166 kfree(heap); 173 kfree(heap);
diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h
index b8fe9088b9ed..57a600c35c95 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_mm.h
@@ -42,6 +42,7 @@ struct nouveau_mm {
42 struct mutex mutex; 42 struct mutex mutex;
43 43
44 u32 block_size; 44 u32 block_size;
45 int heap_nodes;
45}; 46};
46 47
47int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); 48int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);