aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2009-06-17 06:29:56 -0400
committerDave Airlie <airlied@redhat.com>2009-06-18 19:01:12 -0400
commit89579f778266d5a4d08d0c64c46b1565218de9f9 (patch)
treef7a2389d1277bf285e790b660e0f6a6019ff857f /drivers
parent78ecf091aa592a9e160ebbbfa5873c2bb2e2d0f8 (diff)
drm: Apply "Memory fragmentation from lost alignment blocks"
also for the atomic path by using a common code-path. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_mm.c48
1 files changed, 7 insertions, 41 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index a912a0ff11cc..3e47869d6dae 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -187,9 +187,10 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
187} 187}
188 188
189 189
190 190struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
191struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node, 191 unsigned long size,
192 unsigned long size, unsigned alignment) 192 unsigned alignment,
193 int atomic)
193{ 194{
194 195
195 struct drm_mm_node *align_splitoff = NULL; 196 struct drm_mm_node *align_splitoff = NULL;
@@ -200,7 +201,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
200 201
201 if (tmp) { 202 if (tmp) {
202 align_splitoff = 203 align_splitoff =
203 drm_mm_split_at_start(node, alignment - tmp, 0); 204 drm_mm_split_at_start(node, alignment - tmp, atomic);
204 if (unlikely(align_splitoff == NULL)) 205 if (unlikely(align_splitoff == NULL))
205 return NULL; 206 return NULL;
206 } 207 }
@@ -209,7 +210,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
209 list_del_init(&node->fl_entry); 210 list_del_init(&node->fl_entry);
210 node->free = 0; 211 node->free = 0;
211 } else { 212 } else {
212 node = drm_mm_split_at_start(node, size, 0); 213 node = drm_mm_split_at_start(node, size, atomic);
213 } 214 }
214 215
215 if (align_splitoff) 216 if (align_splitoff)
@@ -217,42 +218,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node,
217 218
218 return node; 219 return node;
219} 220}
220 221EXPORT_SYMBOL(drm_mm_get_block_generic);
221EXPORT_SYMBOL(drm_mm_get_block);
222
223struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
224 unsigned long size,
225 unsigned alignment)
226{
227
228 struct drm_mm_node *align_splitoff = NULL;
229 struct drm_mm_node *child;
230 unsigned tmp = 0;
231
232 if (alignment)
233 tmp = parent->start % alignment;
234
235 if (tmp) {
236 align_splitoff =
237 drm_mm_split_at_start(parent, alignment - tmp, 1);
238 if (unlikely(align_splitoff == NULL))
239 return NULL;
240 }
241
242 if (parent->size == size) {
243 list_del_init(&parent->fl_entry);
244 parent->free = 0;
245 return parent;
246 } else {
247 child = drm_mm_split_at_start(parent, size, 1);
248 }
249
250 if (align_splitoff)
251 drm_mm_put_block(align_splitoff);
252
253 return child;
254}
255EXPORT_SYMBOL(drm_mm_get_block_atomic);
256 222
257/* 223/*
258 * Put a block. Merge with the previous and / or next block if they are free. 224 * Put a block. Merge with the previous and / or next block if they are free.