Changes in kernel/generic/src/mm/frame.c [f72906c:adb252c0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/frame.c
rf72906c radb252c0 60 60 #include <config.h> 61 61 #include <str.h> 62 63 #define BITMAP_BLOCK_SIZE 1024 62 64 63 65 zones_t zones; … … 234 236 * the bitmap if the last argument is NULL. 235 237 */ 236 237 238 return ((zone->flags & ZONE_AVAILABLE) && 238 239 bitmap_allocate_range(&zone->bitmap, count, zone->base, 239 FRAME_LOWPRIO, constraint, NULL)); 240 } 241 242 /** Find a zone that can allocate specified number of frames 243 * 244 * This function searches among all zones. Assume interrupts are 245 * disabled and zones lock is locked. 246 * 247 * @param count Number of free frames we are trying to find. 248 * @param flags Required flags of the zone. 249 * @param constraint Indication of bits that cannot be set in the 250 * physical frame number of the first allocated frame. 251 * @param hint Preferred zone. 252 * 253 * @return Zone that can allocate specified number of frames. 254 * @return -1 if no zone can satisfy the request. 255 * 256 */ 257 NO_TRACE static size_t find_free_zone_all(size_t count, zone_flags_t flags, 258 pfn_t constraint, size_t hint) 259 { 260 for (size_t pos = 0; pos < zones.count; pos++) { 261 size_t i = (pos + hint) % zones.count; 262 263 /* Check whether the zone meets the search criteria. */ 264 if (!ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) 265 continue; 266 267 /* Check if the zone can satisfy the allocation request. */ 268 if (zone_can_alloc(&zones.info[i], count, constraint)) 269 return i; 270 } 271 272 return (size_t) -1; 273 } 274 275 /** Check if frame range priority memory 276 * 277 * @param pfn Starting frame. 278 * @param count Number of frames. 279 * 280 * @return True if the range contains only priority memory. 281 * 282 */ 283 NO_TRACE static bool is_high_priority(pfn_t base, size_t count) 284 { 285 return (base + count <= FRAME_LOWPRIO); 286 } 287 288 /** Find a zone that can allocate specified number of frames 289 * 290 * This function ignores zones that contain only high-priority 291 * memory. Assume interrupts are disabled and zones lock is locked. 292 * 293 * @param count Number of free frames we are trying to find. 294 * @param flags Required flags of the zone. 295 * @param constraint Indication of bits that cannot be set in the 296 * physical frame number of the first allocated frame. 297 * @param hint Preferred zone. 298 * 299 * @return Zone that can allocate specified number of frames. 300 * @return -1 if no low-priority zone can satisfy the request. 301 * 302 */ 303 NO_TRACE static size_t find_free_zone_lowprio(size_t count, zone_flags_t flags, 304 pfn_t constraint, size_t hint) 305 { 306 for (size_t pos = 0; pos < zones.count; pos++) { 307 size_t i = (pos + hint) % zones.count; 308 309 /* Skip zones containing only high-priority memory. */ 310 if (is_high_priority(zones.info[i].base, zones.info[i].count)) 311 continue; 312 313 /* Check whether the zone meets the search criteria. */ 314 if (!ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) 315 continue; 316 317 /* Check if the zone can satisfy the allocation request. */ 318 if (zone_can_alloc(&zones.info[i], count, constraint)) 319 return i; 320 } 321 322 return (size_t) -1; 240 constraint, NULL)); 323 241 } 324 242 … … 332 250 * @param constraint Indication of bits that cannot be set in the 333 251 * physical frame number of the first allocated frame. 334 * @param hint Preferred zone. 335 * 336 * @return Zone that can allocate specified number of frames. 337 * @return -1 if no zone can satisfy the request. 252 * @param hind Preferred zone. 338 253 * 339 254 */ … … 344 259 hint = 0; 345 260 346 /* 347 * Prefer zones with low-priority memory over 348 * zones with high-priority memory. 349 */ 350 351 size_t znum = find_free_zone_lowprio(count, flags, constraint, hint); 352 if (znum != (size_t) -1) 353 return znum; 354 355 /* Take all zones into account */ 356 return find_free_zone_all(count, flags, constraint, hint); 261 size_t i = hint; 262 do { 263 /* 264 * Check whether the zone meets the search criteria. 265 */ 266 if (ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) { 267 /* 268 * Check if the zone can satisfy the allocation request. 269 */ 270 if (zone_can_alloc(&zones.info[i], count, constraint)) 271 return i; 272 } 273 274 i++; 275 if (i >= zones.count) 276 i = 0; 277 278 } while (i != hint); 279 280 return (size_t) -1; 357 281 } 358 282 … … 390 314 size_t index; 391 315 int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base, 392 FRAME_LOWPRIO,constraint, &index);316 constraint, &index); 393 317 394 318 ASSERT(avail); … … 428 352 429 353 if (!--frame->refcount) { 430 bitmap_ set(&zone->bitmap, index, 0);354 bitmap_free_range(&zone->bitmap, index, 1); 431 355 432 356 /* Update zone information. */ … … 486 410 487 411 bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count, 488 confdata + (sizeof(frame_t) * zones.info[z1].count)); 412 BITMAP_BLOCK_SIZE, confdata + 413 (sizeof(frame_t) * zones.info[z1].count)); 489 414 bitmap_clear_range(&zones.info[z1].bitmap, 0, zones.info[z1].count); 490 415 … … 653 578 */ 654 579 655 bitmap_initialize(&zone->bitmap, count, confdata +656 (sizeof(frame_t) * count));580 bitmap_initialize(&zone->bitmap, count, BITMAP_BLOCK_SIZE, 581 confdata + (sizeof(frame_t) * count)); 657 582 bitmap_clear_range(&zone->bitmap, 0, count); 658 583 … … 666 591 frame_initialize(&zone->frames[i]); 667 592 } else { 668 bitmap_initialize(&zone->bitmap, 0, NULL);593 bitmap_initialize(&zone->bitmap, 0, 0, NULL); 669 594 zone->frames = NULL; 670 595 } … … 680 605 size_t zone_conf_size(size_t count) 681 606 { 682 return (count * sizeof(frame_t) + bitmap_size(count)); 607 return (count * sizeof(frame_t) + 608 bitmap_size(count, BITMAP_BLOCK_SIZE)); 683 609 } 684 610 … … 961 887 } 962 888 889 uintptr_t frame_alloc_noreserve(size_t count, frame_flags_t flags, 890 uintptr_t constraint) 891 { 892 return frame_alloc_generic(count, flags | FRAME_NO_RESERVE, constraint, 893 NULL); 894 } 895 963 896 /** Free frames of physical memory. 964 897 * … … 1208 1141 /* 1209 1142 * Because printing may require allocation of memory, we may not hold 1210 * the frame allocator locks when printing zone statistics. Therefore,1143 * the frame allocator locks when printing zone statistics. Therefore, 1211 1144 * we simply gather the statistics under the protection of the locks and 1212 1145 * print the statistics when the locks have been released. … … 1217 1150 */ 1218 1151 1219 size_t free_lowmem = 0;1220 size_t free_highmem = 0;1221 size_t free_highprio = 0;1222 1223 1152 for (size_t i = 0;; i++) { 1224 1153 irq_spinlock_lock(&zones.lock, true); … … 1229 1158 } 1230 1159 1231 pfn_t fbase = zones.info[i].base; 1232 uintptr_t base = PFN2ADDR(fbase); 1160 uintptr_t base = PFN2ADDR(zones.info[i].base); 1233 1161 size_t count = zones.info[i].count; 1234 1162 zone_flags_t flags = zones.info[i].flags; … … 1236 1164 size_t busy_count = zones.info[i].busy_count; 1237 1165 1166 irq_spinlock_unlock(&zones.lock, true); 1167 1238 1168 bool available = ((flags & ZONE_AVAILABLE) != 0); 1239 bool lowmem = ((flags & ZONE_LOWMEM) != 0);1240 bool highmem = ((flags & ZONE_HIGHMEM) != 0);1241 bool highprio = is_high_priority(fbase, count);1242 1243 if (available) {1244 if (lowmem)1245 free_lowmem += free_count;1246 1247 if (highmem)1248 free_highmem += free_count;1249 1250 if (highprio) {1251 free_highprio += free_count;1252 } else {1253 /*1254 * Walk all frames of the zone and examine1255 * all high priority memory to get accurate1256 * statistics.1257 */1258 1259 for (size_t index = 0; index < count; index++) {1260 if (is_high_priority(fbase + index, 0)) {1261 if (!bitmap_get(&zones.info[i].bitmap, index))1262 free_highprio++;1263 } else1264 break;1265 }1266 }1267 }1268 1269 irq_spinlock_unlock(&zones.lock, true);1270 1169 1271 1170 printf("%-4zu", i); … … 1292 1191 printf("\n"); 1293 1192 } 1294 1295 printf("\n");1296 1297 uint64_t size;1298 const char *size_suffix;1299 1300 bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,1301 false);1302 printf("Available low memory: %zu frames (%" PRIu64 " %s)\n",1303 free_lowmem, size, size_suffix);1304 1305 bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,1306 false);1307 printf("Available high memory: %zu frames (%" PRIu64 " %s)\n",1308 free_highmem, size, size_suffix);1309 1310 bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,1311 false);1312 printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",1313 free_highprio, size, size_suffix);1314 1193 } 1315 1194 … … 1337 1216 } 1338 1217 1339 size_t free_lowmem = 0; 1340 size_t free_highmem = 0; 1341 size_t free_highprio = 0; 1342 1343 pfn_t fbase = zones.info[znum].base; 1344 uintptr_t base = PFN2ADDR(fbase); 1218 uintptr_t base = PFN2ADDR(zones.info[znum].base); 1345 1219 zone_flags_t flags = zones.info[znum].flags; 1346 1220 size_t count = zones.info[znum].count; … … 1348 1222 size_t busy_count = zones.info[znum].busy_count; 1349 1223 1224 irq_spinlock_unlock(&zones.lock, true); 1225 1350 1226 bool available = ((flags & ZONE_AVAILABLE) != 0); 1351 bool lowmem = ((flags & ZONE_LOWMEM) != 0);1352 bool highmem = ((flags & ZONE_HIGHMEM) != 0);1353 bool highprio = is_high_priority(fbase, count);1354 1355 if (available) {1356 if (lowmem)1357 free_lowmem = free_count;1358 1359 if (highmem)1360 free_highmem = free_count;1361 1362 if (highprio) {1363 free_highprio = free_count;1364 } else {1365 /*1366 * Walk all frames of the zone and examine1367 * all high priority memory to get accurate1368 * statistics.1369 */1370 1371 for (size_t index = 0; index < count; index++) {1372 if (is_high_priority(fbase + index, 0)) {1373 if (!bitmap_get(&zones.info[znum].bitmap, index))1374 free_highprio++;1375 } else1376 break;1377 }1378 }1379 }1380 1381 irq_spinlock_unlock(&zones.lock, true);1382 1227 1383 1228 uint64_t size; 1384 1229 const char *size_suffix; 1385 1386 1230 bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false); 1387 1231 1388 printf("Zone number: 1389 printf("Zone base address: 1390 printf("Zone size: 1232 printf("Zone number: %zu\n", znum); 1233 printf("Zone base address: %p\n", (void *) base); 1234 printf("Zone size: %zu frames (%" PRIu64 " %s)\n", count, 1391 1235 size, size_suffix); 1392 printf("Zone flags: 1236 printf("Zone flags: %c%c%c%c%c\n", 1393 1237 available ? 'A' : '-', 1394 1238 (flags & ZONE_RESERVED) ? 'R' : '-', … … 1400 1244 bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix, 1401 1245 false); 1402 printf("Allocated space: 1246 printf("Allocated space: %zu frames (%" PRIu64 " %s)\n", 1403 1247 busy_count, size, size_suffix); 1404 1405 1248 bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix, 1406 1249 false); 1407 printf("Available space: 1250 printf("Available space: %zu frames (%" PRIu64 " %s)\n", 1408 1251 free_count, size, size_suffix); 1409 1410 bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,1411 false);1412 printf("Available low memory: %zu frames (%" PRIu64 " %s)\n",1413 free_lowmem, size, size_suffix);1414 1415 bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,1416 false);1417 printf("Available high memory: %zu frames (%" PRIu64 " %s)\n",1418 free_highmem, size, size_suffix);1419 1420 bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,1421 false);1422 printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",1423 free_highprio, size, size_suffix);1424 1252 } 1425 1253 }
Note:
See TracChangeset
for help on using the changeset viewer.