200,7 → 200,8 |
return i; |
} |
|
/** Try to find a zone where can we find the frame. |
/** |
* Try to find a zone where can we find the frame. |
* |
* Assume interrupts are disabled. |
* |
236,7 → 237,7 |
i++; |
if (i >= zones.count) |
i = 0; |
} while (i != hint); |
} while(i != hint); |
|
spinlock_unlock(&zones.lock); |
return NULL; |
253,20 → 254,15 |
* Assume interrupts are disabled. |
* |
* @param order Size (2^order) of free space we are trying to find. |
* @param flags Required flags of the target zone. |
* @param pzone Pointer to preferred zone or NULL, on return contains |
* zone number. |
*/ |
static zone_t * |
find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone) |
static zone_t *find_free_zone_and_lock(uint8_t order, unsigned int *pzone) |
{ |
unsigned int i; |
zone_t *z; |
unsigned int hint = pzone ? *pzone : 0; |
|
/* Mask off flags that are not applicable. */ |
flags &= FRAME_LOW_4_GiB; |
|
spinlock_lock(&zones.lock); |
if (hint >= zones.count) |
hint = 0; |
276,24 → 272,17 |
|
spinlock_lock(&z->lock); |
|
/* |
* Check whether the zone meets the search criteria. |
*/ |
if ((z->flags & flags) == flags) { |
/* |
* Check if the zone has 2^order frames area available. |
*/ |
if (zone_can_alloc(z, order)) { |
spinlock_unlock(&zones.lock); |
if (pzone) |
*pzone = i; |
return z; |
} |
/* Check if the zone has 2^order frames area available */ |
if (zone_can_alloc(z, order)) { |
spinlock_unlock(&zones.lock); |
if (pzone) |
*pzone = i; |
return z; |
} |
spinlock_unlock(&z->lock); |
if (++i >= zones.count) |
i = 0; |
} while (i != hint); |
} while(i != hint); |
spinlock_unlock(&zones.lock); |
return NULL; |
} |
329,6 → 318,18 |
return NULL; |
} |
|
static void zone_buddy_print_id(buddy_system_t *b, link_t *block) |
{ |
frame_t *frame; |
zone_t *zone; |
index_t index; |
|
frame = list_get_instance(block, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
index = frame_index(zone, frame); |
printf("%" PRIi, index); |
} |
|
/** Buddy system find_buddy implementation. |
* |
* @param b Buddy system. |
468,7 → 469,8 |
.get_order = zone_buddy_get_order, |
.mark_busy = zone_buddy_mark_busy, |
.mark_available = zone_buddy_mark_available, |
.find_block = zone_buddy_find_block |
.find_block = zone_buddy_find_block, |
.print_id = zone_buddy_print_id |
}; |
|
/******************/ |
821,15 → 823,7 |
spinlock_initialize(&z->lock, "zone_lock"); |
z->base = start; |
z->count = count; |
|
/* Mask off flags that are calculated automatically. */ |
flags &= ~FRAME_LOW_4_GiB; |
/* Determine calculated flags. */ |
if (z->base + count < (1ULL << (32 - FRAME_WIDTH))) /* 4 GiB */ |
flags |= FRAME_LOW_4_GiB; |
|
z->flags = flags; |
|
z->free_count = count; |
z->busy_count = 0; |
|
1001,7 → 995,7 |
/* |
* First, find suitable frame zone. |
*/ |
zone = find_free_zone_and_lock(order, flags, pzone); |
zone = find_free_zone_and_lock(order, pzone); |
|
/* If no memory, reclaim some slab memory, |
if it does not help, reclaim all */ |
1008,12 → 1002,11 |
if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
freed = slab_reclaim(0); |
if (freed) |
zone = find_free_zone_and_lock(order, flags, pzone); |
zone = find_free_zone_and_lock(order, pzone); |
if (!zone) { |
freed = slab_reclaim(SLAB_RECLAIM_ALL); |
if (freed) |
zone = find_free_zone_and_lock(order, flags, |
pzone); |
zone = find_free_zone_and_lock(order, pzone); |
} |
} |
if (!zone) { |
1221,6 → 1214,9 |
unsigned int i; |
ipl_t ipl; |
|
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
|
#ifdef __32_BITS__ |
printf("# base address free frames busy frames\n"); |
printf("-- ------------ ------------ ------------\n"); |
1231,54 → 1227,26 |
printf("-- -------------------- ------------ ------------\n"); |
#endif |
|
/* |
* Because printing may require allocation of memory, we may not hold |
* the frame allocator locks when printing zone statistics. Therefore, |
* we simply gather the statistics under the protection of the locks and |
* print the statistics when the locks have been released. |
* |
* When someone adds/removes zones while we are printing the statistics, |
* we may end up with inaccurate output (e.g. a zone being skipped from |
* the listing). |
*/ |
|
for (i = 0; ; i++) { |
uintptr_t base; |
count_t free_count; |
count_t busy_count; |
|
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
|
if (i >= zones.count) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
break; |
} |
|
for (i = 0; i < zones.count; i++) { |
zone = zones.info[i]; |
spinlock_lock(&zone->lock); |
|
base = PFN2ADDR(zone->base); |
free_count = zone->free_count; |
busy_count = zone->busy_count; |
|
spinlock_unlock(&zone->lock); |
|
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
|
#ifdef __32_BITS__ |
printf("%-2u %10p %12" PRIc " %12" PRIc "\n", i, base, |
free_count, busy_count); |
printf("%-2u %10p %12" PRIc " %12" PRIc "\n", |
i, PFN2ADDR(zone->base), zone->free_count, |
zone->busy_count); |
#endif |
|
#ifdef __64_BITS__ |
printf("%-2u %18p %12" PRIc " %12" PRIc "\n", i, base, |
free_count, busy_count); |
printf("%-2u %18p %12" PRIc " %12" PRIc "\n", i, |
PFN2ADDR(zone->base), zone->free_count, zone->busy_count); |
#endif |
|
spinlock_unlock(&zone->lock); |
} |
|
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
} |
|
/** Prints zone details. |
1290,10 → 1258,6 |
zone_t *zone = NULL; |
ipl_t ipl; |
unsigned int i; |
uintptr_t base; |
count_t count; |
count_t busy_count; |
count_t free_count; |
|
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
1305,28 → 1269,25 |
} |
} |
if (!zone) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
printf("Zone not found.\n"); |
return; |
goto out; |
} |
|
spinlock_lock(&zone->lock); |
base = PFN2ADDR(zone->base); |
count = zone->count; |
busy_count = zone->busy_count; |
free_count = zone->free_count; |
printf("Memory zone information\n"); |
printf("Zone base address: %p\n", PFN2ADDR(zone->base)); |
printf("Zone size: %" PRIc " frames (%" PRIs " KB)\n", zone->count, |
SIZE2KB(FRAMES2SIZE(zone->count))); |
printf("Allocated space: %" PRIc " frames (%" PRIs " KB)\n", |
zone->busy_count, SIZE2KB(FRAMES2SIZE(zone->busy_count))); |
printf("Available space: %" PRIc " frames (%" PRIs " KB)\n", |
zone->free_count, SIZE2KB(FRAMES2SIZE(zone->free_count))); |
buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
spinlock_unlock(&zone->lock); |
|
out: |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
|
printf("Zone base address: %p\n", base); |
printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count, |
SIZE2KB(FRAMES2SIZE(count))); |
printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n", |
busy_count, SIZE2KB(FRAMES2SIZE(busy_count))); |
printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n", |
free_count, SIZE2KB(FRAMES2SIZE(free_count))); |
} |
|
/** @} |