@@ -41,13 +41,15 @@ static frames_array_t early_frames;
4141static list_head_t free_frames [MAX_PAGE_ORDER + 1 ];
4242static list_head_t busy_frames [MAX_PAGE_ORDER + 1 ];
4343
44- /* 1 frame for array frame, 3 for mapping it, times to for paging/pmm collisions */
44+ /* 1 frame for array frame, 3 for mapping it, times two for paging/pmm collisions */
4545#define MIN_NUM_4K_FRAMES 2 * (1 + 3)
4646static size_t frames_count [MAX_PAGE_ORDER + 1 ];
4747
4848static bool refilling ;
4949static spinlock_t lock = SPINLOCK_INIT ;
5050
51+ static void try_create_4k_frames (void );
52+
5153static void spin_lock_norefill () {
5254 spin_lock (& lock );
5355
@@ -110,7 +112,7 @@ static inline void init_frames_array(frames_array_t *array) {
110112 total_free_frames += array -> meta .free_count ;
111113}
112114
113- static frames_array_t * _new_frames_array (bool paging_lock ) {
115+ static frames_array_t * _new_frames_array (bool from_paging ) {
114116 frames_array_t * array ;
115117 frame_t * frame ;
116118
@@ -122,11 +124,13 @@ static frames_array_t *_new_frames_array(bool paging_lock) {
122124 array = (frames_array_t * ) mfn_to_virt_kern (frame -> mfn );
123125 else {
124126 /* switch to special refilling mode to avoid deadlock with paging */
127+ ASSERT (!refilling );
125128 refilling = true;
126129 /* only paging will be allowed to take the lock while refilling */
127130 spin_unlock (& lock );
128- array = vmap_frame_refill (mfn_to_virt_map (frame -> mfn ), frame -> mfn , paging_lock );
131+ array = vmap_frame_refill (mfn_to_virt_map (frame -> mfn ), frame -> mfn , from_paging );
129132 spin_lock (& lock );
133+ ASSERT (refilling );
130134 refilling = false;
131135 if (!array )
132136 goto error ;
@@ -136,6 +140,9 @@ static frames_array_t *_new_frames_array(bool paging_lock) {
136140
137141 init_frames_array (array );
138142
143+ /* since paging will back off from refilling we are responsible to do it here */
144+ try_create_4k_frames ();
145+
139146 return array ;
140147error :
141148 panic ("PMM: Unable to allocate new page for frame array" );
@@ -449,7 +456,7 @@ static frame_t *_find_mfn_frame(list_head_t *list, mfn_t mfn, unsigned int order
449456frame_t * find_free_mfn_frame (mfn_t mfn , unsigned int order ) {
450457 frame_t * frame ;
451458
452- spin_lock_norefill ( );
459+ spin_lock ( & lock );
453460 frame = _find_mfn_frame (free_frames , mfn , order );
454461 spin_unlock (& lock );
455462
@@ -459,7 +466,7 @@ frame_t *find_free_mfn_frame(mfn_t mfn, unsigned int order) {
459466frame_t * find_busy_mfn_frame (mfn_t mfn , unsigned int order ) {
460467 frame_t * frame ;
461468
462- spin_lock_norefill ( );
469+ spin_lock ( & lock );
463470 frame = _find_mfn_frame (busy_frames , mfn , order );
464471 spin_unlock (& lock );
465472
@@ -469,7 +476,7 @@ frame_t *find_busy_mfn_frame(mfn_t mfn, unsigned int order) {
469476frame_t * find_mfn_frame (mfn_t mfn , unsigned int order ) {
470477 frame_t * frame ;
471478
472- spin_lock_norefill ( );
479+ spin_lock ( & lock );
473480 frame = _find_mfn_frame (busy_frames , mfn , order );
474481 if (!frame )
475482 frame = _find_mfn_frame (free_frames , mfn , order );
@@ -494,7 +501,7 @@ static frame_t *_find_paddr_frame(list_head_t *list, paddr_t paddr) {
494501frame_t * find_free_paddr_frame (paddr_t paddr ) {
495502 frame_t * frame ;
496503
497- spin_lock_norefill ( );
504+ spin_lock ( & lock );
498505 frame = _find_paddr_frame (free_frames , paddr );
499506 spin_unlock (& lock );
500507
@@ -504,7 +511,7 @@ frame_t *find_free_paddr_frame(paddr_t paddr) {
504511frame_t * find_busy_paddr_frame (paddr_t paddr ) {
505512 frame_t * frame ;
506513
507- spin_lock_norefill ( );
514+ spin_lock ( & lock );
508515 frame = _find_paddr_frame (busy_frames , paddr );
509516 spin_unlock (& lock );
510517
@@ -514,7 +521,7 @@ frame_t *find_busy_paddr_frame(paddr_t paddr) {
514521frame_t * find_paddr_frame (paddr_t paddr ) {
515522 frame_t * frame ;
516523
517- spin_lock_norefill ( );
524+ spin_lock ( & lock );
518525 frame = _find_paddr_frame (busy_frames , paddr );
519526 if (!frame )
520527 frame = _find_paddr_frame (free_frames , paddr );
@@ -687,7 +694,7 @@ void put_free_frames(mfn_t mfn, unsigned int order) {
687694
688695 ASSERT (order <= MAX_PAGE_ORDER );
689696
690- spin_lock_norefill ( );
697+ spin_lock ( & lock );
691698 frame = _find_mfn_frame (busy_frames , mfn , order );
692699 if (!frame ) {
693700 warning ("PMM: unable to find frame: %lx, order: %u among busy frames" , mfn ,
@@ -729,7 +736,6 @@ void map_frames_array(void) {
729736
730737void refill_from_paging (void ) {
731738
732- printk ("%s: start\n" , __func__ );
733739 spin_lock (& lock );
734740
735741 /* if a refill is already active then they are responsible */
0 commit comments