Rev 3191 | Rev 4346 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3191 | Rev 3211 | ||
---|---|---|---|
Line 198... | Line 198... | ||
198 | interrupts_restore(ipl); |
198 | interrupts_restore(ipl); |
199 | 199 | ||
200 | return i; |
200 | return i; |
201 | } |
201 | } |
202 | 202 | ||
203 | /** |
- | |
204 | * Try to find a zone where can we find the frame. |
203 | /** Try to find a zone where can we find the frame. |
205 | * |
204 | * |
206 | * Assume interrupts are disabled. |
205 | * Assume interrupts are disabled. |
207 | * |
206 | * |
208 | * @param frame Frame number contained in zone. |
207 | * @param frame Frame number contained in zone. |
209 | * @param pzone If not null, it is used as zone hint. Zone index is |
208 | * @param pzone If not null, it is used as zone hint. Zone index is |
Line 235... | Line 234... | ||
235 | spinlock_unlock(&z->lock); |
234 | spinlock_unlock(&z->lock); |
236 | 235 | ||
237 | i++; |
236 | i++; |
238 | if (i >= zones.count) |
237 | if (i >= zones.count) |
239 | i = 0; |
238 | i = 0; |
240 | } while(i != hint); |
239 | } while (i != hint); |
241 | 240 | ||
242 | spinlock_unlock(&zones.lock); |
241 | spinlock_unlock(&zones.lock); |
243 | return NULL; |
242 | return NULL; |
244 | } |
243 | } |
245 | 244 | ||
Line 252... | Line 251... | ||
252 | /** Find and lock zone that can allocate order frames. |
251 | /** Find and lock zone that can allocate order frames. |
253 | * |
252 | * |
254 | * Assume interrupts are disabled. |
253 | * Assume interrupts are disabled. |
255 | * |
254 | * |
256 | * @param order Size (2^order) of free space we are trying to find. |
255 | * @param order Size (2^order) of free space we are trying to find. |
- | 256 | * @param flags Required flags of the target zone. |
|
257 | * @param pzone Pointer to preferred zone or NULL, on return contains |
257 | * @param pzone Pointer to preferred zone or NULL, on return contains |
258 | * zone number. |
258 | * zone number. |
259 | */ |
259 | */ |
- | 260 | static zone_t * |
|
260 | static zone_t *find_free_zone_and_lock(uint8_t order, unsigned int *pzone) |
261 | find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone) |
261 | { |
262 | { |
262 | unsigned int i; |
263 | unsigned int i; |
263 | zone_t *z; |
264 | zone_t *z; |
264 | unsigned int hint = pzone ? *pzone : 0; |
265 | unsigned int hint = pzone ? *pzone : 0; |
265 | 266 | ||
- | 267 | /* Mask off flags that are not applicable. */ |
|
- | 268 | flags &= FRAME_LOW_4_GiB; |
|
- | 269 | ||
266 | spinlock_lock(&zones.lock); |
270 | spinlock_lock(&zones.lock); |
267 | if (hint >= zones.count) |
271 | if (hint >= zones.count) |
268 | hint = 0; |
272 | hint = 0; |
269 | i = hint; |
273 | i = hint; |
270 | do { |
274 | do { |
271 | z = zones.info[i]; |
275 | z = zones.info[i]; |
272 | 276 | ||
273 | spinlock_lock(&z->lock); |
277 | spinlock_lock(&z->lock); |
274 | 278 | ||
- | 279 | /* |
|
- | 280 | * Check whether the zone meets the search criteria. |
|
- | 281 | */ |
|
- | 282 | if ((z->flags & flags) == flags) { |
|
- | 283 | /* |
|
275 | /* Check if the zone has 2^order frames area available */ |
284 | * Check if the zone has 2^order frames area available. |
- | 285 | */ |
|
276 | if (zone_can_alloc(z, order)) { |
286 | if (zone_can_alloc(z, order)) { |
277 | spinlock_unlock(&zones.lock); |
287 | spinlock_unlock(&zones.lock); |
278 | if (pzone) |
288 | if (pzone) |
279 | *pzone = i; |
289 | *pzone = i; |
280 | return z; |
290 | return z; |
- | 291 | } |
|
281 | } |
292 | } |
282 | spinlock_unlock(&z->lock); |
293 | spinlock_unlock(&z->lock); |
283 | if (++i >= zones.count) |
294 | if (++i >= zones.count) |
284 | i = 0; |
295 | i = 0; |
285 | } while(i != hint); |
296 | } while (i != hint); |
286 | spinlock_unlock(&zones.lock); |
297 | spinlock_unlock(&zones.lock); |
287 | return NULL; |
298 | return NULL; |
288 | } |
299 | } |
289 | 300 | ||
290 | /**************************/ |
301 | /**************************/ |
Line 316... | Line 327... | ||
316 | } |
327 | } |
317 | } while(index-- > 0); |
328 | } while(index-- > 0); |
318 | return NULL; |
329 | return NULL; |
319 | } |
330 | } |
320 | 331 | ||
321 | static void zone_buddy_print_id(buddy_system_t *b, link_t *block) |
- | |
322 | { |
- | |
323 | frame_t *frame; |
- | |
324 | zone_t *zone; |
- | |
325 | index_t index; |
- | |
326 | - | ||
327 | frame = list_get_instance(block, frame_t, buddy_link); |
- | |
328 | zone = (zone_t *) b->data; |
- | |
329 | index = frame_index(zone, frame); |
- | |
330 | printf("%" PRIi, index); |
- | |
331 | } |
- | |
332 | - | ||
333 | /** Buddy system find_buddy implementation. |
332 | /** Buddy system find_buddy implementation. |
334 | * |
333 | * |
335 | * @param b Buddy system. |
334 | * @param b Buddy system. |
336 | * @param block Block for which buddy should be found. |
335 | * @param block Block for which buddy should be found. |
337 | * |
336 | * |
Line 467... | Line 466... | ||
467 | .coalesce = zone_buddy_coalesce, |
466 | .coalesce = zone_buddy_coalesce, |
468 | .set_order = zone_buddy_set_order, |
467 | .set_order = zone_buddy_set_order, |
469 | .get_order = zone_buddy_get_order, |
468 | .get_order = zone_buddy_get_order, |
470 | .mark_busy = zone_buddy_mark_busy, |
469 | .mark_busy = zone_buddy_mark_busy, |
471 | .mark_available = zone_buddy_mark_available, |
470 | .mark_available = zone_buddy_mark_available, |
472 | .find_block = zone_buddy_find_block, |
471 | .find_block = zone_buddy_find_block |
473 | .print_id = zone_buddy_print_id |
- | |
474 | }; |
472 | }; |
475 | 473 | ||
476 | /******************/ |
474 | /******************/ |
477 | /* Zone functions */ |
475 | /* Zone functions */ |
478 | /******************/ |
476 | /******************/ |
Line 821... | Line 819... | ||
821 | uint8_t max_order; |
819 | uint8_t max_order; |
822 | 820 | ||
823 | spinlock_initialize(&z->lock, "zone_lock"); |
821 | spinlock_initialize(&z->lock, "zone_lock"); |
824 | z->base = start; |
822 | z->base = start; |
825 | z->count = count; |
823 | z->count = count; |
- | 824 | ||
- | 825 | /* Mask off flags that are calculated automatically. */ |
|
- | 826 | flags &= ~FRAME_LOW_4_GiB; |
|
- | 827 | /* Determine calculated flags. */ |
|
- | 828 | if (z->base + count < (1ULL << (32 - FRAME_WIDTH))) /* 4 GiB */ |
|
- | 829 | flags |= FRAME_LOW_4_GiB; |
|
- | 830 | ||
826 | z->flags = flags; |
831 | z->flags = flags; |
- | 832 | ||
827 | z->free_count = count; |
833 | z->free_count = count; |
828 | z->busy_count = 0; |
834 | z->busy_count = 0; |
829 | 835 | ||
830 | /* |
836 | /* |
831 | * Compute order for buddy system, initialize |
837 | * Compute order for buddy system, initialize |
Line 993... | Line 999... | ||
993 | ipl = interrupts_disable(); |
999 | ipl = interrupts_disable(); |
994 | 1000 | ||
995 | /* |
1001 | /* |
996 | * First, find suitable frame zone. |
1002 | * First, find suitable frame zone. |
997 | */ |
1003 | */ |
998 | zone = find_free_zone_and_lock(order, pzone); |
1004 | zone = find_free_zone_and_lock(order, flags, pzone); |
999 | 1005 | ||
1000 | /* If no memory, reclaim some slab memory, |
1006 | /* If no memory, reclaim some slab memory, |
1001 | if it does not help, reclaim all */ |
1007 | if it does not help, reclaim all */ |
1002 | if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
1008 | if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
1003 | freed = slab_reclaim(0); |
1009 | freed = slab_reclaim(0); |
1004 | if (freed) |
1010 | if (freed) |
1005 | zone = find_free_zone_and_lock(order, pzone); |
1011 | zone = find_free_zone_and_lock(order, flags, pzone); |
1006 | if (!zone) { |
1012 | if (!zone) { |
1007 | freed = slab_reclaim(SLAB_RECLAIM_ALL); |
1013 | freed = slab_reclaim(SLAB_RECLAIM_ALL); |
1008 | if (freed) |
1014 | if (freed) |
1009 | zone = find_free_zone_and_lock(order, pzone); |
1015 | zone = find_free_zone_and_lock(order, flags, |
- | 1016 | pzone); |
|
1010 | } |
1017 | } |
1011 | } |
1018 | } |
1012 | if (!zone) { |
1019 | if (!zone) { |
1013 | /* |
1020 | /* |
1014 | * Sleep until some frames are available again. |
1021 | * Sleep until some frames are available again. |
Line 1212... | Line 1219... | ||
1212 | { |
1219 | { |
1213 | zone_t *zone = NULL; |
1220 | zone_t *zone = NULL; |
1214 | unsigned int i; |
1221 | unsigned int i; |
1215 | ipl_t ipl; |
1222 | ipl_t ipl; |
1216 | 1223 | ||
1217 | ipl = interrupts_disable(); |
- | |
1218 | spinlock_lock(&zones.lock); |
- | |
1219 | - | ||
1220 | #ifdef __32_BITS__ |
1224 | #ifdef __32_BITS__ |
1221 | printf("# base address free frames busy frames\n"); |
1225 | printf("# base address free frames busy frames\n"); |
1222 | printf("-- ------------ ------------ ------------\n"); |
1226 | printf("-- ------------ ------------ ------------\n"); |
1223 | #endif |
1227 | #endif |
1224 | 1228 | ||
1225 | #ifdef __64_BITS__ |
1229 | #ifdef __64_BITS__ |
1226 | printf("# base address free frames busy frames\n"); |
1230 | printf("# base address free frames busy frames\n"); |
1227 | printf("-- -------------------- ------------ ------------\n"); |
1231 | printf("-- -------------------- ------------ ------------\n"); |
1228 | #endif |
1232 | #endif |
1229 | 1233 | ||
- | 1234 | /* |
|
- | 1235 | * Because printing may require allocation of memory, we may not hold |
|
- | 1236 | * the frame allocator locks when printing zone statistics. Therefore, |
|
- | 1237 | * we simply gather the statistics under the protection of the locks and |
|
- | 1238 | * print the statistics when the locks have been released. |
|
- | 1239 | * |
|
- | 1240 | * When someone adds/removes zones while we are printing the statistics, |
|
- | 1241 | * we may end up with inaccurate output (e.g. a zone being skipped from |
|
- | 1242 | * the listing). |
|
- | 1243 | */ |
|
- | 1244 | ||
1230 | for (i = 0; i < zones.count; i++) { |
1245 | for (i = 0; ; i++) { |
- | 1246 | uintptr_t base; |
|
- | 1247 | count_t free_count; |
|
- | 1248 | count_t busy_count; |
|
- | 1249 | ||
- | 1250 | ipl = interrupts_disable(); |
|
- | 1251 | spinlock_lock(&zones.lock); |
|
- | 1252 | ||
- | 1253 | if (i >= zones.count) { |
|
- | 1254 | spinlock_unlock(&zones.lock); |
|
- | 1255 | interrupts_restore(ipl); |
|
- | 1256 | break; |
|
- | 1257 | } |
|
- | 1258 | ||
1231 | zone = zones.info[i]; |
1259 | zone = zones.info[i]; |
1232 | spinlock_lock(&zone->lock); |
1260 | spinlock_lock(&zone->lock); |
1233 | 1261 | ||
- | 1262 | base = PFN2ADDR(zone->base); |
|
- | 1263 | free_count = zone->free_count; |
|
- | 1264 | busy_count = zone->busy_count; |
|
- | 1265 | ||
- | 1266 | spinlock_unlock(&zone->lock); |
|
- | 1267 | ||
- | 1268 | spinlock_unlock(&zones.lock); |
|
- | 1269 | interrupts_restore(ipl); |
|
- | 1270 | ||
1234 | #ifdef __32_BITS__ |
1271 | #ifdef __32_BITS__ |
1235 | printf("%-2u %10p %12" PRIc " %12" PRIc "\n", |
1272 | printf("%-2u %10p %12" PRIc " %12" PRIc "\n", i, base, |
1236 | i, PFN2ADDR(zone->base), zone->free_count, |
- | |
1237 | zone->busy_count); |
1273 | free_count, busy_count); |
1238 | #endif |
1274 | #endif |
1239 | 1275 | ||
1240 | #ifdef __64_BITS__ |
1276 | #ifdef __64_BITS__ |
1241 | printf("%-2u %18p %12" PRIc " %12" PRIc "\n", i, |
1277 | printf("%-2u %18p %12" PRIc " %12" PRIc "\n", i, base, |
1242 | PFN2ADDR(zone->base), zone->free_count, zone->busy_count); |
1278 | free_count, busy_count); |
1243 | #endif |
1279 | #endif |
1244 | 1280 | ||
1245 | spinlock_unlock(&zone->lock); |
- | |
1246 | } |
1281 | } |
1247 | - | ||
1248 | spinlock_unlock(&zones.lock); |
- | |
1249 | interrupts_restore(ipl); |
- | |
1250 | } |
1282 | } |
1251 | 1283 | ||
1252 | /** Prints zone details. |
1284 | /** Prints zone details. |
1253 | * |
1285 | * |
1254 | * @param num Zone base address or zone number. |
1286 | * @param num Zone base address or zone number. |
Line 1256... | Line 1288... | ||
1256 | void zone_print_one(unsigned int num) |
1288 | void zone_print_one(unsigned int num) |
1257 | { |
1289 | { |
1258 | zone_t *zone = NULL; |
1290 | zone_t *zone = NULL; |
1259 | ipl_t ipl; |
1291 | ipl_t ipl; |
1260 | unsigned int i; |
1292 | unsigned int i; |
- | 1293 | uintptr_t base; |
|
- | 1294 | count_t count; |
|
- | 1295 | count_t busy_count; |
|
- | 1296 | count_t free_count; |
|
1261 | 1297 | ||
1262 | ipl = interrupts_disable(); |
1298 | ipl = interrupts_disable(); |
1263 | spinlock_lock(&zones.lock); |
1299 | spinlock_lock(&zones.lock); |
1264 | 1300 | ||
1265 | for (i = 0; i < zones.count; i++) { |
1301 | for (i = 0; i < zones.count; i++) { |
Line 1267... | Line 1303... | ||
1267 | zone = zones.info[i]; |
1303 | zone = zones.info[i]; |
1268 | break; |
1304 | break; |
1269 | } |
1305 | } |
1270 | } |
1306 | } |
1271 | if (!zone) { |
1307 | if (!zone) { |
- | 1308 | spinlock_unlock(&zones.lock); |
|
- | 1309 | interrupts_restore(ipl); |
|
1272 | printf("Zone not found.\n"); |
1310 | printf("Zone not found.\n"); |
1273 | goto out; |
1311 | return; |
1274 | } |
1312 | } |
1275 | 1313 | ||
1276 | spinlock_lock(&zone->lock); |
1314 | spinlock_lock(&zone->lock); |
1277 | printf("Memory zone information\n"); |
- | |
1278 | printf("Zone base address: %p\n", PFN2ADDR(zone->base)); |
1315 | base = PFN2ADDR(zone->base); |
1279 | printf("Zone size: %" PRIc " frames (%" PRIs " KB)\n", zone->count, |
- | |
1280 | SIZE2KB(FRAMES2SIZE(zone->count))); |
1316 | count = zone->count; |
1281 | printf("Allocated space: %" PRIc " frames (%" PRIs " KB)\n", |
- | |
1282 | zone->busy_count, SIZE2KB(FRAMES2SIZE(zone->busy_count))); |
1317 | busy_count = zone->busy_count; |
1283 | printf("Available space: %" PRIc " frames (%" PRIs " KB)\n", |
- | |
1284 | zone->free_count, SIZE2KB(FRAMES2SIZE(zone->free_count))); |
1318 | free_count = zone->free_count; |
1285 | buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
- | |
1286 | spinlock_unlock(&zone->lock); |
1319 | spinlock_unlock(&zone->lock); |
1287 | - | ||
1288 | out: |
- | |
1289 | spinlock_unlock(&zones.lock); |
1320 | spinlock_unlock(&zones.lock); |
1290 | interrupts_restore(ipl); |
1321 | interrupts_restore(ipl); |
- | 1322 | ||
- | 1323 | printf("Zone base address: %p\n", base); |
|
- | 1324 | printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count, |
|
- | 1325 | SIZE2KB(FRAMES2SIZE(count))); |
|
- | 1326 | printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n", |
|
- | 1327 | busy_count, SIZE2KB(FRAMES2SIZE(busy_count))); |
|
- | 1328 | printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n", |
|
- | 1329 | free_count, SIZE2KB(FRAMES2SIZE(free_count))); |
|
1291 | } |
1330 | } |
1292 | 1331 | ||
1293 | /** @} |
1332 | /** @} |
1294 | */ |
1333 | */ |
1295 | 1334 |