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 |