Changes in kernel/generic/src/mm/frame.c [11d41be5:905721b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/frame.c
r11d41be5 r905721b 38 38 * 39 39 * This file contains the physical frame allocator and memory zone management. 40 * The frame allocator is built on top of the two-level bitmap structure. 41 * 40 * The frame allocator is built on top of the buddy allocator. 41 * 42 * @see buddy.c 42 43 */ 43 44 … … 91 92 } 92 93 94 NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame) 95 { 96 return (frame - zone->frames); 97 } 98 93 99 /** Initialize frame structure. 94 100 * … … 98 104 NO_TRACE static void frame_initialize(frame_t *frame) 99 105 { 100 frame->refcount = 0;101 frame-> parent = NULL;106 frame->refcount = 1; 107 frame->buddy_order = 0; 102 108 } 103 109 … … 155 161 156 162 /* Move other zones up */ 157 for (size_t j = zones.count; j > i; j--) 163 size_t j; 164 for (j = zones.count; j > i; j--) { 158 165 zones.info[j] = zones.info[j - 1]; 166 if (zones.info[j].buddy_system != NULL) 167 zones.info[j].buddy_system->data = 168 (void *) &zones.info[j]; 169 } 159 170 160 171 zones.count++; … … 226 237 } 227 238 228 /** @return True if zone can allocate specified number of frames */ 229 NO_TRACE static bool zone_can_alloc(zone_t *zone, size_t count, 230 pfn_t constraint) 231 { 232 /* 233 * The function bitmap_allocate_range() does not modify 234 * the bitmap if the last argument is NULL. 235 */ 236 239 /** @return True if zone can allocate specified order */ 240 NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order) 241 { 237 242 return ((zone->flags & ZONE_AVAILABLE) && 238 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; 323 } 324 325 /** Find a zone that can allocate specified number of frames 243 buddy_system_can_alloc(zone->buddy_system, order)); 244 } 245 246 /** Find a zone that can allocate order frames. 326 247 * 327 248 * Assume interrupts are disabled and zones lock is 328 249 * locked. 329 250 * 330 * @param count Number of free frames we are trying to find. 331 * @param flags Required flags of the target zone. 332 * @param constraint Indication of bits that cannot be set in the 333 * 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. 338 * 339 */ 340 NO_TRACE static size_t find_free_zone(size_t count, zone_flags_t flags, 341 pfn_t constraint, size_t hint) 251 * @param order Size (2^order) of free space we are trying to find. 252 * @param flags Required flags of the target zone. 253 * @param hind Preferred zone. 254 * 255 */ 256 NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags, 257 size_t hint) 342 258 { 343 259 if (hint >= zones.count) 344 260 hint = 0; 345 261 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); 357 } 262 size_t i = hint; 263 do { 264 /* 265 * Check whether the zone meets the search criteria. 266 */ 267 if (ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) { 268 /* 269 * Check if the zone has 2^order frames area available. 270 */ 271 if (zone_can_alloc(&zones.info[i], order)) 272 return i; 273 } 274 275 i++; 276 if (i >= zones.count) 277 i = 0; 278 279 } while (i != hint); 280 281 return (size_t) -1; 282 } 283 284 /**************************/ 285 /* Buddy system functions */ 286 /**************************/ 287 288 /** Buddy system find_block implementation. 289 * 290 * Find block that is parent of current list. 291 * That means go to lower addresses, until such block is found 292 * 293 * @param order Order of parent must be different then this 294 * parameter!! 295 * 296 */ 297 NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy, 298 link_t *child, uint8_t order) 299 { 300 frame_t *frame = list_get_instance(child, frame_t, buddy_link); 301 zone_t *zone = (zone_t *) buddy->data; 302 303 size_t index = frame_index(zone, frame); 304 do { 305 if (zone->frames[index].buddy_order != order) 306 return &zone->frames[index].buddy_link; 307 } while (index-- > 0); 308 309 return NULL; 310 } 311 312 /** Buddy system find_buddy implementation. 313 * 314 * @param buddy Buddy system. 315 * @param block Block for which buddy should be found. 316 * 317 * @return Buddy for given block if found. 318 * 319 */ 320 NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, 321 link_t *block) 322 { 323 frame_t *frame = list_get_instance(block, frame_t, buddy_link); 324 zone_t *zone = (zone_t *) buddy->data; 325 ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), 326 frame->buddy_order)); 327 328 bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); 329 330 size_t index; 331 if (is_left) { 332 index = (frame_index(zone, frame)) + 333 (1 << frame->buddy_order); 334 } else { /* is_right */ 335 index = (frame_index(zone, frame)) - 336 (1 << frame->buddy_order); 337 } 338 339 if (frame_index_valid(zone, index)) { 340 if ((zone->frames[index].buddy_order == frame->buddy_order) && 341 (zone->frames[index].refcount == 0)) { 342 return &zone->frames[index].buddy_link; 343 } 344 } 345 346 return NULL; 347 } 348 349 /** Buddy system bisect implementation. 350 * 351 * @param buddy Buddy system. 352 * @param block Block to bisect. 353 * 354 * @return Right block. 355 * 356 */ 357 NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block) 358 { 359 frame_t *frame_l = list_get_instance(block, frame_t, buddy_link); 360 frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1))); 361 362 return &frame_r->buddy_link; 363 } 364 365 /** Buddy system coalesce implementation. 366 * 367 * @param buddy Buddy system. 368 * @param block_1 First block. 369 * @param block_2 First block's buddy. 370 * 371 * @return Coalesced block (actually block that represents lower 372 * address). 373 * 374 */ 375 NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy, 376 link_t *block_1, link_t *block_2) 377 { 378 frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link); 379 frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link); 380 381 return ((frame1 < frame2) ? block_1 : block_2); 382 } 383 384 /** Buddy system set_order implementation. 385 * 386 * @param buddy Buddy system. 387 * @param block Buddy system block. 388 * @param order Order to set. 389 * 390 */ 391 NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block, 392 uint8_t order) 393 { 394 list_get_instance(block, frame_t, buddy_link)->buddy_order = order; 395 } 396 397 /** Buddy system get_order implementation. 398 * 399 * @param buddy Buddy system. 400 * @param block Buddy system block. 401 * 402 * @return Order of block. 403 * 404 */ 405 NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy, 406 link_t *block) 407 { 408 return list_get_instance(block, frame_t, buddy_link)->buddy_order; 409 } 410 411 /** Buddy system mark_busy implementation. 412 * 413 * @param buddy Buddy system. 414 * @param block Buddy system block. 415 * 416 */ 417 NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block) 418 { 419 list_get_instance(block, frame_t, buddy_link)->refcount = 1; 420 } 421 422 /** Buddy system mark_available implementation. 423 * 424 * @param buddy Buddy system. 425 * @param block Buddy system block. 426 * 427 */ 428 NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy, 429 link_t *block) 430 { 431 list_get_instance(block, frame_t, buddy_link)->refcount = 0; 432 } 433 434 static buddy_system_operations_t zone_buddy_system_operations = { 435 .find_buddy = zone_buddy_find_buddy, 436 .bisect = zone_buddy_bisect, 437 .coalesce = zone_buddy_coalesce, 438 .set_order = zone_buddy_set_order, 439 .get_order = zone_buddy_get_order, 440 .mark_busy = zone_buddy_mark_busy, 441 .mark_available = zone_buddy_mark_available, 442 .find_block = zone_buddy_find_block 443 }; 358 444 359 445 /******************/ … … 361 447 /******************/ 362 448 363 /** Return frame from zone. */364 NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t index)365 {366 ASSERT(index < zone->count);367 368 return &zone->frames[index];369 }370 371 449 /** Allocate frame in particular zone. 372 450 * … … 374 452 * Panics if allocation is impossible. 375 453 * 376 * @param zone Zone to allocate from. 377 * @param count Number of frames to allocate 378 * @param constraint Indication of bits that cannot be set in the 379 * physical frame number of the first allocated frame. 454 * @param zone Zone to allocate from. 455 * @param order Allocate exactly 2^order frames. 380 456 * 381 457 * @return Frame index in zone. 382 458 * 383 459 */ 384 NO_TRACE static size_t zone_frame_alloc(zone_t *zone, size_t count, 385 pfn_t constraint) 460 NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order) 386 461 { 387 462 ASSERT(zone->flags & ZONE_AVAILABLE); 388 463 389 /* Allocate frames from zone */ 390 size_t index; 391 int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base, 392 FRAME_LOWPRIO, constraint, &index); 393 394 ASSERT(avail); 395 396 /* Update frame reference count */ 397 for (size_t i = 0; i < count; i++) { 398 frame_t *frame = zone_get_frame(zone, index + i); 399 400 ASSERT(frame->refcount == 0); 401 frame->refcount = 1; 402 } 464 /* Allocate frames from zone buddy system */ 465 link_t *link = buddy_system_alloc(zone->buddy_system, order); 466 467 ASSERT(link); 403 468 404 469 /* Update zone information. */ 405 zone->free_count -= count; 406 zone->busy_count += count; 407 408 return index; 470 zone->free_count -= (1 << order); 471 zone->busy_count += (1 << order); 472 473 /* Frame will be actually a first frame of the block. */ 474 frame_t *frame = list_get_instance(link, frame_t, buddy_link); 475 476 /* Get frame address */ 477 return make_frame_index(zone, frame); 409 478 } 410 479 … … 413 482 * Assume zone is locked and is available for deallocation. 414 483 * 415 * @param zone Pointer to zone from which the frame is to be freed.416 * @param index Frame index relative to zone.417 * 418 * @return Number of freed frames.419 * 420 */ 421 NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t index)484 * @param zone Pointer to zone from which the frame is to be freed. 485 * @param frame_idx Frame index relative to zone. 486 * 487 * @return Number of freed frames. 488 * 489 */ 490 NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx) 422 491 { 423 492 ASSERT(zone->flags & ZONE_AVAILABLE); 424 493 425 frame_t *frame = zone_get_frame(zone, index); 426 427 ASSERT(frame->refcount > 0); 494 frame_t *frame = &zone->frames[frame_idx]; 495 size_t size = 0; 496 497 ASSERT(frame->refcount); 428 498 429 499 if (!--frame->refcount) { 430 bitmap_set(&zone->bitmap, index, 0);431 500 size = 1 << frame->buddy_order; 501 buddy_system_free(zone->buddy_system, &frame->buddy_link); 432 502 /* Update zone information. */ 433 zone->free_count++; 434 zone->busy_count--; 435 436 return 1; 437 } 438 439 return 0; 503 zone->free_count += size; 504 zone->busy_count -= size; 505 } 506 507 return size; 508 } 509 510 /** Return frame from zone. */ 511 NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx) 512 { 513 ASSERT(frame_idx < zone->count); 514 return &zone->frames[frame_idx]; 440 515 } 441 516 442 517 /** Mark frame in zone unavailable to allocation. */ 443 NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)518 NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx) 444 519 { 445 520 ASSERT(zone->flags & ZONE_AVAILABLE); 446 521 447 frame_t *frame = zone_get_frame(zone, index);448 if (frame->refcount > 0)522 frame_t *frame = zone_get_frame(zone, frame_idx); 523 if (frame->refcount) 449 524 return; 450 525 451 frame->refcount = 1; 452 bitmap_set_range(&zone->bitmap, index, 1); 453 526 link_t *link __attribute__ ((unused)); 527 528 link = buddy_system_alloc_block(zone->buddy_system, 529 &frame->buddy_link); 530 531 ASSERT(link); 454 532 zone->free_count--; 455 533 reserve_force_alloc(1); … … 458 536 /** Merge two zones. 459 537 * 538 * Expect buddy to point to space at least zone_conf_size large. 460 539 * Assume z1 & z2 are locked and compatible and zones lock is 461 540 * locked. 462 541 * 463 * @param z1 464 * @param z2 465 * @param old_z1 Original dataof the first zone.466 * @param confdata Merged zone configuration data.542 * @param z1 First zone to merge. 543 * @param z2 Second zone to merge. 544 * @param old_z1 Original date of the first zone. 545 * @param buddy Merged zone buddy. 467 546 * 468 547 */ 469 548 NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, 470 void *confdata)549 buddy_system_t *buddy) 471 550 { 472 551 ASSERT(zones.info[z1].flags & ZONE_AVAILABLE); … … 483 562 zones.info[z1].free_count += zones.info[z2].free_count; 484 563 zones.info[z1].busy_count += zones.info[z2].busy_count; 485 486 bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count, 487 confdata + (sizeof(frame_t) * zones.info[z1].count)); 488 bitmap_clear_range(&zones.info[z1].bitmap, 0, zones.info[z1].count); 489 490 zones.info[z1].frames = (frame_t *) confdata; 491 492 /* 493 * Copy frames and bits from both zones to preserve parents, etc. 564 zones.info[z1].buddy_system = buddy; 565 566 uint8_t order = fnzb(zones.info[z1].count); 567 buddy_system_create(zones.info[z1].buddy_system, order, 568 &zone_buddy_system_operations, (void *) &zones.info[z1]); 569 570 zones.info[z1].frames = 571 (frame_t *) ((uint8_t *) zones.info[z1].buddy_system 572 + buddy_conf_size(order)); 573 574 /* This marks all frames busy */ 575 size_t i; 576 for (i = 0; i < zones.info[z1].count; i++) 577 frame_initialize(&zones.info[z1].frames[i]); 578 579 /* Copy frames from both zones to preserve full frame orders, 580 * parents etc. Set all free frames with refcount = 0 to 1, because 581 * we add all free frames to buddy allocator later again, clearing 582 * order to 0. Don't set busy frames with refcount = 0, as they 583 * will not be reallocated during merge and it would make later 584 * problems with allocation/free. 494 585 */ 495 496 for (size_t i = 0; i < old_z1->count; i++) { 497 bitmap_set(&zones.info[z1].bitmap, i, 498 bitmap_get(&old_z1->bitmap, i)); 586 for (i = 0; i < old_z1->count; i++) 499 587 zones.info[z1].frames[i] = old_z1->frames[i]; 500 } 501 502 for (size_t i = 0; i < zones.info[z2].count; i++) { 503 bitmap_set(&zones.info[z1].bitmap, base_diff + i, 504 bitmap_get(&zones.info[z2].bitmap, i)); 505 zones.info[z1].frames[base_diff + i] = 506 zones.info[z2].frames[i]; 588 589 for (i = 0; i < zones.info[z2].count; i++) 590 zones.info[z1].frames[base_diff + i] 591 = zones.info[z2].frames[i]; 592 593 i = 0; 594 while (i < zones.info[z1].count) { 595 if (zones.info[z1].frames[i].refcount) { 596 /* Skip busy frames */ 597 i += 1 << zones.info[z1].frames[i].buddy_order; 598 } else { 599 /* Free frames, set refcount = 1 600 * (all free frames have refcount == 0, we need not 601 * to check the order) 602 */ 603 zones.info[z1].frames[i].refcount = 1; 604 zones.info[z1].frames[i].buddy_order = 0; 605 i++; 606 } 607 } 608 609 /* Add free blocks from the original zone z1 */ 610 while (zone_can_alloc(old_z1, 0)) { 611 /* Allocate from the original zone */ 612 pfn_t frame_idx = zone_frame_alloc(old_z1, 0); 613 614 /* Free the frame from the merged zone */ 615 frame_t *frame = &zones.info[z1].frames[frame_idx]; 616 frame->refcount = 0; 617 buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link); 618 } 619 620 /* Add free blocks from the original zone z2 */ 621 while (zone_can_alloc(&zones.info[z2], 0)) { 622 /* Allocate from the original zone */ 623 pfn_t frame_idx = zone_frame_alloc(&zones.info[z2], 0); 624 625 /* Free the frame from the merged zone */ 626 frame_t *frame = &zones.info[z1].frames[base_diff + frame_idx]; 627 frame->refcount = 0; 628 buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link); 507 629 } 508 630 } … … 527 649 size_t cframes = SIZE2FRAMES(zone_conf_size(count)); 528 650 529 if ((pfn < zones.info[znum].base) ||530 (pfn >= zones.info[znum].base + zones.info[znum].count))651 if ((pfn < zones.info[znum].base) 652 || (pfn >= zones.info[znum].base + zones.info[znum].count)) 531 653 return; 532 654 533 for (size_t i = 0; i < cframes; i++) 655 frame_t *frame __attribute__ ((unused)); 656 657 frame = &zones.info[znum].frames[pfn - zones.info[znum].base]; 658 ASSERT(!frame->buddy_order); 659 660 size_t i; 661 for (i = 0; i < cframes; i++) { 662 zones.info[znum].busy_count++; 534 663 (void) zone_frame_free(&zones.info[znum], 535 664 pfn - zones.info[znum].base + i); 665 } 666 } 667 668 /** Reduce allocated block to count of order 0 frames. 669 * 670 * The allocated block needs 2^order frames. Reduce all frames 671 * in the block to order 0 and free the unneeded frames. This means that 672 * when freeing the previously allocated block starting with frame_idx, 673 * you have to free every frame. 674 * 675 * @param znum Zone. 676 * @param frame_idx Index the first frame of the block. 677 * @param count Allocated frames in block. 678 * 679 */ 680 NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx, 681 size_t count) 682 { 683 ASSERT(zones.info[znum].flags & ZONE_AVAILABLE); 684 ASSERT(frame_idx + count < zones.info[znum].count); 685 686 uint8_t order = zones.info[znum].frames[frame_idx].buddy_order; 687 ASSERT((size_t) (1 << order) >= count); 688 689 /* Reduce all blocks to order 0 */ 690 size_t i; 691 for (i = 0; i < (size_t) (1 << order); i++) { 692 frame_t *frame = &zones.info[znum].frames[i + frame_idx]; 693 frame->buddy_order = 0; 694 if (!frame->refcount) 695 frame->refcount = 1; 696 ASSERT(frame->refcount == 1); 697 } 698 699 /* Free unneeded frames */ 700 for (i = count; i < (size_t) (1 << order); i++) 701 (void) zone_frame_free(&zones.info[znum], i + frame_idx); 536 702 } 537 703 … … 553 719 bool ret = true; 554 720 555 /* 556 * We can join only 2 zones with none existing inbetween, 721 /* We can join only 2 zones with none existing inbetween, 557 722 * the zones have to be available and with the same 558 723 * set of flags … … 568 733 + zones.info[z2].count)); 569 734 735 uint8_t order; 736 if (cframes == 1) 737 order = 0; 738 else 739 order = fnzb(cframes - 1) + 1; 740 570 741 /* Allocate merged zone data inside one of the zones */ 571 742 pfn_t pfn; 572 if (zone_can_alloc(&zones.info[z1], cframes, 0)) { 573 pfn = zones.info[z1].base + 574 zone_frame_alloc(&zones.info[z1], cframes, 0); 575 } else if (zone_can_alloc(&zones.info[z2], cframes, 0)) { 576 pfn = zones.info[z2].base + 577 zone_frame_alloc(&zones.info[z2], cframes, 0); 743 if (zone_can_alloc(&zones.info[z1], order)) { 744 pfn = zones.info[z1].base + zone_frame_alloc(&zones.info[z1], order); 745 } else if (zone_can_alloc(&zones.info[z2], order)) { 746 pfn = zones.info[z2].base + zone_frame_alloc(&zones.info[z2], order); 578 747 } else { 579 748 ret = false; … … 583 752 /* Preserve original data from z1 */ 584 753 zone_t old_z1 = zones.info[z1]; 754 old_z1.buddy_system->data = (void *) &old_z1; 585 755 586 756 /* Do zone merging */ 587 zone_merge_internal(z1, z2, &old_z1, (void *) PA2KA(PFN2ADDR(pfn))); 757 buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(pfn)); 758 zone_merge_internal(z1, z2, &old_z1, buddy); 759 760 /* Free unneeded config frames */ 761 zone_reduce_region(z1, pfn - zones.info[z1].base, cframes); 588 762 589 763 /* Subtract zone information from busy frames */ … … 598 772 599 773 /* Move zones down */ 600 for (size_t i = z2 + 1; i < zones.count; i++) 774 size_t i; 775 for (i = z2 + 1; i < zones.count; i++) { 601 776 zones.info[i - 1] = zones.info[i]; 777 if (zones.info[i - 1].buddy_system != NULL) 778 zones.info[i - 1].buddy_system->data = 779 (void *) &zones.info[i - 1]; 780 } 602 781 603 782 zones.count--; … … 618 797 void zone_merge_all(void) 619 798 { 620 size_t i = 1; 621 799 size_t i = 0; 622 800 while (i < zones.count) { 623 if (!zone_merge(i - 1, i))801 if (!zone_merge(i, i + 1)) 624 802 i++; 625 803 } … … 628 806 /** Create new frame zone. 629 807 * 630 * @param zone 631 * @param start Physical address of the first frame within the zone.632 * @param count Count of frames inzone.633 * @param flags Zone flags.634 * @param confdata Configuration data of the zone.808 * @param zone Zone to construct. 809 * @param buddy Address of buddy system configuration information. 810 * @param start Physical address of the first frame within the zone. 811 * @param count Count of frames in zone. 812 * @param flags Zone flags. 635 813 * 636 814 * @return Initialized zone. 637 815 * 638 816 */ 639 NO_TRACE static void zone_construct(zone_t *zone, pfn_t start, size_t count,640 zone_flags_t flags, void *confdata)817 NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy, 818 pfn_t start, size_t count, zone_flags_t flags) 641 819 { 642 820 zone->base = start; … … 645 823 zone->free_count = count; 646 824 zone->busy_count = 0; 825 zone->buddy_system = buddy; 647 826 648 827 if (flags & ZONE_AVAILABLE) { 649 828 /* 650 * Initialize frame bitmap (located after the array of 651 * frame_t structures in the configuration space). 829 * Compute order for buddy system and initialize 652 830 */ 653 654 b itmap_initialize(&zone->bitmap, count, confdata +655 (sizeof(frame_t) * count));656 bitmap_clear_range(&zone->bitmap, 0, count);657 658 /*659 * Initialize the array of frame_t structures.660 */661 662 zone->frames = (frame_t *) confdata;663 664 for ( size_ti = 0; i < count; i++)831 uint8_t order = fnzb(count); 832 buddy_system_create(zone->buddy_system, order, 833 &zone_buddy_system_operations, (void *) zone); 834 835 /* Allocate frames _after_ the confframe */ 836 837 /* Check sizes */ 838 zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system + 839 buddy_conf_size(order)); 840 841 size_t i; 842 for (i = 0; i < count; i++) 665 843 frame_initialize(&zone->frames[i]); 666 } else { 667 bitmap_initialize(&zone->bitmap, 0, NULL); 844 845 /* Stuffing frames */ 846 for (i = 0; i < count; i++) { 847 zone->frames[i].refcount = 0; 848 buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link); 849 } 850 } else 668 851 zone->frames = NULL; 669 }670 852 } 671 853 … … 679 861 size_t zone_conf_size(size_t count) 680 862 { 681 return (count * sizeof(frame_t) + b itmap_size(count));863 return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count))); 682 864 } 683 865 … … 685 867 pfn_t zone_external_conf_alloc(size_t count) 686 868 { 687 size_t frames = SIZE2FRAMES(zone_conf_size(count)); 688 689 return ADDR2PFN((uintptr_t) 690 frame_alloc(frames, FRAME_LOWMEM | FRAME_ATOMIC, 0)); 869 size_t size = zone_conf_size(count); 870 size_t order = ispwr2(size) ? fnzb(size) : (fnzb(size) + 1); 871 872 return ADDR2PFN((uintptr_t) frame_alloc(order - FRAME_WIDTH, 873 FRAME_LOWMEM | FRAME_ATOMIC)); 691 874 } 692 875 … … 696 879 * @param count Size of zone in frames. 697 880 * @param confframe Where configuration frames are supposed to be. 698 * Automatically checks that we will not disturb the881 * Automatically checks, that we will not disturb the 699 882 * kernel and possibly init. If confframe is given 700 883 * _outside_ this zone, it is expected, that the area is … … 713 896 714 897 if (flags & ZONE_AVAILABLE) { /* Create available zone */ 715 /* 716 * Theoretically we could have NULL here, practically make sure 898 /* Theoretically we could have NULL here, practically make sure 717 899 * nobody tries to do that. If some platform requires, remove 718 900 * the assert 719 901 */ 720 902 ASSERT(confframe != ADDR2PFN((uintptr_t ) NULL)); 721 903 722 904 /* Update the known end of physical memory. */ 723 905 config.physmem_end = max(config.physmem_end, PFN2ADDR(start + count)); 724 906 725 /* 726 * If confframe is supposed to be inside our zone, then make sure 907 /* If confframe is supposed to be inside our zone, then make sure 727 908 * it does not span kernel & init 728 909 */ 729 910 size_t confcount = SIZE2FRAMES(zone_conf_size(count)); 730 731 911 if ((confframe >= start) && (confframe < start + count)) { 732 912 for (; confframe < start + count; confframe++) { … … 741 921 742 922 bool overlap = false; 743 for (size_t i = 0; i < init.cnt; i++) { 923 size_t i; 924 for (i = 0; i < init.cnt; i++) 744 925 if (overlaps(addr, PFN2ADDR(confcount), 745 926 init.tasks[i].paddr, … … 748 929 break; 749 930 } 750 }751 752 931 if (overlap) 753 932 continue; … … 766 945 } 767 946 768 void *confdata = (void*) PA2KA(PFN2ADDR(confframe));769 zone_construct(&zones.info[znum], start, count, flags, confdata);947 buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe)); 948 zone_construct(&zones.info[znum], buddy, start, count, flags); 770 949 771 950 /* If confdata in zone, mark as unavailable */ 772 951 if ((confframe >= start) && (confframe < start + count)) { 773 for (size_t i = confframe; i < confframe + confcount; i++) 952 size_t i; 953 for (i = confframe; i < confframe + confcount; i++) 774 954 zone_mark_unavailable(&zones.info[znum], 775 955 i - zones.info[znum].base); … … 787 967 return (size_t) -1; 788 968 } 789 790 zone_construct(&zones.info[znum], start, count, flags, NULL); 969 zone_construct(&zones.info[znum], NULL, start, count, flags); 791 970 792 971 irq_spinlock_unlock(&zones.lock, true); … … 830 1009 } 831 1010 832 /** Allocate frames of physical memory. 833 * 834 * @param count Number of continuous frames to allocate. 835 * @param flags Flags for host zone selection and address processing. 836 * @param constraint Indication of physical address bits that cannot be 837 * set in the address of the first allocated frame. 838 * @param pzone Preferred zone. 1011 /** Allocate power-of-two frames of physical memory. 1012 * 1013 * @param order Allocate exactly 2^order frames. 1014 * @param flags Flags for host zone selection and address processing. 1015 * @param pzone Preferred zone. 839 1016 * 840 1017 * @return Physical address of the allocated frame. 841 1018 * 842 1019 */ 843 uintptr_t frame_alloc_generic(size_t count, frame_flags_t flags, 844 uintptr_t constraint, size_t *pzone) 845 { 846 ASSERT(count > 0); 847 1020 void *frame_alloc_generic(uint8_t order, frame_flags_t flags, size_t *pzone) 1021 { 1022 size_t size = ((size_t) 1) << order; 848 1023 size_t hint = pzone ? (*pzone) : 0; 849 pfn_t frame_constraint = ADDR2PFN(constraint);850 1024 851 1025 /* 852 1026 * If not told otherwise, we must first reserve the memory. 853 1027 */ 854 if (!(flags & FRAME_NO_RESERVE)) 855 reserve_force_alloc( count);856 1028 if (!(flags & FRAME_NO_RESERVE)) 1029 reserve_force_alloc(size); 1030 857 1031 loop: 858 1032 irq_spinlock_lock(&zones.lock, true); … … 861 1035 * First, find suitable frame zone. 862 1036 */ 863 size_t znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags), 864 frame_constraint, hint); 865 866 /* 867 * If no memory, reclaim some slab memory, 868 * if it does not help, reclaim all. 869 */ 1037 size_t znum = find_free_zone(order, 1038 FRAME_TO_ZONE_FLAGS(flags), hint); 1039 1040 /* If no memory, reclaim some slab memory, 1041 if it does not help, reclaim all */ 870 1042 if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { 871 1043 irq_spinlock_unlock(&zones.lock, true); … … 874 1046 875 1047 if (freed > 0) 876 znum = find_free_zone( count, FRAME_TO_ZONE_FLAGS(flags),877 frame_constraint, hint);1048 znum = find_free_zone(order, 1049 FRAME_TO_ZONE_FLAGS(flags), hint); 878 1050 879 1051 if (znum == (size_t) -1) { … … 883 1055 884 1056 if (freed > 0) 885 znum = find_free_zone( count, FRAME_TO_ZONE_FLAGS(flags),886 frame_constraint, hint);1057 znum = find_free_zone(order, 1058 FRAME_TO_ZONE_FLAGS(flags), hint); 887 1059 } 888 1060 } … … 891 1063 if (flags & FRAME_ATOMIC) { 892 1064 irq_spinlock_unlock(&zones.lock, true); 893 894 1065 if (!(flags & FRAME_NO_RESERVE)) 895 reserve_free(count); 896 897 return 0; 1066 reserve_free(size); 1067 return NULL; 898 1068 } 899 1069 … … 905 1075 906 1076 if (!THREAD) 907 panic("Cannot wait for %zu frames to become available " 908 "(%zu available).", count, avail); 1077 panic("Cannot wait for memory to become available."); 909 1078 910 1079 /* … … 913 1082 914 1083 #ifdef CONFIG_DEBUG 915 printf("Thread %" PRIu64 " waiting for %zu frames "916 " (%zu available).\n", THREAD->tid, count, avail);1084 printf("Thread %" PRIu64 " waiting for %zu frames, " 1085 "%zu available.\n", THREAD->tid, size, avail); 917 1086 #endif 918 1087 919 1088 /* 920 * Since the mem_avail_mtx is an active mutex, we need to 921 * disable interruptsto prevent deadlock with TLB shootdown.1089 * Since the mem_avail_mtx is an active mutex, we need to disable interrupts 1090 * to prevent deadlock with TLB shootdown. 922 1091 */ 923 1092 ipl_t ipl = interrupts_disable(); … … 925 1094 926 1095 if (mem_avail_req > 0) 927 mem_avail_req = min(mem_avail_req, count);1096 mem_avail_req = min(mem_avail_req, size); 928 1097 else 929 mem_avail_req = count; 930 1098 mem_avail_req = size; 931 1099 size_t gen = mem_avail_gen; 932 1100 … … 944 1112 } 945 1113 946 pfn_t pfn = zone_frame_alloc(&zones.info[znum], count,947 frame_constraint)+ zones.info[znum].base;1114 pfn_t pfn = zone_frame_alloc(&zones.info[znum], order) 1115 + zones.info[znum].base; 948 1116 949 1117 irq_spinlock_unlock(&zones.lock, true); … … 952 1120 *pzone = znum; 953 1121 954 return PFN2ADDR(pfn); 955 } 956 957 uintptr_t frame_alloc(size_t count, frame_flags_t flags, uintptr_t constraint) 958 { 959 return frame_alloc_generic(count, flags, constraint, NULL); 960 } 961 962 /** Free frames of physical memory. 963 * 964 * Find respective frame structures for supplied physical frames. 965 * Decrement each frame reference count. If it drops to zero, mark 966 * the frames as available. 967 * 968 * @param start Physical Address of the first frame to be freed. 969 * @param count Number of frames to free. 1122 if (flags & FRAME_KA) 1123 return (void *) PA2KA(PFN2ADDR(pfn)); 1124 1125 return (void *) PFN2ADDR(pfn); 1126 } 1127 1128 void *frame_alloc(uint8_t order, frame_flags_t flags) 1129 { 1130 return frame_alloc_generic(order, flags, NULL); 1131 } 1132 1133 void *frame_alloc_noreserve(uint8_t order, frame_flags_t flags) 1134 { 1135 return frame_alloc_generic(order, flags | FRAME_NO_RESERVE, NULL); 1136 } 1137 1138 /** Free a frame. 1139 * 1140 * Find respective frame structure for supplied physical frame address. 1141 * Decrement frame reference count. If it drops to zero, move the frame 1142 * structure to free list. 1143 * 1144 * @param frame Physical Address of of the frame to be freed. 970 1145 * @param flags Flags to control memory reservation. 971 1146 * 972 1147 */ 973 void frame_free_generic(uintptr_t start, size_t count, frame_flags_t flags)974 { 975 size_t freed = 0;1148 void frame_free_generic(uintptr_t frame, frame_flags_t flags) 1149 { 1150 size_t size; 976 1151 977 1152 irq_spinlock_lock(&zones.lock, true); 978 1153 979 for (size_t i = 0; i < count; i++) { 980 /* 981 * First, find host frame zone for addr. 982 */ 983 pfn_t pfn = ADDR2PFN(start) + i; 984 size_t znum = find_zone(pfn, 1, 0); 985 986 ASSERT(znum != (size_t) -1); 987 988 freed += zone_frame_free(&zones.info[znum], 989 pfn - zones.info[znum].base); 990 } 1154 /* 1155 * First, find host frame zone for addr. 1156 */ 1157 pfn_t pfn = ADDR2PFN(frame); 1158 size_t znum = find_zone(pfn, 1, 0); 1159 1160 ASSERT(znum != (size_t) -1); 1161 1162 size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); 991 1163 992 1164 irq_spinlock_unlock(&zones.lock, true); … … 994 1166 /* 995 1167 * Signal that some memory has been freed. 996 * Since the mem_avail_mtx is an active mutex,997 * we need to disable interruptsto prevent deadlock998 * with TLB shootdown.999 1168 */ 1000 1169 1170 1171 /* 1172 * Since the mem_avail_mtx is an active mutex, we need to disable interrupts 1173 * to prevent deadlock with TLB shootdown. 1174 */ 1001 1175 ipl_t ipl = interrupts_disable(); 1002 1176 mutex_lock(&mem_avail_mtx); 1003 1004 1177 if (mem_avail_req > 0) 1005 mem_avail_req -= min(mem_avail_req, freed);1178 mem_avail_req -= min(mem_avail_req, size); 1006 1179 1007 1180 if (mem_avail_req == 0) { … … 1009 1182 condvar_broadcast(&mem_avail_cv); 1010 1183 } 1011 1012 1184 mutex_unlock(&mem_avail_mtx); 1013 1185 interrupts_restore(ipl); 1014 1186 1015 1187 if (!(flags & FRAME_NO_RESERVE)) 1016 reserve_free( freed);1017 } 1018 1019 void frame_free(uintptr_t frame , size_t count)1020 { 1021 frame_free_generic(frame, count,0);1022 } 1023 1024 void frame_free_noreserve(uintptr_t frame , size_t count)1025 { 1026 frame_free_generic(frame, count,FRAME_NO_RESERVE);1188 reserve_free(size); 1189 } 1190 1191 void frame_free(uintptr_t frame) 1192 { 1193 frame_free_generic(frame, 0); 1194 } 1195 1196 void frame_free_noreserve(uintptr_t frame) 1197 { 1198 frame_free_generic(frame, FRAME_NO_RESERVE); 1027 1199 } 1028 1200 … … 1058 1230 irq_spinlock_lock(&zones.lock, true); 1059 1231 1060 for (size_t i = 0; i < count; i++) { 1232 size_t i; 1233 for (i = 0; i < count; i++) { 1061 1234 size_t znum = find_zone(start + i, 1, 0); 1062 1063 1235 if (znum == (size_t) -1) /* PFN not found */ 1064 1236 continue; … … 1085 1257 /* Tell the architecture to create some memory */ 1086 1258 frame_low_arch_init(); 1087 1088 1259 if (config.cpu_active == 1) { 1089 1260 frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), … … 1092 1263 SIZE2FRAMES(config.stack_size)); 1093 1264 1094 for (size_t i = 0; i < init.cnt; i++) 1095 frame_mark_unavailable(ADDR2PFN(init.tasks[i].paddr), 1265 size_t i; 1266 for (i = 0; i < init.cnt; i++) { 1267 pfn_t pfn = ADDR2PFN(init.tasks[i].paddr); 1268 frame_mark_unavailable(pfn, 1096 1269 SIZE2FRAMES(init.tasks[i].size)); 1270 } 1097 1271 1098 1272 if (ballocs.size) … … 1100 1274 SIZE2FRAMES(ballocs.size)); 1101 1275 1102 /* 1103 * Blacklist first frame, as allocating NULL would 1276 /* Black list first frame, as allocating NULL would 1104 1277 * fail in some places 1105 1278 */ 1106 1279 frame_mark_unavailable(0, 1); 1107 1280 } 1108 1109 1281 frame_high_arch_init(); 1110 1282 } … … 1112 1284 /** Adjust bounds of physical memory region according to low/high memory split. 1113 1285 * 1114 * @param low[in] If true, the adjustment is performed to make the region 1115 * fit in the low memory. Otherwise the adjustment is 1116 * performed to make the region fit in the high memory. 1117 * @param basep[inout] Pointer to a variable which contains the region's base 1118 * address and which may receive the adjusted base address. 1119 * @param sizep[inout] Pointer to a variable which contains the region's size 1120 * and which may receive the adjusted size. 1121 * 1122 * @return True if the region still exists even after the adjustment. 1123 * @return False otherwise. 1124 * 1286 * @param low[in] If true, the adjustment is performed to make the region 1287 * fit in the low memory. Otherwise the adjustment is 1288 * performed to make the region fit in the high memory. 1289 * @param basep[inout] Pointer to a variable which contains the region's base 1290 * address and which may receive the adjusted base address. 1291 * @param sizep[inout] Pointer to a variable which contains the region's size 1292 * and which may receive the adjusted size. 1293 * @retun True if the region still exists even after the 1294 * adjustment, false otherwise. 1125 1295 */ 1126 1296 bool frame_adjust_zone_bounds(bool low, uintptr_t *basep, size_t *sizep) 1127 1297 { 1128 1298 uintptr_t limit = KA2PA(config.identity_base) + config.identity_size; 1129 1299 1130 1300 if (low) { 1131 1301 if (*basep > limit) 1132 1302 return false; 1133 1134 1303 if (*basep + *sizep > limit) 1135 1304 *sizep = limit - *basep; … … 1137 1306 if (*basep + *sizep <= limit) 1138 1307 return false; 1139 1140 1308 if (*basep <= limit) { 1141 1309 *sizep -= limit - *basep; … … 1143 1311 } 1144 1312 } 1145 1146 1313 return true; 1147 1314 } … … 1155 1322 1156 1323 uint64_t total = 0; 1157 1158 for ( size_ti = 0; i < zones.count; i++)1324 size_t i; 1325 for (i = 0; i < zones.count; i++) 1159 1326 total += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1160 1327 … … 1179 1346 *free = 0; 1180 1347 1181 for (size_t i = 0; i < zones.count; i++) { 1348 size_t i; 1349 for (i = 0; i < zones.count; i++) { 1182 1350 *total += (uint64_t) FRAMES2SIZE(zones.info[i].count); 1183 1351 … … 1207 1375 /* 1208 1376 * Because printing may require allocation of memory, we may not hold 1209 * the frame allocator locks when printing zone statistics. Therefore,1377 * the frame allocator locks when printing zone statistics. Therefore, 1210 1378 * we simply gather the statistics under the protection of the locks and 1211 1379 * print the statistics when the locks have been released. … … 1216 1384 */ 1217 1385 1218 size_t free_lowmem = 0; 1219 size_t free_highmem = 0; 1220 size_t free_highprio = 0; 1221 1222 for (size_t i = 0;; i++) { 1386 size_t i; 1387 for (i = 0;; i++) { 1223 1388 irq_spinlock_lock(&zones.lock, true); 1224 1389 … … 1228 1393 } 1229 1394 1230 pfn_t fbase = zones.info[i].base; 1231 uintptr_t base = PFN2ADDR(fbase); 1395 uintptr_t base = PFN2ADDR(zones.info[i].base); 1232 1396 size_t count = zones.info[i].count; 1233 1397 zone_flags_t flags = zones.info[i].flags; … … 1235 1399 size_t busy_count = zones.info[i].busy_count; 1236 1400 1401 irq_spinlock_unlock(&zones.lock, true); 1402 1237 1403 bool available = ((flags & ZONE_AVAILABLE) != 0); 1238 bool lowmem = ((flags & ZONE_LOWMEM) != 0);1239 bool highmem = ((flags & ZONE_HIGHMEM) != 0);1240 bool highprio = is_high_priority(fbase, count);1241 1242 if (available) {1243 if (lowmem)1244 free_lowmem += free_count;1245 1246 if (highmem)1247 free_highmem += free_count;1248 1249 if (highprio) {1250 free_highprio += free_count;1251 } else {1252 /*1253 * Walk all frames of the zone and examine1254 * all high priority memory to get accurate1255 * statistics.1256 */1257 1258 for (size_t index = 0; index < count; index++) {1259 if (is_high_priority(fbase + index, 0)) {1260 if (!bitmap_get(&zones.info[i].bitmap, index))1261 free_highprio++;1262 } else1263 break;1264 }1265 }1266 }1267 1268 irq_spinlock_unlock(&zones.lock, true);1269 1404 1270 1405 printf("%-4zu", i); … … 1291 1426 printf("\n"); 1292 1427 } 1293 1294 printf("\n");1295 1296 uint64_t size;1297 const char *size_suffix;1298 1299 bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,1300 false);1301 printf("Available low memory: %zu frames (%" PRIu64 " %s)\n",1302 free_lowmem, size, size_suffix);1303 1304 bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,1305 false);1306 printf("Available high memory: %zu frames (%" PRIu64 " %s)\n",1307 free_highmem, size, size_suffix);1308 1309 bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,1310 false);1311 printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",1312 free_highprio, size, size_suffix);1313 1428 } 1314 1429 … … 1323 1438 size_t znum = (size_t) -1; 1324 1439 1325 for (size_t i = 0; i < zones.count; i++) { 1440 size_t i; 1441 for (i = 0; i < zones.count; i++) { 1326 1442 if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) { 1327 1443 znum = i; … … 1336 1452 } 1337 1453 1338 size_t free_lowmem = 0; 1339 size_t free_highmem = 0; 1340 size_t free_highprio = 0; 1341 1342 pfn_t fbase = zones.info[znum].base; 1343 uintptr_t base = PFN2ADDR(fbase); 1344 zone_flags_t flags = zones.info[znum].flags; 1345 size_t count = zones.info[znum].count; 1346 size_t free_count = zones.info[znum].free_count; 1347 size_t busy_count = zones.info[znum].busy_count; 1454 uintptr_t base = PFN2ADDR(zones.info[i].base); 1455 zone_flags_t flags = zones.info[i].flags; 1456 size_t count = zones.info[i].count; 1457 size_t free_count = zones.info[i].free_count; 1458 size_t busy_count = zones.info[i].busy_count; 1459 1460 irq_spinlock_unlock(&zones.lock, true); 1348 1461 1349 1462 bool available = ((flags & ZONE_AVAILABLE) != 0); 1350 bool lowmem = ((flags & ZONE_LOWMEM) != 0);1351 bool highmem = ((flags & ZONE_HIGHMEM) != 0);1352 bool highprio = is_high_priority(fbase, count);1353 1354 if (available) {1355 if (lowmem)1356 free_lowmem = free_count;1357 1358 if (highmem)1359 free_highmem = free_count;1360 1361 if (highprio) {1362 free_highprio = free_count;1363 } else {1364 /*1365 * Walk all frames of the zone and examine1366 * all high priority memory to get accurate1367 * statistics.1368 */1369 1370 for (size_t index = 0; index < count; index++) {1371 if (is_high_priority(fbase + index, 0)) {1372 if (!bitmap_get(&zones.info[znum].bitmap, index))1373 free_highprio++;1374 } else1375 break;1376 }1377 }1378 }1379 1380 irq_spinlock_unlock(&zones.lock, true);1381 1463 1382 1464 uint64_t size; 1383 1465 const char *size_suffix; 1384 1385 1466 bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false); 1386 1467 1387 printf("Zone number: 1388 printf("Zone base address: 1389 printf("Zone size: 1468 printf("Zone number: %zu\n", znum); 1469 printf("Zone base address: %p\n", (void *) base); 1470 printf("Zone size: %zu frames (%" PRIu64 " %s)\n", count, 1390 1471 size, size_suffix); 1391 printf("Zone flags: 1472 printf("Zone flags: %c%c%c%c%c\n", 1392 1473 available ? 'A' : '-', 1393 1474 (flags & ZONE_RESERVED) ? 'R' : '-', … … 1399 1480 bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix, 1400 1481 false); 1401 printf("Allocated space: 1482 printf("Allocated space: %zu frames (%" PRIu64 " %s)\n", 1402 1483 busy_count, size, size_suffix); 1403 1404 1484 bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix, 1405 1485 false); 1406 printf("Available space: 1486 printf("Available space: %zu frames (%" PRIu64 " %s)\n", 1407 1487 free_count, size, size_suffix); 1408 1409 bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,1410 false);1411 printf("Available low memory: %zu frames (%" PRIu64 " %s)\n",1412 free_lowmem, size, size_suffix);1413 1414 bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,1415 false);1416 printf("Available high memory: %zu frames (%" PRIu64 " %s)\n",1417 free_highmem, size, size_suffix);1418 1419 bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,1420 false);1421 printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",1422 free_highprio, size, size_suffix);1423 1488 } 1424 1489 }
Note:
See TracChangeset
for help on using the changeset viewer.