Changes in kernel/generic/src/mm/frame.c [d1582b50:c626117] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/frame.c
rd1582b50 rc626117 63 63 #include <proc/thread.h> /* THREAD */ 64 64 65 zones_t zones; 65 zones_t zones = { 66 .count = 0, 67 .lock = IRQ_SPINLOCK_INITIALIZER("frame.zones.lock"), 68 }; 66 69 67 70 /* … … 69 72 * available. 70 73 */ 71 static mutex_t mem_avail_mtx;72 static condvar_t mem_avail_cv;74 static IRQ_SPINLOCK_INITIALIZE(mem_avail_lock); 75 static CONDVAR_INITIALIZE(mem_avail_cv); 73 76 static size_t mem_avail_req = 0; /**< Number of frames requested. */ 74 77 static size_t mem_avail_gen = 0; /**< Generation counter. */ … … 370 373 { 371 374 assert(zone->flags & ZONE_AVAILABLE); 375 assert(zone->free_count >= count); 372 376 373 377 /* Allocate frames from zone */ … … 410 414 411 415 frame_t *frame = zone_get_frame(zone, index); 412 413 416 assert(frame->refcount > 0); 414 417 415 418 if (!--frame->refcount) { 419 assert(zone->busy_count > 0); 420 416 421 bitmap_set(&zone->bitmap, index, 0); 417 422 … … 432 437 433 438 frame_t *frame = zone_get_frame(zone, index); 439 assert(frame->refcount <= 1); 440 434 441 if (frame->refcount > 0) 435 442 return; 436 443 444 assert(zone->free_count > 0); 445 437 446 frame->refcount = 1; 438 447 bitmap_set_range(&zone->bitmap, index, 1); … … 440 449 zone->free_count--; 441 450 reserve_force_alloc(1); 451 } 452 453 /** Mark frame in zone available to allocation. */ 454 _NO_TRACE static void zone_mark_available(zone_t *zone, size_t index) 455 { 456 assert(zone->flags & ZONE_AVAILABLE); 457 458 frame_t *frame = zone_get_frame(zone, index); 459 assert(frame->refcount == 1); 460 461 frame->refcount = 0; 462 bitmap_set_range(&zone->bitmap, index, 0); 463 464 zone->free_count++; 442 465 } 443 466 … … 465 488 /* Difference between zone bases */ 466 489 pfn_t base_diff = zones.info[z2].base - zones.info[z1].base; 490 pfn_t gap = base_diff - zones.info[z1].count; 467 491 468 492 zones.info[z1].count = base_diff + zones.info[z2].count; … … 492 516 zones.info[z2].frames[i]; 493 517 } 518 519 /* 520 * Mark the gap between the original zones as unavailable. 521 */ 522 523 for (size_t i = 0; i < gap; i++) { 524 frame_initialize(&zones.info[z1].frames[old_z1->count + i]); 525 zone_mark_unavailable(&zones.info[z1], old_z1->count + i); 526 } 494 527 } 495 528 … … 518 551 519 552 for (size_t i = 0; i < cframes; i++) 520 (void) zone_frame_free(&zones.info[znum],553 zone_mark_available(&zones.info[znum], 521 554 pfn - zones.info[znum].base + i); 522 555 } … … 723 756 724 757 if (overlaps(addr, PFN2ADDR(confcount), 725 KA2PA( config.stack_base), config.stack_size))758 KA2PA(ballocs.base), ballocs.size)) 726 759 continue; 727 760 … … 918 951 #endif 919 952 920 /* 921 * Since the mem_avail_mtx is an active mutex, we need to 922 * disable interrupts to prevent deadlock with TLB shootdown. 923 */ 924 ipl_t ipl = interrupts_disable(); 925 mutex_lock(&mem_avail_mtx); 953 /* Disabled interrupts needed to prevent deadlock with TLB shootdown. */ 954 irq_spinlock_lock(&mem_avail_lock, true); 926 955 927 956 if (mem_avail_req > 0) … … 933 962 934 963 while (gen == mem_avail_gen) 935 condvar_wait(&mem_avail_cv, &mem_avail_mtx); 936 937 mutex_unlock(&mem_avail_mtx); 938 interrupts_restore(ipl); 964 condvar_wait(&mem_avail_cv, &mem_avail_lock); 965 966 irq_spinlock_unlock(&mem_avail_lock, true); 939 967 940 968 #ifdef CONFIG_DEBUG … … 994 1022 irq_spinlock_unlock(&zones.lock, true); 995 1023 996 /* 997 * Signal that some memory has been freed. 998 * Since the mem_avail_mtx is an active mutex, 999 * we need to disable interruptsto prevent deadlock 1000 * with TLB shootdown. 1001 */ 1002 1003 ipl_t ipl = interrupts_disable(); 1004 mutex_lock(&mem_avail_mtx); 1024 /* Signal that some memory has been freed. */ 1025 1026 /* Disabled interrupts needed to prevent deadlock with TLB shootdown. */ 1027 irq_spinlock_lock(&mem_avail_lock, true); 1005 1028 1006 1029 if (mem_avail_req > 0) … … 1012 1035 } 1013 1036 1014 mutex_unlock(&mem_avail_mtx); 1015 interrupts_restore(ipl); 1037 irq_spinlock_unlock(&mem_avail_lock, true); 1016 1038 1017 1039 if (!(flags & FRAME_NO_RESERVE)) … … 1078 1100 void frame_init(void) 1079 1101 { 1080 if (config.cpu_active == 1) {1081 zones.count = 0;1082 irq_spinlock_initialize(&zones.lock, "frame.zones.lock");1083 mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);1084 condvar_initialize(&mem_avail_cv);1085 }1086 1087 1102 /* Tell the architecture to create some memory */ 1088 1103 frame_low_arch_init(); … … 1091 1106 frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), 1092 1107 SIZE2FRAMES(config.kernel_size)); 1093 frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)),1094 SIZE2FRAMES(config.stack_size));1095 1108 1096 1109 for (size_t i = 0; i < init.cnt; i++)
Note:
See TracChangeset
for help on using the changeset viewer.