Changes in kernel/generic/src/mm/frame.c [adb252c0:f72906c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/frame.c
radb252c0 rf72906c 60 60 #include <config.h> 61 61 #include <str.h> 62 63 #define BITMAP_BLOCK_SIZE 102464 62 65 63 zones_t zones; … … 236 234 * the bitmap if the last argument is NULL. 237 235 */ 236 238 237 return ((zone->flags & ZONE_AVAILABLE) && 239 238 bitmap_allocate_range(&zone->bitmap, count, zone->base, 240 constraint, NULL)); 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; 241 323 } 242 324 … … 250 332 * @param constraint Indication of bits that cannot be set in the 251 333 * physical frame number of the first allocated frame. 252 * @param hind Preferred zone. 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. 253 338 * 254 339 */ … … 259 344 hint = 0; 260 345 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; 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); 281 357 } 282 358 … … 314 390 size_t index; 315 391 int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base, 316 constraint, &index);392 FRAME_LOWPRIO, constraint, &index); 317 393 318 394 ASSERT(avail); … … 352 428 353 429 if (!--frame->refcount) { 354 bitmap_ free_range(&zone->bitmap, index, 1);430 bitmap_set(&zone->bitmap, index, 0); 355 431 356 432 /* Update zone information. */ … … 410 486 411 487 bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count, 412 BITMAP_BLOCK_SIZE, confdata + 413 (sizeof(frame_t) * zones.info[z1].count)); 488 confdata + (sizeof(frame_t) * zones.info[z1].count)); 414 489 bitmap_clear_range(&zones.info[z1].bitmap, 0, zones.info[z1].count); 415 490 … … 578 653 */ 579 654 580 bitmap_initialize(&zone->bitmap, count, BITMAP_BLOCK_SIZE,581 confdata +(sizeof(frame_t) * count));655 bitmap_initialize(&zone->bitmap, count, confdata + 656 (sizeof(frame_t) * count)); 582 657 bitmap_clear_range(&zone->bitmap, 0, count); 583 658 … … 591 666 frame_initialize(&zone->frames[i]); 592 667 } else { 593 bitmap_initialize(&zone->bitmap, 0, 0,NULL);668 bitmap_initialize(&zone->bitmap, 0, NULL); 594 669 zone->frames = NULL; 595 670 } … … 605 680 size_t zone_conf_size(size_t count) 606 681 { 607 return (count * sizeof(frame_t) + 608 bitmap_size(count, BITMAP_BLOCK_SIZE)); 682 return (count * sizeof(frame_t) + bitmap_size(count)); 609 683 } 610 684 … … 887 961 } 888 962 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 896 963 /** Free frames of physical memory. 897 964 * … … 1141 1208 /* 1142 1209 * Because printing may require allocation of memory, we may not hold 1143 * the frame allocator locks when printing zone statistics. 1210 * the frame allocator locks when printing zone statistics. Therefore, 1144 1211 * we simply gather the statistics under the protection of the locks and 1145 1212 * print the statistics when the locks have been released. … … 1150 1217 */ 1151 1218 1219 size_t free_lowmem = 0; 1220 size_t free_highmem = 0; 1221 size_t free_highprio = 0; 1222 1152 1223 for (size_t i = 0;; i++) { 1153 1224 irq_spinlock_lock(&zones.lock, true); … … 1158 1229 } 1159 1230 1160 uintptr_t base = PFN2ADDR(zones.info[i].base); 1231 pfn_t fbase = zones.info[i].base; 1232 uintptr_t base = PFN2ADDR(fbase); 1161 1233 size_t count = zones.info[i].count; 1162 1234 zone_flags_t flags = zones.info[i].flags; … … 1164 1236 size_t busy_count = zones.info[i].busy_count; 1165 1237 1238 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 examine 1255 * all high priority memory to get accurate 1256 * 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 } else 1264 break; 1265 } 1266 } 1267 } 1268 1166 1269 irq_spinlock_unlock(&zones.lock, true); 1167 1168 bool available = ((flags & ZONE_AVAILABLE) != 0);1169 1270 1170 1271 printf("%-4zu", i); … … 1191 1292 printf("\n"); 1192 1293 } 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); 1193 1314 } 1194 1315 … … 1216 1337 } 1217 1338 1218 uintptr_t base = PFN2ADDR(zones.info[znum].base); 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); 1219 1345 zone_flags_t flags = zones.info[znum].flags; 1220 1346 size_t count = zones.info[znum].count; … … 1222 1348 size_t busy_count = zones.info[znum].busy_count; 1223 1349 1350 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 examine 1367 * all high priority memory to get accurate 1368 * 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 } else 1376 break; 1377 } 1378 } 1379 } 1380 1224 1381 irq_spinlock_unlock(&zones.lock, true); 1225 1226 bool available = ((flags & ZONE_AVAILABLE) != 0);1227 1382 1228 1383 uint64_t size; 1229 1384 const char *size_suffix; 1385 1230 1386 bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false); 1231 1387 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,1388 printf("Zone number: %zu\n", znum); 1389 printf("Zone base address: %p\n", (void *) base); 1390 printf("Zone size: %zu frames (%" PRIu64 " %s)\n", count, 1235 1391 size, size_suffix); 1236 printf("Zone flags: %c%c%c%c%c\n",1392 printf("Zone flags: %c%c%c%c%c\n", 1237 1393 available ? 'A' : '-', 1238 1394 (flags & ZONE_RESERVED) ? 'R' : '-', … … 1244 1400 bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix, 1245 1401 false); 1246 printf("Allocated space: %zu frames (%" PRIu64 " %s)\n",1402 printf("Allocated space: %zu frames (%" PRIu64 " %s)\n", 1247 1403 busy_count, size, size_suffix); 1404 1248 1405 bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix, 1249 1406 false); 1250 printf("Available space: %zu frames (%" PRIu64 " %s)\n",1407 printf("Available space: %zu frames (%" PRIu64 " %s)\n", 1251 1408 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); 1252 1424 } 1253 1425 }
Note:
See TracChangeset
for help on using the changeset viewer.