Rev 3192 | Rev 3764 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3192 | Rev 3480 | ||
---|---|---|---|
Line 100... | Line 100... | ||
100 | spin_unlock(&mm->unused_lock); |
100 | spin_unlock(&mm->unused_lock); |
101 | return 0; |
101 | return 0; |
102 | } |
102 | } |
103 | EXPORT_SYMBOL(drm_mm_pre_get); |
103 | EXPORT_SYMBOL(drm_mm_pre_get); |
Line 104... | Line -... | ||
104 | - | ||
105 | static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) |
- | |
106 | { |
- | |
107 | return hole_node->start + hole_node->size; |
- | |
108 | } |
- | |
109 | - | ||
110 | static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) |
- | |
111 | { |
- | |
112 | struct drm_mm_node *next_node = |
- | |
113 | list_entry(hole_node->node_list.next, struct drm_mm_node, |
- | |
114 | node_list); |
- | |
115 | - | ||
116 | return next_node->start; |
- | |
117 | } |
- | |
118 | 104 | ||
119 | static void drm_mm_insert_helper(struct drm_mm_node *hole_node, |
105 | static void drm_mm_insert_helper(struct drm_mm_node *hole_node, |
120 | struct drm_mm_node *node, |
106 | struct drm_mm_node *node, |
121 | unsigned long size, unsigned alignment, |
107 | unsigned long size, unsigned alignment, |
122 | unsigned long color) |
108 | unsigned long color) |
Line 125... | Line 111... | ||
125 | unsigned long hole_start = drm_mm_hole_node_start(hole_node); |
111 | unsigned long hole_start = drm_mm_hole_node_start(hole_node); |
126 | unsigned long hole_end = drm_mm_hole_node_end(hole_node); |
112 | unsigned long hole_end = drm_mm_hole_node_end(hole_node); |
127 | unsigned long adj_start = hole_start; |
113 | unsigned long adj_start = hole_start; |
128 | unsigned long adj_end = hole_end; |
114 | unsigned long adj_end = hole_end; |
Line 129... | Line 115... | ||
129 | 115 | ||
Line 130... | Line 116... | ||
130 | BUG_ON(!hole_node->hole_follows || node->allocated); |
116 | BUG_ON(node->allocated); |
131 | 117 | ||
Line 132... | Line 118... | ||
132 | if (mm->color_adjust) |
118 | if (mm->color_adjust) |
Line 153... | Line 139... | ||
153 | list_add(&node->node_list, &hole_node->node_list); |
139 | list_add(&node->node_list, &hole_node->node_list); |
Line 154... | Line 140... | ||
154 | 140 | ||
Line 155... | Line 141... | ||
155 | BUG_ON(node->start + node->size > adj_end); |
141 | BUG_ON(node->start + node->size > adj_end); |
156 | 142 | ||
157 | node->hole_follows = 0; |
143 | node->hole_follows = 0; |
158 | if (node->start + node->size < hole_end) { |
144 | if (__drm_mm_hole_node_start(node) < hole_end) { |
159 | list_add(&node->hole_stack, &mm->hole_stack); |
145 | list_add(&node->hole_stack, &mm->hole_stack); |
160 | node->hole_follows = 1; |
146 | node->hole_follows = 1; |
Line -... | Line 147... | ||
- | 147 | } |
|
- | 148 | } |
|
- | 149 | ||
- | 150 | struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, |
|
- | 151 | unsigned long start, |
|
- | 152 | unsigned long size, |
|
- | 153 | bool atomic) |
|
- | 154 | { |
|
- | 155 | struct drm_mm_node *hole, *node; |
|
- | 156 | unsigned long end = start + size; |
|
- | 157 | unsigned long hole_start; |
|
- | 158 | unsigned long hole_end; |
|
- | 159 | ||
- | 160 | drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { |
|
- | 161 | if (hole_start > start || hole_end < end) |
|
- | 162 | continue; |
|
- | 163 | ||
- | 164 | node = drm_mm_kmalloc(mm, atomic); |
|
- | 165 | if (unlikely(node == NULL)) |
|
- | 166 | return NULL; |
|
- | 167 | ||
- | 168 | node->start = start; |
|
- | 169 | node->size = size; |
|
- | 170 | node->mm = mm; |
|
- | 171 | node->allocated = 1; |
|
- | 172 | ||
- | 173 | INIT_LIST_HEAD(&node->hole_stack); |
|
- | 174 | list_add(&node->node_list, &hole->node_list); |
|
- | 175 | ||
- | 176 | if (start == hole_start) { |
|
- | 177 | hole->hole_follows = 0; |
|
- | 178 | list_del_init(&hole->hole_stack); |
|
- | 179 | } |
|
- | 180 | ||
- | 181 | node->hole_follows = 0; |
|
- | 182 | if (end != hole_end) { |
|
- | 183 | list_add(&node->hole_stack, &mm->hole_stack); |
|
- | 184 | node->hole_follows = 1; |
|
- | 185 | } |
|
- | 186 | ||
- | 187 | return node; |
|
- | 188 | } |
|
- | 189 | ||
- | 190 | WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); |
|
- | 191 | return NULL; |
|
161 | } |
192 | } |
162 | } |
193 | EXPORT_SYMBOL(drm_mm_create_block); |
163 | 194 | ||
164 | struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, |
195 | struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, |
165 | unsigned long size, |
196 | unsigned long size, |
Line 251... | Line 282... | ||
251 | 282 | ||
252 | BUG_ON(node->start + node->size > adj_end); |
283 | BUG_ON(node->start + node->size > adj_end); |
Line 253... | Line 284... | ||
253 | BUG_ON(node->start + node->size > end); |
284 | BUG_ON(node->start + node->size > end); |
254 | 285 | ||
255 | node->hole_follows = 0; |
286 | node->hole_follows = 0; |
256 | if (node->start + node->size < hole_end) { |
287 | if (__drm_mm_hole_node_start(node) < hole_end) { |
257 | list_add(&node->hole_stack, &mm->hole_stack); |
288 | list_add(&node->hole_stack, &mm->hole_stack); |
258 | node->hole_follows = 1; |
289 | node->hole_follows = 1; |
Line 325... | Line 356... | ||
325 | 356 | ||
326 | prev_node = |
357 | prev_node = |
Line 327... | Line 358... | ||
327 | list_entry(node->node_list.prev, struct drm_mm_node, node_list); |
358 | list_entry(node->node_list.prev, struct drm_mm_node, node_list); |
328 | 359 | ||
329 | if (node->hole_follows) { |
360 | if (node->hole_follows) { |
330 | BUG_ON(drm_mm_hole_node_start(node) |
361 | BUG_ON(__drm_mm_hole_node_start(node) == |
331 | == drm_mm_hole_node_end(node)); |
362 | __drm_mm_hole_node_end(node)); |
332 | list_del(&node->hole_stack); |
363 | list_del(&node->hole_stack); |
333 | } else |
364 | } else |
- | 365 | BUG_ON(__drm_mm_hole_node_start(node) != |
|
Line 334... | Line 366... | ||
334 | BUG_ON(drm_mm_hole_node_start(node) |
366 | __drm_mm_hole_node_end(node)); |
335 | != drm_mm_hole_node_end(node)); |
367 | |
336 | 368 | ||
337 | if (!prev_node->hole_follows) { |
369 | if (!prev_node->hole_follows) { |
Line 388... | Line 420... | ||
388 | unsigned long color, |
420 | unsigned long color, |
389 | bool best_match) |
421 | bool best_match) |
390 | { |
422 | { |
391 | struct drm_mm_node *entry; |
423 | struct drm_mm_node *entry; |
392 | struct drm_mm_node *best; |
424 | struct drm_mm_node *best; |
- | 425 | unsigned long adj_start; |
|
- | 426 | unsigned long adj_end; |
|
393 | unsigned long best_size; |
427 | unsigned long best_size; |
Line 394... | Line 428... | ||
394 | 428 | ||
Line 395... | Line 429... | ||
395 | BUG_ON(mm->scanned_blocks); |
429 | BUG_ON(mm->scanned_blocks); |
396 | 430 | ||
Line 397... | Line 431... | ||
397 | best = NULL; |
431 | best = NULL; |
398 | best_size = ~0UL; |
- | |
399 | - | ||
400 | list_for_each_entry(entry, &mm->hole_stack, hole_stack) { |
- | |
401 | unsigned long adj_start = drm_mm_hole_node_start(entry); |
432 | best_size = ~0UL; |
402 | unsigned long adj_end = drm_mm_hole_node_end(entry); |
433 | |
403 | 434 | drm_mm_for_each_hole(entry, mm, adj_start, adj_end) { |
|
404 | if (mm->color_adjust) { |
435 | if (mm->color_adjust) { |
405 | mm->color_adjust(entry, color, &adj_start, &adj_end); |
436 | mm->color_adjust(entry, color, &adj_start, &adj_end); |
Line 406... | Line -... | ||
406 | if (adj_end <= adj_start) |
- | |
407 | continue; |
437 | if (adj_end <= adj_start) |
408 | } |
438 | continue; |
Line 409... | Line 439... | ||
409 | 439 | } |
|
410 | BUG_ON(!entry->hole_follows); |
440 | |
Line 432... | Line 462... | ||
432 | unsigned long end, |
462 | unsigned long end, |
433 | bool best_match) |
463 | bool best_match) |
434 | { |
464 | { |
435 | struct drm_mm_node *entry; |
465 | struct drm_mm_node *entry; |
436 | struct drm_mm_node *best; |
466 | struct drm_mm_node *best; |
- | 467 | unsigned long adj_start; |
|
- | 468 | unsigned long adj_end; |
|
437 | unsigned long best_size; |
469 | unsigned long best_size; |
Line 438... | Line 470... | ||
438 | 470 | ||
Line 439... | Line 471... | ||
439 | BUG_ON(mm->scanned_blocks); |
471 | BUG_ON(mm->scanned_blocks); |
440 | 472 | ||
Line 441... | Line 473... | ||
441 | best = NULL; |
473 | best = NULL; |
442 | best_size = ~0UL; |
474 | best_size = ~0UL; |
443 | 475 | ||
444 | list_for_each_entry(entry, &mm->hole_stack, hole_stack) { |
- | |
445 | unsigned long adj_start = drm_mm_hole_node_start(entry) < start ? |
476 | drm_mm_for_each_hole(entry, mm, adj_start, adj_end) { |
446 | start : drm_mm_hole_node_start(entry); |
- | |
447 | unsigned long adj_end = drm_mm_hole_node_end(entry) > end ? |
477 | if (adj_start < start) |
Line 448... | Line 478... | ||
448 | end : drm_mm_hole_node_end(entry); |
478 | adj_start = start; |
449 | 479 | if (adj_end > end) |
|
450 | BUG_ON(!entry->hole_follows); |
480 | adj_end = end; |
451 | 481 |