Lines Matching +full:block +full:- +full:size
35 pp = (unsigned long *)&l->next; in fixup()
39 pp = (unsigned long *)&l->prev; in fixup()
47 rh_block_t *block, *blk; in grow() local
52 if (max_blocks <= info->max_blocks) in grow()
53 return -EINVAL; in grow()
55 new_blocks = max_blocks - info->max_blocks; in grow()
57 block = kmalloc_array(max_blocks, sizeof(rh_block_t), GFP_ATOMIC); in grow()
58 if (block == NULL) in grow()
59 return -ENOMEM; in grow()
61 if (info->max_blocks > 0) { in grow()
63 /* copy old block area */ in grow()
64 memcpy(block, info->block, in grow()
65 sizeof(rh_block_t) * info->max_blocks); in grow()
67 delta = (char *)block - (char *)info->block; in grow()
70 blks = (unsigned long)info->block; in grow()
71 blke = (unsigned long)(info->block + info->max_blocks); in grow()
73 for (i = 0, blk = block; i < info->max_blocks; i++, blk++) in grow()
74 fixup(blks, blke, delta, &blk->list); in grow()
76 fixup(blks, blke, delta, &info->empty_list); in grow()
77 fixup(blks, blke, delta, &info->free_list); in grow()
78 fixup(blks, blke, delta, &info->taken_list); in grow()
81 if ((info->flags & RHIF_STATIC_BLOCK) == 0) in grow()
82 kfree(info->block); in grow()
85 info->block = block; in grow()
86 info->empty_slots += new_blocks; in grow()
87 info->max_blocks = max_blocks; in grow()
88 info->flags &= ~RHIF_STATIC_BLOCK; in grow()
91 blk = block + info->max_blocks - new_blocks; in grow()
93 list_add(&blk->list, &info->empty_list); in grow()
100 * causes a grow in the block area then all pointers kept to the block
109 return -EINVAL; in assure_empty()
112 if (info->empty_slots >= slots) in assure_empty()
115 /* Next 16 sized block */ in assure_empty()
116 max_blocks = ((info->max_blocks + slots) + 15) & ~15; in assure_empty()
127 if (info->empty_slots == 0) { in get_slot()
133 blk = list_entry(info->empty_list.next, rh_block_t, list); in get_slot()
134 list_del_init(&blk->list); in get_slot()
135 info->empty_slots--; in get_slot()
138 blk->start = 0; in get_slot()
139 blk->size = 0; in get_slot()
140 blk->owner = NULL; in get_slot()
147 list_add(&blk->list, &info->empty_list); in release_slot()
148 info->empty_slots++; in release_slot()
157 int size; in attach_free_block() local
162 size = blkn->size; in attach_free_block()
163 s = blkn->start; in attach_free_block()
164 e = s + size; in attach_free_block()
172 list_for_each(l, &info->free_list) { in attach_free_block()
175 bs = blk->start; in attach_free_block()
176 be = bs + blk->size; in attach_free_block()
193 if (before && s != (before->start + before->size)) in attach_free_block()
196 if (after && e != after->start) in attach_free_block()
203 list_add(&blkn->list, &next->list); in attach_free_block()
205 list_add(&blkn->list, &info->free_list); in attach_free_block()
213 /* Grow the before block */ in attach_free_block()
215 before->size += size; in attach_free_block()
219 /* Grow the after block backwards */ in attach_free_block()
221 after->start -= size; in attach_free_block()
222 after->size += size; in attach_free_block()
226 /* Grow the before block, and release the after block */ in attach_free_block()
227 before->size += size + after->size; in attach_free_block()
228 list_del(&after->list); in attach_free_block()
237 /* Find the block immediately before the given one (if any) */ in attach_taken_block()
238 list_for_each(l, &info->taken_list) { in attach_taken_block()
240 if (blk->start > blkn->start) { in attach_taken_block()
241 list_add_tail(&blkn->list, &blk->list); in attach_taken_block()
246 list_add_tail(&blkn->list, &info->taken_list); in attach_taken_block()
258 if ((alignment & (alignment - 1)) != 0) in rh_create()
259 return ERR_PTR(-EINVAL); in rh_create()
263 return ERR_PTR(-ENOMEM); in rh_create()
265 info->alignment = alignment; in rh_create()
268 info->block = NULL; in rh_create()
269 info->max_blocks = 0; in rh_create()
270 info->empty_slots = 0; in rh_create()
271 info->flags = 0; in rh_create()
273 INIT_LIST_HEAD(&info->empty_list); in rh_create()
274 INIT_LIST_HEAD(&info->free_list); in rh_create()
275 INIT_LIST_HEAD(&info->taken_list); in rh_create()
287 if ((info->flags & RHIF_STATIC_BLOCK) == 0) in rh_destroy()
288 kfree(info->block); in rh_destroy()
290 if ((info->flags & RHIF_STATIC_INFO) == 0) in rh_destroy()
296 * Initialize in place a remote heap info block. This is needed to support
301 rh_block_t * block) in rh_init() argument
307 if ((alignment & (alignment - 1)) != 0) in rh_init()
310 info->alignment = alignment; in rh_init()
313 info->block = block; in rh_init()
314 info->max_blocks = max_blocks; in rh_init()
315 info->empty_slots = max_blocks; in rh_init()
316 info->flags = RHIF_STATIC_INFO | RHIF_STATIC_BLOCK; in rh_init()
318 INIT_LIST_HEAD(&info->empty_list); in rh_init()
319 INIT_LIST_HEAD(&info->free_list); in rh_init()
320 INIT_LIST_HEAD(&info->taken_list); in rh_init()
323 for (i = 0, blk = block; i < max_blocks; i++, blk++) in rh_init()
324 list_add(&blk->list, &info->empty_list); in rh_init()
329 int rh_attach_region(rh_info_t * info, unsigned long start, int size) in rh_attach_region() argument
337 e = s + size; in rh_attach_region()
338 m = info->alignment - 1; in rh_attach_region()
347 return -ERANGE; in rh_attach_region()
351 size = e - s; in rh_attach_region()
359 blk->start = start; in rh_attach_region()
360 blk->size = size; in rh_attach_region()
361 blk->owner = NULL; in rh_attach_region()
369 /* Detatch given address range, splits free block if needed. */
370 unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size) in rh_detach_region() argument
376 /* Validate size */ in rh_detach_region()
377 if (size <= 0) in rh_detach_region()
378 return (unsigned long) -EINVAL; in rh_detach_region()
382 e = s + size; in rh_detach_region()
383 m = info->alignment - 1; in rh_detach_region()
392 return (unsigned long) -ENOMEM; in rh_detach_region()
395 list_for_each(l, &info->free_list) { in rh_detach_region()
397 /* The range must lie entirely inside one free block */ in rh_detach_region()
398 bs = blk->start; in rh_detach_region()
399 be = blk->start + blk->size; in rh_detach_region()
406 return (unsigned long) -ENOMEM; in rh_detach_region()
411 list_del(&blk->list); in rh_detach_region()
416 /* blk still in free list, with updated start and/or size */ in rh_detach_region()
419 blk->start += size; in rh_detach_region()
420 blk->size -= size; in rh_detach_region()
424 blk->size = s - bs; in rh_detach_region()
428 newblk->start = e; in rh_detach_region()
429 newblk->size = be - e; in rh_detach_region()
431 list_add(&newblk->list, &blk->list); in rh_detach_region()
438 /* Allocate a block of memory at the specified alignment. The value returned
442 unsigned long rh_alloc_align(rh_info_t * info, int size, int alignment, const char *owner) in rh_alloc_align() argument
449 /* Validate size, and alignment must be power of two */ in rh_alloc_align()
450 if (size <= 0 || (alignment & (alignment - 1)) != 0) in rh_alloc_align()
451 return (unsigned long) -EINVAL; in rh_alloc_align()
454 size = (size + (info->alignment - 1)) & ~(info->alignment - 1); in rh_alloc_align()
457 return (unsigned long) -ENOMEM; in rh_alloc_align()
460 list_for_each(l, &info->free_list) { in rh_alloc_align()
462 if (size <= blk->size) { in rh_alloc_align()
463 start = (blk->start + alignment - 1) & ~(alignment - 1); in rh_alloc_align()
464 if (start + size <= blk->start + blk->size) in rh_alloc_align()
471 return (unsigned long) -ENOMEM; in rh_alloc_align()
474 if (blk->size == size) { in rh_alloc_align()
476 list_del(&blk->list); in rh_alloc_align()
480 /* Create block for fragment in the beginning */ in rh_alloc_align()
481 sp_size = start - blk->start; in rh_alloc_align()
486 spblk->start = blk->start; in rh_alloc_align()
487 spblk->size = sp_size; in rh_alloc_align()
489 list_add(&spblk->list, blk->list.prev); in rh_alloc_align()
492 newblk->start = start; in rh_alloc_align()
493 newblk->size = size; in rh_alloc_align()
495 /* blk still in free list, with updated start and size in rh_alloc_align()
497 blk->start = start + size; in rh_alloc_align()
498 blk->size -= sp_size + size; in rh_alloc_align()
500 if (blk->size == 0) { in rh_alloc_align()
501 list_del(&blk->list); in rh_alloc_align()
506 newblk->owner = owner; in rh_alloc_align()
513 /* Allocate a block of memory at the default alignment. The value returned is
517 unsigned long rh_alloc(rh_info_t * info, int size, const char *owner) in rh_alloc() argument
519 return rh_alloc_align(info, size, info->alignment, owner); in rh_alloc()
523 /* Allocate a block of memory at the given offset, rounded up to the default
527 unsigned long rh_alloc_fixed(rh_info_t * info, unsigned long start, int size, const char *owner) in rh_alloc_fixed() argument
533 /* Validate size */ in rh_alloc_fixed()
534 if (size <= 0) in rh_alloc_fixed()
535 return (unsigned long) -EINVAL; in rh_alloc_fixed()
539 e = s + size; in rh_alloc_fixed()
540 m = info->alignment - 1; in rh_alloc_fixed()
549 return (unsigned long) -ENOMEM; in rh_alloc_fixed()
552 list_for_each(l, &info->free_list) { in rh_alloc_fixed()
554 /* The range must lie entirely inside one free block */ in rh_alloc_fixed()
555 bs = blk->start; in rh_alloc_fixed()
556 be = blk->start + blk->size; in rh_alloc_fixed()
563 return (unsigned long) -ENOMEM; in rh_alloc_fixed()
568 list_del(&blk->list); in rh_alloc_fixed()
569 blk->owner = owner; in rh_alloc_fixed()
571 start = blk->start; in rh_alloc_fixed()
578 /* blk still in free list, with updated start and/or size */ in rh_alloc_fixed()
581 blk->start += size; in rh_alloc_fixed()
582 blk->size -= size; in rh_alloc_fixed()
586 blk->size = s - bs; in rh_alloc_fixed()
590 newblk2->start = e; in rh_alloc_fixed()
591 newblk2->size = be - e; in rh_alloc_fixed()
593 list_add(&newblk2->list, &blk->list); in rh_alloc_fixed()
597 newblk1->start = s; in rh_alloc_fixed()
598 newblk1->size = e - s; in rh_alloc_fixed()
599 newblk1->owner = owner; in rh_alloc_fixed()
601 start = newblk1->start; in rh_alloc_fixed()
609 * The return value is the size of the deallocated block, or a negative number
616 int size; in rh_free() local
618 /* Linear search for block */ in rh_free()
620 list_for_each(l, &info->taken_list) { in rh_free()
622 if (start < blk2->start) in rh_free()
627 if (blk == NULL || start > (blk->start + blk->size)) in rh_free()
628 return -EINVAL; in rh_free()
631 list_del(&blk->list); in rh_free()
633 /* Get size of freed block */ in rh_free()
634 size = blk->size; in rh_free()
637 return size; in rh_free()
651 h = &info->free_list; in rh_get_stats()
655 h = &info->taken_list; in rh_get_stats()
659 return -EINVAL; in rh_get_stats()
662 /* Linear search for block */ in rh_get_stats()
667 stats->start = blk->start; in rh_get_stats()
668 stats->size = blk->size; in rh_get_stats()
669 stats->owner = blk->owner; in rh_get_stats()
683 int size; in rh_set_owner() local
685 /* Linear search for block */ in rh_set_owner()
687 list_for_each(l, &info->taken_list) { in rh_set_owner()
689 if (start < blk2->start) in rh_set_owner()
694 if (blk == NULL || start > (blk->start + blk->size)) in rh_set_owner()
695 return -EINVAL; in rh_set_owner()
697 blk->owner = owner; in rh_set_owner()
698 size = blk->size; in rh_set_owner()
700 return size; in rh_set_owner()
714 info, info->empty_slots, info->max_blocks); in rh_dump()
722 " 0x%lx-0x%lx (%u)\n", in rh_dump()
723 st[i].start, st[i].start + st[i].size, in rh_dump()
724 st[i].size); in rh_dump()
733 " 0x%lx-0x%lx (%u) %s\n", in rh_dump()
734 st[i].start, st[i].start + st[i].size, in rh_dump()
735 st[i].size, st[i].owner != NULL ? st[i].owner : ""); in rh_dump()
743 "blk @0x%p: 0x%lx-0x%lx (%u)\n", in rh_dump_blk()
744 blk, blk->start, blk->start + blk->size, blk->size); in rh_dump_blk()