diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2009-06-17 06:29:56 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-06-18 19:01:12 -0400 |
commit | 89579f778266d5a4d08d0c64c46b1565218de9f9 (patch) | |
tree | f7a2389d1277bf285e790b660e0f6a6019ff857f /drivers | |
parent | 78ecf091aa592a9e160ebbbfa5873c2bb2e2d0f8 (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.c | 48 |
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 | 190 | struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, | |
191 | struct 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 | 221 | EXPORT_SYMBOL(drm_mm_get_block_generic); | |
221 | EXPORT_SYMBOL(drm_mm_get_block); | ||
222 | |||
223 | struct 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 | } | ||
255 | EXPORT_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. |