Rev 1767 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1767 | Rev 1780 | ||
|---|---|---|---|
| Line 67... | Line 67... | ||
| 67 | #include <bitops.h> |
67 | #include <bitops.h> |
| 68 | #include <macros.h> |
68 | #include <macros.h> |
| 69 | 69 | ||
| 70 | typedef struct { |
70 | typedef struct { |
| 71 | count_t refcount; /**< tracking of shared frames */ |
71 | count_t refcount; /**< tracking of shared frames */ |
| 72 | __u8 buddy_order; /**< buddy system block order */ |
72 | uint8_t buddy_order; /**< buddy system block order */ |
| 73 | link_t buddy_link; /**< link to the next free block inside one order */ |
73 | link_t buddy_link; /**< link to the next free block inside one order */ |
| 74 | void *parent; /**< If allocated by slab, this points there */ |
74 | void *parent; /**< If allocated by slab, this points there */ |
| 75 | } frame_t; |
75 | } frame_t; |
| 76 | 76 | ||
| 77 | typedef struct { |
77 | typedef struct { |
| Line 215... | Line 215... | ||
| 215 | spinlock_unlock(&zones.lock); |
215 | spinlock_unlock(&zones.lock); |
| 216 | return NULL; |
216 | return NULL; |
| 217 | } |
217 | } |
| 218 | 218 | ||
| 219 | /** @return True if zone can allocate specified order */ |
219 | /** @return True if zone can allocate specified order */ |
| 220 | static int zone_can_alloc(zone_t *z, __u8 order) |
220 | static int zone_can_alloc(zone_t *z, uint8_t order) |
| 221 | { |
221 | { |
| 222 | return buddy_system_can_alloc(z->buddy_system, order); |
222 | return buddy_system_can_alloc(z->buddy_system, order); |
| 223 | } |
223 | } |
| 224 | 224 | ||
| 225 | /** |
225 | /** |
| Line 228... | Line 228... | ||
| 228 | * Assume interrupts are disabled!! |
228 | * Assume interrupts are disabled!! |
| 229 | * |
229 | * |
| 230 | * @param order Size (2^order) of free space we are trying to find |
230 | * @param order Size (2^order) of free space we are trying to find |
| 231 | * @param pzone Pointer to preferred zone or NULL, on return contains zone number |
231 | * @param pzone Pointer to preferred zone or NULL, on return contains zone number |
| 232 | */ |
232 | */ |
| 233 | static zone_t * find_free_zone_lock(__u8 order, int *pzone) |
233 | static zone_t * find_free_zone_lock(uint8_t order, int *pzone) |
| 234 | { |
234 | { |
| 235 | int i; |
235 | int i; |
| 236 | zone_t *z; |
236 | zone_t *z; |
| 237 | int hint = pzone ? *pzone : 0; |
237 | int hint = pzone ? *pzone : 0; |
| 238 | 238 | ||
| Line 269... | Line 269... | ||
| 269 | * That means go to lower addresses, until such block is found |
269 | * That means go to lower addresses, until such block is found |
| 270 | * |
270 | * |
| 271 | * @param order - Order of parent must be different then this parameter!! |
271 | * @param order - Order of parent must be different then this parameter!! |
| 272 | */ |
272 | */ |
| 273 | static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child, |
273 | static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child, |
| 274 | __u8 order) |
274 | uint8_t order) |
| 275 | { |
275 | { |
| 276 | frame_t * frame; |
276 | frame_t * frame; |
| 277 | zone_t * zone; |
277 | zone_t * zone; |
| 278 | index_t index; |
278 | index_t index; |
| 279 | 279 | ||
| Line 378... | Line 378... | ||
| 378 | * |
378 | * |
| 379 | * @param b Buddy system. |
379 | * @param b Buddy system. |
| 380 | * @param block Buddy system block |
380 | * @param block Buddy system block |
| 381 | * @param order Order to set |
381 | * @param order Order to set |
| 382 | */ |
382 | */ |
| 383 | static void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order) { |
383 | static void zone_buddy_set_order(buddy_system_t *b, link_t * block, uint8_t order) { |
| 384 | frame_t * frame; |
384 | frame_t * frame; |
| 385 | frame = list_get_instance(block, frame_t, buddy_link); |
385 | frame = list_get_instance(block, frame_t, buddy_link); |
| 386 | frame->buddy_order = order; |
386 | frame->buddy_order = order; |
| 387 | } |
387 | } |
| 388 | 388 | ||
| Line 391... | Line 391... | ||
| 391 | * @param b Buddy system. |
391 | * @param b Buddy system. |
| 392 | * @param block Buddy system block |
392 | * @param block Buddy system block |
| 393 | * |
393 | * |
| 394 | * @return Order of block |
394 | * @return Order of block |
| 395 | */ |
395 | */ |
| 396 | static __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block) { |
396 | static uint8_t zone_buddy_get_order(buddy_system_t *b, link_t * block) { |
| 397 | frame_t * frame; |
397 | frame_t * frame; |
| 398 | frame = list_get_instance(block, frame_t, buddy_link); |
398 | frame = list_get_instance(block, frame_t, buddy_link); |
| 399 | return frame->buddy_order; |
399 | return frame->buddy_order; |
| 400 | } |
400 | } |
| 401 | 401 | ||
| Line 448... | Line 448... | ||
| 448 | * @param order Allocate exactly 2^order frames. |
448 | * @param order Allocate exactly 2^order frames. |
| 449 | * |
449 | * |
| 450 | * @return Frame index in zone |
450 | * @return Frame index in zone |
| 451 | * |
451 | * |
| 452 | */ |
452 | */ |
| 453 | static pfn_t zone_frame_alloc(zone_t *zone, __u8 order) |
453 | static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order) |
| 454 | { |
454 | { |
| 455 | pfn_t v; |
455 | pfn_t v; |
| 456 | link_t *tmp; |
456 | link_t *tmp; |
| 457 | frame_t *frame; |
457 | frame_t *frame; |
| 458 | 458 | ||
| Line 481... | Line 481... | ||
| 481 | * @param frame_idx Frame index relative to zone |
481 | * @param frame_idx Frame index relative to zone |
| 482 | */ |
482 | */ |
| 483 | static void zone_frame_free(zone_t *zone, index_t frame_idx) |
483 | static void zone_frame_free(zone_t *zone, index_t frame_idx) |
| 484 | { |
484 | { |
| 485 | frame_t *frame; |
485 | frame_t *frame; |
| 486 | __u8 order; |
486 | uint8_t order; |
| 487 | 487 | ||
| 488 | frame = &zone->frames[frame_idx]; |
488 | frame = &zone->frames[frame_idx]; |
| 489 | 489 | ||
| 490 | /* remember frame order */ |
490 | /* remember frame order */ |
| 491 | order = frame->buddy_order; |
491 | order = frame->buddy_order; |
| Line 535... | Line 535... | ||
| 535 | * @param z2 Zone to merge |
535 | * @param z2 Zone to merge |
| 536 | */ |
536 | */ |
| 537 | 537 | ||
| 538 | static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2) |
538 | static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2) |
| 539 | { |
539 | { |
| 540 | __u8 max_order; |
540 | uint8_t max_order; |
| 541 | int i, z2idx; |
541 | int i, z2idx; |
| 542 | pfn_t frame_idx; |
542 | pfn_t frame_idx; |
| 543 | frame_t *frame; |
543 | frame_t *frame; |
| 544 | 544 | ||
| 545 | ASSERT(!overlaps(z1->base,z1->count,z2->base,z2->count)); |
545 | ASSERT(!overlaps(z1->base,z1->count,z2->base,z2->count)); |
| Line 622... | Line 622... | ||
| 622 | pfn_t pfn; |
622 | pfn_t pfn; |
| 623 | frame_t *frame; |
623 | frame_t *frame; |
| 624 | count_t cframes; |
624 | count_t cframes; |
| 625 | int i; |
625 | int i; |
| 626 | 626 | ||
| 627 | pfn = ADDR2PFN((__address)KA2PA(oldzone)); |
627 | pfn = ADDR2PFN((uintptr_t)KA2PA(oldzone)); |
| 628 | cframes = SIZE2FRAMES(zone_conf_size(oldzone->count)); |
628 | cframes = SIZE2FRAMES(zone_conf_size(oldzone->count)); |
| 629 | 629 | ||
| 630 | if (pfn < newzone->base || pfn >= newzone->base + newzone->count) |
630 | if (pfn < newzone->base || pfn >= newzone->base + newzone->count) |
| 631 | return; |
631 | return; |
| 632 | 632 | ||
| Line 651... | Line 651... | ||
| 651 | * @param count Allocated space in block |
651 | * @param count Allocated space in block |
| 652 | */ |
652 | */ |
| 653 | static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count) |
653 | static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count) |
| 654 | { |
654 | { |
| 655 | count_t i; |
655 | count_t i; |
| 656 | __u8 order; |
656 | uint8_t order; |
| 657 | frame_t *frame; |
657 | frame_t *frame; |
| 658 | 658 | ||
| 659 | ASSERT(frame_idx+count < zone->count); |
659 | ASSERT(frame_idx+count < zone->count); |
| 660 | 660 | ||
| 661 | order = zone->frames[frame_idx].buddy_order; |
661 | order = zone->frames[frame_idx].buddy_order; |
| Line 687... | Line 687... | ||
| 687 | void zone_merge(int z1, int z2) |
687 | void zone_merge(int z1, int z2) |
| 688 | { |
688 | { |
| 689 | ipl_t ipl; |
689 | ipl_t ipl; |
| 690 | zone_t *zone1, *zone2, *newzone; |
690 | zone_t *zone1, *zone2, *newzone; |
| 691 | int cframes; |
691 | int cframes; |
| 692 | __u8 order; |
692 | uint8_t order; |
| 693 | int i; |
693 | int i; |
| 694 | pfn_t pfn; |
694 | pfn_t pfn; |
| 695 | 695 | ||
| 696 | ipl = interrupts_disable(); |
696 | ipl = interrupts_disable(); |
| 697 | spinlock_lock(&zones.lock); |
697 | spinlock_lock(&zones.lock); |
| Line 777... | Line 777... | ||
| 777 | * @return Initialized zone. |
777 | * @return Initialized zone. |
| 778 | */ |
778 | */ |
| 779 | static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags) |
779 | static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags) |
| 780 | { |
780 | { |
| 781 | int i; |
781 | int i; |
| 782 | __u8 max_order; |
782 | uint8_t max_order; |
| 783 | 783 | ||
| 784 | spinlock_initialize(&z->lock, "zone_lock"); |
784 | spinlock_initialize(&z->lock, "zone_lock"); |
| 785 | z->base = start; |
785 | z->base = start; |
| 786 | z->count = count; |
786 | z->count = count; |
| 787 | z->flags = flags; |
787 | z->flags = flags; |
| Line 815... | Line 815... | ||
| 815 | /** Compute configuration data size for zone |
815 | /** Compute configuration data size for zone |
| 816 | * |
816 | * |
| 817 | * @param count Size of zone in frames |
817 | * @param count Size of zone in frames |
| 818 | * @return Size of zone configuration info (in bytes) |
818 | * @return Size of zone configuration info (in bytes) |
| 819 | */ |
819 | */ |
| 820 | __address zone_conf_size(count_t count) |
820 | uintptr_t zone_conf_size(count_t count) |
| 821 | { |
821 | { |
| 822 | int size = sizeof(zone_t) + count*sizeof(frame_t); |
822 | int size = sizeof(zone_t) + count*sizeof(frame_t); |
| 823 | int max_order; |
823 | int max_order; |
| 824 | 824 | ||
| 825 | max_order = fnzb(count); |
825 | max_order = fnzb(count); |
| Line 843... | Line 843... | ||
| 843 | * @return Zone number or -1 on error |
843 | * @return Zone number or -1 on error |
| 844 | */ |
844 | */ |
| 845 | int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags) |
845 | int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags) |
| 846 | { |
846 | { |
| 847 | zone_t *z; |
847 | zone_t *z; |
| 848 | __address addr; |
848 | uintptr_t addr; |
| 849 | count_t confcount; |
849 | count_t confcount; |
| 850 | int i; |
850 | int i; |
| 851 | int znum; |
851 | int znum; |
| 852 | 852 | ||
| 853 | /* Theoretically we could have here 0, practically make sure |
853 | /* Theoretically we could have here 0, practically make sure |
| Line 929... | Line 929... | ||
| 929 | * @param pzone Preferred zone |
929 | * @param pzone Preferred zone |
| 930 | * |
930 | * |
| 931 | * @return Physical address of the allocated frame. |
931 | * @return Physical address of the allocated frame. |
| 932 | * |
932 | * |
| 933 | */ |
933 | */ |
| 934 | void * frame_alloc_generic(__u8 order, int flags, int *pzone) |
934 | void * frame_alloc_generic(uint8_t order, int flags, int *pzone) |
| 935 | { |
935 | { |
| 936 | ipl_t ipl; |
936 | ipl_t ipl; |
| 937 | int freed; |
937 | int freed; |
| 938 | pfn_t v; |
938 | pfn_t v; |
| 939 | zone_t *zone; |
939 | zone_t *zone; |
| Line 988... | Line 988... | ||
| 988 | * Decrement frame reference count. |
988 | * Decrement frame reference count. |
| 989 | * If it drops to zero, move the frame structure to free list. |
989 | * If it drops to zero, move the frame structure to free list. |
| 990 | * |
990 | * |
| 991 | * @param Frame Physical Address of of the frame to be freed. |
991 | * @param Frame Physical Address of of the frame to be freed. |
| 992 | */ |
992 | */ |
| 993 | void frame_free(__address frame) |
993 | void frame_free(uintptr_t frame) |
| 994 | { |
994 | { |
| 995 | ipl_t ipl; |
995 | ipl_t ipl; |
| 996 | zone_t *zone; |
996 | zone_t *zone; |
| 997 | pfn_t pfn = ADDR2PFN(frame); |
997 | pfn_t pfn = ADDR2PFN(frame); |
| 998 | 998 | ||
| Line 1097... | Line 1097... | ||
| 1097 | printf("# Base address\tFree Frames\tBusy Frames\n"); |
1097 | printf("# Base address\tFree Frames\tBusy Frames\n"); |
| 1098 | printf(" ------------\t-----------\t-----------\n"); |
1098 | printf(" ------------\t-----------\t-----------\n"); |
| 1099 | for (i = 0; i < zones.count; i++) { |
1099 | for (i = 0; i < zones.count; i++) { |
| 1100 | zone = zones.info[i]; |
1100 | zone = zones.info[i]; |
| 1101 | spinlock_lock(&zone->lock); |
1101 | spinlock_lock(&zone->lock); |
| 1102 | printf("%d: %.*p \t%10zd\t%10zd\n", i, sizeof(__address) * 2, PFN2ADDR(zone->base), zone->free_count, zone->busy_count); |
1102 | printf("%d: %.*p \t%10zd\t%10zd\n", i, sizeof(uintptr_t) * 2, PFN2ADDR(zone->base), zone->free_count, zone->busy_count); |
| 1103 | spinlock_unlock(&zone->lock); |
1103 | spinlock_unlock(&zone->lock); |
| 1104 | } |
1104 | } |
| 1105 | spinlock_unlock(&zones.lock); |
1105 | spinlock_unlock(&zones.lock); |
| 1106 | interrupts_restore(ipl); |
1106 | interrupts_restore(ipl); |
| 1107 | } |
1107 | } |
| Line 1129... | Line 1129... | ||
| 1129 | goto out; |
1129 | goto out; |
| 1130 | } |
1130 | } |
| 1131 | 1131 | ||
| 1132 | spinlock_lock(&zone->lock); |
1132 | spinlock_lock(&zone->lock); |
| 1133 | printf("Memory zone information\n"); |
1133 | printf("Memory zone information\n"); |
| 1134 | printf("Zone base address: %#.*p\n", sizeof(__address) * 2, PFN2ADDR(zone->base)); |
1134 | printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2, PFN2ADDR(zone->base)); |
| 1135 | printf("Zone size: %zd frames (%zdK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10); |
1135 | printf("Zone size: %zd frames (%zdK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10); |
| 1136 | printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10); |
1136 | printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10); |
| 1137 | printf("Available space: %zd (%zdK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10); |
1137 | printf("Available space: %zd (%zdK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10); |
| 1138 | buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
1138 | buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
| 1139 | 1139 | ||