102,20 → 102,6 |
} |
EXPORT_SYMBOL(drm_mm_pre_get); |
|
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) |
{ |
return hole_node->start + hole_node->size; |
} |
|
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) |
{ |
struct drm_mm_node *next_node = |
list_entry(hole_node->node_list.next, struct drm_mm_node, |
node_list); |
|
return next_node->start; |
} |
|
static void drm_mm_insert_helper(struct drm_mm_node *hole_node, |
struct drm_mm_node *node, |
unsigned long size, unsigned alignment, |
127,7 → 113,7 |
unsigned long adj_start = hole_start; |
unsigned long adj_end = hole_end; |
|
BUG_ON(!hole_node->hole_follows || node->allocated); |
BUG_ON(node->allocated); |
|
if (mm->color_adjust) |
mm->color_adjust(hole_node, color, &adj_start, &adj_end); |
155,12 → 141,57 |
BUG_ON(node->start + node->size > adj_end); |
|
node->hole_follows = 0; |
if (node->start + node->size < hole_end) { |
if (__drm_mm_hole_node_start(node) < hole_end) { |
list_add(&node->hole_stack, &mm->hole_stack); |
node->hole_follows = 1; |
} |
} |
|
struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, |
unsigned long start, |
unsigned long size, |
bool atomic) |
{ |
struct drm_mm_node *hole, *node; |
unsigned long end = start + size; |
unsigned long hole_start; |
unsigned long hole_end; |
|
drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { |
if (hole_start > start || hole_end < end) |
continue; |
|
node = drm_mm_kmalloc(mm, atomic); |
if (unlikely(node == NULL)) |
return NULL; |
|
node->start = start; |
node->size = size; |
node->mm = mm; |
node->allocated = 1; |
|
INIT_LIST_HEAD(&node->hole_stack); |
list_add(&node->node_list, &hole->node_list); |
|
if (start == hole_start) { |
hole->hole_follows = 0; |
list_del_init(&hole->hole_stack); |
} |
|
node->hole_follows = 0; |
if (end != hole_end) { |
list_add(&node->hole_stack, &mm->hole_stack); |
node->hole_follows = 1; |
} |
|
return node; |
} |
|
WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); |
return NULL; |
} |
EXPORT_SYMBOL(drm_mm_create_block); |
|
struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, |
unsigned long size, |
unsigned alignment, |
253,7 → 284,7 |
BUG_ON(node->start + node->size > end); |
|
node->hole_follows = 0; |
if (node->start + node->size < hole_end) { |
if (__drm_mm_hole_node_start(node) < hole_end) { |
list_add(&node->hole_stack, &mm->hole_stack); |
node->hole_follows = 1; |
} |
327,13 → 358,14 |
list_entry(node->node_list.prev, struct drm_mm_node, node_list); |
|
if (node->hole_follows) { |
BUG_ON(drm_mm_hole_node_start(node) |
== drm_mm_hole_node_end(node)); |
BUG_ON(__drm_mm_hole_node_start(node) == |
__drm_mm_hole_node_end(node)); |
list_del(&node->hole_stack); |
} else |
BUG_ON(drm_mm_hole_node_start(node) |
!= drm_mm_hole_node_end(node)); |
BUG_ON(__drm_mm_hole_node_start(node) != |
__drm_mm_hole_node_end(node)); |
|
|
if (!prev_node->hole_follows) { |
prev_node->hole_follows = 1; |
list_add(&prev_node->hole_stack, &mm->hole_stack); |
390,6 → 422,8 |
{ |
struct drm_mm_node *entry; |
struct drm_mm_node *best; |
unsigned long adj_start; |
unsigned long adj_end; |
unsigned long best_size; |
|
BUG_ON(mm->scanned_blocks); |
397,10 → 431,7 |
best = NULL; |
best_size = ~0UL; |
|
list_for_each_entry(entry, &mm->hole_stack, hole_stack) { |
unsigned long adj_start = drm_mm_hole_node_start(entry); |
unsigned long adj_end = drm_mm_hole_node_end(entry); |
|
drm_mm_for_each_hole(entry, mm, adj_start, adj_end) { |
if (mm->color_adjust) { |
mm->color_adjust(entry, color, &adj_start, &adj_end); |
if (adj_end <= adj_start) |
407,7 → 438,6 |
continue; |
} |
|
BUG_ON(!entry->hole_follows); |
if (!check_free_hole(adj_start, adj_end, size, alignment)) |
continue; |
|
434,6 → 464,8 |
{ |
struct drm_mm_node *entry; |
struct drm_mm_node *best; |
unsigned long adj_start; |
unsigned long adj_end; |
unsigned long best_size; |
|
BUG_ON(mm->scanned_blocks); |
441,14 → 473,12 |
best = NULL; |
best_size = ~0UL; |
|
list_for_each_entry(entry, &mm->hole_stack, hole_stack) { |
unsigned long adj_start = drm_mm_hole_node_start(entry) < start ? |
start : drm_mm_hole_node_start(entry); |
unsigned long adj_end = drm_mm_hole_node_end(entry) > end ? |
end : drm_mm_hole_node_end(entry); |
drm_mm_for_each_hole(entry, mm, adj_start, adj_end) { |
if (adj_start < start) |
adj_start = start; |
if (adj_end > end) |
adj_end = end; |
|
BUG_ON(!entry->hole_follows); |
|
if (mm->color_adjust) { |
mm->color_adjust(entry, color, &adj_start, &adj_end); |
if (adj_end <= adj_start) |