15 #include <linux/types.h>
16 #include <linux/errno.h>
17 #include <linux/kernel.h>
18 #include <linux/export.h>
21 #include <linux/slab.h>
30 static inline void fixup(
unsigned long s,
unsigned long e,
int d,
35 pp = (
unsigned long *)&l->
next;
36 if (*pp >= s && *pp < e)
39 pp = (
unsigned long *)&l->
prev;
40 if (*pp >= s && *pp < e)
50 unsigned long blks, blke;
52 if (max_blocks <= info->max_blocks)
67 delta = (
char *)block - (
char *)info->
block;
73 for (i = 0, blk = block; i < info->
max_blocks; i++, blk++)
92 for (i = 0; i < new_blocks; i++, blk++)
118 return grow(info, max_blocks);
134 list_del_init(&blk->
list);
158 unsigned long s,
e, bs, be;
178 if (next ==
NULL && s >= bs)
188 if (before !=
NULL && after !=
NULL)
193 if (before && s != (before->
start + before->
size))
196 if (after && e != after->
start)
200 if (before ==
NULL && after ==
NULL) {
211 release_slot(info, blkn);
214 if (before !=
NULL && after ==
NULL) {
220 if (before ==
NULL && after !=
NULL) {
229 release_slot(info, after);
258 if ((alignment & (alignment - 1)) != 0)
307 if ((alignment & (alignment - 1)) != 0)
323 for (i = 0, blk = block; i < max_blocks; i++, blk++)
332 unsigned long s,
e,
m;
354 r = assure_empty(info, 1);
358 blk = get_slot(info);
363 attach_free_block(info, blk);
374 unsigned long s,
e,
m, bs, be;
378 return (
unsigned long) -
EINVAL;
391 if (assure_empty(info, 1) < 0)
392 return (
unsigned long) -
ENOMEM;
400 if (s >= bs && e <= be)
406 return (
unsigned long) -
ENOMEM;
409 if (bs == s && be == e) {
412 release_slot(info, blk);
417 if (bs == s || be == e) {
427 newblk = get_slot(info);
429 newblk->
size = be -
e;
431 list_add(&newblk->
list, &blk->
list);
447 unsigned long start, sp_size;
450 if (size <= 0 || (alignment & (alignment - 1)) != 0)
451 return (
unsigned long) -
EINVAL;
456 if (assure_empty(info, 2) < 0)
457 return (
unsigned long) -
ENOMEM;
462 if (size <= blk->size) {
463 start = (blk->
start + alignment - 1) & ~(alignment - 1);
464 if (start + size <= blk->start + blk->
size)
471 return (
unsigned long) -
ENOMEM;
474 if (blk->
size == size) {
481 sp_size = start - blk->
start;
485 spblk = get_slot(info);
487 spblk->
size = sp_size;
489 list_add(&spblk->
list, blk->
list.prev);
491 newblk = get_slot(info);
500 if (blk->
size == 0) {
502 release_slot(info, blk);
507 attach_taken_block(info, newblk);
531 unsigned long s,
e,
m, bs = 0, be = 0;
535 return (
unsigned long) -
EINVAL;
548 if (assure_empty(info, 2) < 0)
549 return (
unsigned long) -
ENOMEM;
557 if (s >= bs && e <= be)
563 return (
unsigned long) -
ENOMEM;
566 if (bs == s && be == e) {
572 attach_taken_block(info, blk);
579 if (bs == s || be == e) {
589 newblk2 = get_slot(info);
591 newblk2->
size = be -
e;
593 list_add(&newblk2->
list, &blk->
list);
596 newblk1 = get_slot(info);
598 newblk1->
size = e -
s;
601 start = newblk1->
start;
602 attach_taken_block(info, newblk1);
622 if (start < blk2->start)
635 attach_free_block(info, blk);
666 if (stats !=
NULL && nr < max_stats) {
689 if (start < blk2->start)
713 "info @0x%p (%d slots empty / %d max)\n",
720 for (i = 0; i <
nr; i++)
722 " 0x%lx-0x%lx (%u)\n",
723 st[i].
start, st[i].start + st[i].size,
731 for (i = 0; i <
nr; i++)
733 " 0x%lx-0x%lx (%u) %s\n",
734 st[i].start, st[i].start + st[i].size,
743 "blk @0x%p: 0x%lx-0x%lx (%u)\n",