Rev 3031 | Rev 3480 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3031 | Rev 3192 | ||
---|---|---|---|
Line 182... | Line 182... | ||
182 | /** |
182 | /** |
183 | * Search for free space and insert a preallocated memory node. Returns |
183 | * Search for free space and insert a preallocated memory node. Returns |
184 | * -ENOSPC if no suitable free area is available. The preallocated memory node |
184 | * -ENOSPC if no suitable free area is available. The preallocated memory node |
185 | * must be cleared. |
185 | * must be cleared. |
186 | */ |
186 | */ |
187 | int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, |
187 | int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node, |
188 | unsigned long size, unsigned alignment) |
188 | unsigned long size, unsigned alignment, |
- | 189 | unsigned long color) |
|
189 | { |
190 | { |
190 | struct drm_mm_node *hole_node; |
191 | struct drm_mm_node *hole_node; |
Line 191... | Line 192... | ||
191 | 192 | ||
- | 193 | hole_node = drm_mm_search_free_generic(mm, size, alignment, |
|
192 | hole_node = drm_mm_search_free(mm, size, alignment, false); |
194 | color, 0); |
193 | if (!hole_node) |
195 | if (!hole_node) |
Line 194... | Line 196... | ||
194 | return -ENOSPC; |
196 | return -ENOSPC; |
195 | - | ||
196 | drm_mm_insert_helper(hole_node, node, size, alignment, 0); |
197 | |
197 | 198 | drm_mm_insert_helper(hole_node, node, size, alignment, color); |
|
- | 199 | return 0; |
|
- | 200 | } |
|
- | 201 | EXPORT_SYMBOL(drm_mm_insert_node_generic); |
|
- | 202 | ||
- | 203 | int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, |
|
- | 204 | unsigned long size, unsigned alignment) |
|
- | 205 | { |
|
198 | return 0; |
206 | return drm_mm_insert_node_generic(mm, node, size, alignment, 0); |
Line 199... | Line 207... | ||
199 | } |
207 | } |
200 | EXPORT_SYMBOL(drm_mm_insert_node); |
208 | EXPORT_SYMBOL(drm_mm_insert_node); |
201 | 209 | ||
Line 211... | Line 219... | ||
211 | unsigned long adj_start = hole_start; |
219 | unsigned long adj_start = hole_start; |
212 | unsigned long adj_end = hole_end; |
220 | unsigned long adj_end = hole_end; |
Line 213... | Line 221... | ||
213 | 221 | ||
Line 214... | Line -... | ||
214 | BUG_ON(!hole_node->hole_follows || node->allocated); |
- | |
215 | - | ||
216 | if (mm->color_adjust) |
- | |
217 | mm->color_adjust(hole_node, color, &adj_start, &adj_end); |
222 | BUG_ON(!hole_node->hole_follows || node->allocated); |
218 | 223 | ||
- | 224 | if (adj_start < start) |
|
- | 225 | adj_start = start; |
|
- | 226 | if (adj_end > end) |
|
- | 227 | adj_end = end; |
|
- | 228 | ||
Line 219... | Line 229... | ||
219 | if (adj_start < start) |
229 | if (mm->color_adjust) |
220 | adj_start = start; |
230 | mm->color_adjust(hole_node, color, &adj_start, &adj_end); |
221 | 231 | ||
222 | if (alignment) { |
232 | if (alignment) { |
Line 273... | Line 283... | ||
273 | /** |
283 | /** |
274 | * Search for free space and insert a preallocated memory node. Returns |
284 | * Search for free space and insert a preallocated memory node. Returns |
275 | * -ENOSPC if no suitable free area is available. This is for range |
285 | * -ENOSPC if no suitable free area is available. This is for range |
276 | * restricted allocations. The preallocated memory node must be cleared. |
286 | * restricted allocations. The preallocated memory node must be cleared. |
277 | */ |
287 | */ |
278 | int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, |
288 | int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node, |
279 | unsigned long size, unsigned alignment, |
289 | unsigned long size, unsigned alignment, unsigned long color, |
280 | unsigned long start, unsigned long end) |
290 | unsigned long start, unsigned long end) |
281 | { |
291 | { |
282 | struct drm_mm_node *hole_node; |
292 | struct drm_mm_node *hole_node; |
Line 283... | Line 293... | ||
283 | 293 | ||
- | 294 | hole_node = drm_mm_search_free_in_range_generic(mm, |
|
284 | hole_node = drm_mm_search_free_in_range(mm, size, alignment, |
295 | size, alignment, color, |
285 | start, end, false); |
296 | start, end, 0); |
286 | if (!hole_node) |
297 | if (!hole_node) |
Line 287... | Line 298... | ||
287 | return -ENOSPC; |
298 | return -ENOSPC; |
- | 299 | ||
288 | 300 | drm_mm_insert_helper_range(hole_node, node, |
|
289 | drm_mm_insert_helper_range(hole_node, node, size, alignment, 0, |
- | |
290 | start, end); |
301 | size, alignment, color, |
291 | 302 | start, end); |
|
- | 303 | return 0; |
|
- | 304 | } |
|
- | 305 | EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic); |
|
- | 306 | ||
- | 307 | int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, |
|
- | 308 | unsigned long size, unsigned alignment, |
|
- | 309 | unsigned long start, unsigned long end) |
|
- | 310 | { |
|
292 | return 0; |
311 | return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, 0, start, end); |
Line 293... | Line 312... | ||
293 | } |
312 | } |
294 | EXPORT_SYMBOL(drm_mm_insert_node_in_range); |
313 | EXPORT_SYMBOL(drm_mm_insert_node_in_range); |
295 | 314 | ||
Line 487... | Line 506... | ||
487 | mm->scan_color = color; |
506 | mm->scan_color = color; |
488 | mm->scan_alignment = alignment; |
507 | mm->scan_alignment = alignment; |
489 | mm->scan_size = size; |
508 | mm->scan_size = size; |
490 | mm->scanned_blocks = 0; |
509 | mm->scanned_blocks = 0; |
491 | mm->scan_hit_start = 0; |
510 | mm->scan_hit_start = 0; |
492 | mm->scan_hit_size = 0; |
511 | mm->scan_hit_end = 0; |
493 | mm->scan_check_range = 0; |
512 | mm->scan_check_range = 0; |
494 | mm->prev_scanned_node = NULL; |
513 | mm->prev_scanned_node = NULL; |
495 | } |
514 | } |
496 | EXPORT_SYMBOL(drm_mm_init_scan); |
515 | EXPORT_SYMBOL(drm_mm_init_scan); |
Line 514... | Line 533... | ||
514 | mm->scan_color = color; |
533 | mm->scan_color = color; |
515 | mm->scan_alignment = alignment; |
534 | mm->scan_alignment = alignment; |
516 | mm->scan_size = size; |
535 | mm->scan_size = size; |
517 | mm->scanned_blocks = 0; |
536 | mm->scanned_blocks = 0; |
518 | mm->scan_hit_start = 0; |
537 | mm->scan_hit_start = 0; |
519 | mm->scan_hit_size = 0; |
538 | mm->scan_hit_end = 0; |
520 | mm->scan_start = start; |
539 | mm->scan_start = start; |
521 | mm->scan_end = end; |
540 | mm->scan_end = end; |
522 | mm->scan_check_range = 1; |
541 | mm->scan_check_range = 1; |
523 | mm->prev_scanned_node = NULL; |
542 | mm->prev_scanned_node = NULL; |
524 | } |
543 | } |
Line 533... | Line 552... | ||
533 | int drm_mm_scan_add_block(struct drm_mm_node *node) |
552 | int drm_mm_scan_add_block(struct drm_mm_node *node) |
534 | { |
553 | { |
535 | struct drm_mm *mm = node->mm; |
554 | struct drm_mm *mm = node->mm; |
536 | struct drm_mm_node *prev_node; |
555 | struct drm_mm_node *prev_node; |
537 | unsigned long hole_start, hole_end; |
556 | unsigned long hole_start, hole_end; |
538 | unsigned long adj_start; |
557 | unsigned long adj_start, adj_end; |
539 | unsigned long adj_end; |
- | |
Line 540... | Line 558... | ||
540 | 558 | ||
Line 541... | Line 559... | ||
541 | mm->scanned_blocks++; |
559 | mm->scanned_blocks++; |
542 | 560 | ||
Line 551... | Line 569... | ||
551 | list_del(&node->node_list); |
569 | list_del(&node->node_list); |
552 | node->node_list.prev = &prev_node->node_list; |
570 | node->node_list.prev = &prev_node->node_list; |
553 | node->node_list.next = &mm->prev_scanned_node->node_list; |
571 | node->node_list.next = &mm->prev_scanned_node->node_list; |
554 | mm->prev_scanned_node = node; |
572 | mm->prev_scanned_node = node; |
Line 555... | Line 573... | ||
555 | 573 | ||
556 | hole_start = drm_mm_hole_node_start(prev_node); |
574 | adj_start = hole_start = drm_mm_hole_node_start(prev_node); |
557 | hole_end = drm_mm_hole_node_end(prev_node); |
- | |
558 | - | ||
559 | adj_start = hole_start; |
- | |
560 | adj_end = hole_end; |
- | |
561 | - | ||
562 | if (mm->color_adjust) |
- | |
Line 563... | Line 575... | ||
563 | mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end); |
575 | adj_end = hole_end = drm_mm_hole_node_end(prev_node); |
564 | 576 | ||
565 | if (mm->scan_check_range) { |
577 | if (mm->scan_check_range) { |
566 | if (adj_start < mm->scan_start) |
578 | if (adj_start < mm->scan_start) |
567 | adj_start = mm->scan_start; |
579 | adj_start = mm->scan_start; |
568 | if (adj_end > mm->scan_end) |
580 | if (adj_end > mm->scan_end) |
Line -... | Line 581... | ||
- | 581 | adj_end = mm->scan_end; |
|
- | 582 | } |
|
- | 583 | ||
- | 584 | if (mm->color_adjust) |
|
569 | adj_end = mm->scan_end; |
585 | mm->color_adjust(prev_node, mm->scan_color, |
570 | } |
586 | &adj_start, &adj_end); |
571 | 587 | ||
572 | if (check_free_hole(adj_start, adj_end, |
588 | if (check_free_hole(adj_start, adj_end, |
573 | mm->scan_size, mm->scan_alignment)) { |
- | |
574 | mm->scan_hit_start = hole_start; |
589 | mm->scan_size, mm->scan_alignment)) { |
575 | mm->scan_hit_size = hole_end; |
590 | mm->scan_hit_start = hole_start; |
Line 576... | Line 591... | ||
576 | 591 | mm->scan_hit_end = hole_end; |
|
577 | return 1; |
592 | return 1; |
Line 607... | Line 622... | ||
607 | 622 | ||
608 | prev_node = list_entry(node->node_list.prev, struct drm_mm_node, |
623 | prev_node = list_entry(node->node_list.prev, struct drm_mm_node, |
Line 609... | Line 624... | ||
609 | node_list); |
624 | node_list); |
610 | - | ||
611 | prev_node->hole_follows = node->scanned_preceeds_hole; |
625 | |
Line 612... | Line -... | ||
612 | INIT_LIST_HEAD(&node->node_list); |
- | |
613 | list_add(&node->node_list, &prev_node->node_list); |
- | |
614 | - | ||
615 | /* Only need to check for containement because start&size for the |
626 | prev_node->hole_follows = node->scanned_preceeds_hole; |
616 | * complete resulting free block (not just the desired part) is |
627 | list_add(&node->node_list, &prev_node->node_list); |
617 | * stored. */ |
- | |
618 | if (node->start >= mm->scan_hit_start && |
- | |
619 | node->start + node->size |
- | |
620 | <= mm->scan_hit_start + mm->scan_hit_size) { |
- | |
621 | return 1; |
- | |
622 | } |
628 | |
623 | 629 | return (drm_mm_hole_node_end(node) > mm->scan_hit_start && |
|
Line 624... | Line 630... | ||
624 | return 0; |
630 | node->start < mm->scan_hit_end); |
625 | } |
631 | } |
Line 677... | Line 683... | ||
677 | spin_unlock(&mm->unused_lock); |
683 | spin_unlock(&mm->unused_lock); |
Line 678... | Line 684... | ||
678 | 684 | ||
679 | BUG_ON(mm->num_unused != 0); |
685 | BUG_ON(mm->num_unused != 0); |
680 | } |
686 | } |
- | 687 | EXPORT_SYMBOL(drm_mm_takedown); |
|
- | 688 | ||
- | 689 | void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) |
|
- | 690 | { |
|
- | 691 | struct drm_mm_node *entry; |
|
- | 692 | unsigned long total_used = 0, total_free = 0, total = 0; |
|
- | 693 | unsigned long hole_start, hole_end, hole_size; |
|
- | 694 | ||
- | 695 | hole_start = drm_mm_hole_node_start(&mm->head_node); |
|
- | 696 | hole_end = drm_mm_hole_node_end(&mm->head_node); |
|
- | 697 | hole_size = hole_end - hole_start; |
|
- | 698 | if (hole_size) |
|
- | 699 | printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n", |
|
- | 700 | prefix, hole_start, hole_end, |
|
- | 701 | hole_size); |
|
- | 702 | total_free += hole_size; |
|
- | 703 | ||
- | 704 | drm_mm_for_each_node(entry, mm) { |
|
- | 705 | printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: used\n", |
|
- | 706 | prefix, entry->start, entry->start + entry->size, |
|
- | 707 | entry->size); |
|
- | 708 | total_used += entry->size; |
|
- | 709 | ||
- | 710 | if (entry->hole_follows) { |
|
- | 711 | hole_start = drm_mm_hole_node_start(entry); |
|
- | 712 | hole_end = drm_mm_hole_node_end(entry); |
|
- | 713 | hole_size = hole_end - hole_start; |
|
- | 714 | printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n", |
|
- | 715 | prefix, hole_start, hole_end, |
|
- | 716 | hole_size); |
|
- | 717 | total_free += hole_size; |
|
- | 718 | } |
|
- | 719 | } |
|
- | 720 | total = total_free + total_used; |
|
- | 721 | ||
- | 722 | printk(KERN_DEBUG "%s total: %lu, used %lu free %lu\n", prefix, total, |
|
- | 723 | total_used, total_free); |
|
- | 724 | } |
|
- | 725 | EXPORT_SYMBOL(drm_mm_debug_table); |
|
- | 726 | ||
- | 727 | #if defined(CONFIG_DEBUG_FS) |
|
- | 728 | int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) |
|
- | 729 | { |
|
- | 730 | struct drm_mm_node *entry; |
|
- | 731 | unsigned long total_used = 0, total_free = 0, total = 0; |
|
- | 732 | unsigned long hole_start, hole_end, hole_size; |
|
- | 733 | ||
- | 734 | hole_start = drm_mm_hole_node_start(&mm->head_node); |
|
- | 735 | hole_end = drm_mm_hole_node_end(&mm->head_node); |
|
- | 736 | hole_size = hole_end - hole_start; |
|
- | 737 | if (hole_size) |
|
- | 738 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", |
|
- | 739 | hole_start, hole_end, hole_size); |
|
- | 740 | total_free += hole_size; |
|
- | 741 | ||
- | 742 | drm_mm_for_each_node(entry, mm) { |
|
- | 743 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", |
|
- | 744 | entry->start, entry->start + entry->size, |
|
- | 745 | entry->size); |
|
- | 746 | total_used += entry->size; |
|
- | 747 | if (entry->hole_follows) { |
|
- | 748 | hole_start = drm_mm_hole_node_start(entry); |
|
- | 749 | hole_end = drm_mm_hole_node_end(entry); |
|
- | 750 | hole_size = hole_end - hole_start; |
|
- | 751 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", |
|
- | 752 | hole_start, hole_end, hole_size); |
|
- | 753 | total_free += hole_size; |
|
- | 754 | } |
|
- | 755 | } |
|
- | 756 | total = total_free + total_used; |
|
- | 757 | ||
- | 758 | seq_printf(m, "total: %lu, used %lu free %lu\n", total, total_used, total_free); |
|
- | 759 | return 0; |
|
- | 760 | } |
|
- | 761 | EXPORT_SYMBOL(drm_mm_dump_table); |