diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-06-23 20:23:20 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:04:00 -0400 |
commit | a12036ba2c0a190c93e5238c5f32fdb8c023c068 (patch) | |
tree | 604f365447a806e07f31589a655b1c0a8494f669 | |
parent | 987eec10dd76624d0edacdc7ecc7e1a6fc877373 (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.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mm.h | 1 |
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, | |||
129 | int | 129 | int |
130 | nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) | 130 | nouveau_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 | ||
47 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); | 48 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); |