浏览代码

修复了mmio buddy的bug (#189)

* 修改buddy_query
houmkh 2 年之前
父节点
当前提交
ef9f9732b0
共有 1 个文件被更改,包括 74 次插入27 次删除
  1. 74 27
      kernel/src/mm/mmio_buddy.rs

+ 74 - 27
kernel/src/mm/mmio_buddy.rs

@@ -134,26 +134,51 @@ impl MmioBuddyMemPool {
             // 找到最小符合申请范围的内存块
             // 将大的内存块依次分成小块内存,直到能够满足exp大小,即将exp+1分成两块exp
             for e in exp + 1..MMIO_BUDDY_MAX_EXP + 1 {
-                if self.free_regions[exp2index(e) as usize].lock().num_free == 0 {
+                let pop_list: &mut SpinLockGuard<MmioFreeRegionList> =
+                    &mut self.free_regions[exp2index(e) as usize].lock();
+                if pop_list.num_free == 0 {
                     continue;
                 }
+
                 for e2 in (exp + 1..e + 1).rev() {
-                    match self.pop_block(&mut self.free_regions[exp2index(e2) as usize].lock()) {
-                        Ok(region) => {
-                            if e2 != exp + 1 {
-                                // 要将分裂后的内存块插入到更小的链表中
-                                let low_list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
-                                    &mut self.free_regions[exp2index(e2 - 1) as usize].lock();
-                                self.split_block(region, e2, low_list_guard);
-                            } else {
-                                // 由于exp对应的链表list_guard已经被锁住了 不能再加锁
-                                // 所以直接将list_guard传入
-                                self.split_block(region, e2, list_guard);
+                    if e2 == e {
+                        match self.pop_block(pop_list) {
+                            Ok(region) => {
+                                if e2 != exp + 1 {
+                                    // 要将分裂后的内存块插入到更小的链表中
+                                    let low_list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
+                                        &mut self.free_regions[exp2index(e2 - 1) as usize].lock();
+                                    self.split_block(region, e2, low_list_guard);
+                                } else {
+                                    // 由于exp对应的链表list_guard已经被锁住了 不能再加锁
+                                    // 所以直接将list_guard传入
+                                    self.split_block(region, e2, list_guard);
+                                }
+                            }
+                            Err(err) => {
+                                kdebug!("buddy_pop_region get wrong");
+                                return Err(err);
                             }
                         }
-                        Err(err) => {
-                            kdebug!("buddy_pop_region get wrong");
-                            return Err(err);
+                    } else {
+                        match self.pop_block(&mut self.free_regions[exp2index(e2) as usize].lock())
+                        {
+                            Ok(region) => {
+                                if e2 != exp + 1 {
+                                    // 要将分裂后的内存块插入到更小的链表中
+                                    let low_list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
+                                        &mut self.free_regions[exp2index(e2 - 1) as usize].lock();
+                                    self.split_block(region, e2, low_list_guard);
+                                } else {
+                                    // 由于exp对应的链表list_guard已经被锁住了 不能再加锁
+                                    // 所以直接将list_guard传入
+                                    self.split_block(region, e2, list_guard);
+                                }
+                            }
+                            Err(err) => {
+                                kdebug!("buddy_pop_region get wrong");
+                                return Err(err);
+                            }
                         }
                     }
                 }
@@ -161,33 +186,49 @@ impl MmioBuddyMemPool {
             }
             // 判断是否获得了exp大小的内存块
             if list_guard.num_free > 0 {
-                return Ok(list_guard.list.pop_back().unwrap());
+                match self.pop_block(list_guard) {
+                    Ok(ret) => return Ok(ret),
+                    Err(err) => return Err(err),
+                }
             }
             // 拆分大内存块无法获得exp大小内存块
             // 尝试用小内存块合成
             // 即将两块exp合成一块exp+1
+
+            // TODO:修改下一个循环的冗余代码,请不要删除此处的注释
+            // let merge = |high_list_guard: &mut SpinLockGuard<MmioFreeRegionList>, exp: u32| {
+            //     if let Err(err) = self.merge_all_exp(
+            //         exp,
+            //         &mut self.free_regions[exp2index(exp) as usize].lock(),
+            //         high_list_guard,
+            //     ) {
+            //         return err;
+            //     } else {
+            //         return MmioResult::SUCCESS;
+            //     }
+            // };
             for e in MMIO_BUDDY_MIN_EXP..exp {
                 if e != exp - 1 {
-                    let high_list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
-                        &mut self.free_regions[exp2index(exp + 1)].lock();
                     match self.merge_all_exp(
-                        e,
-                        &mut self.free_regions[exp2index(e) as usize].lock(),
-                        high_list_guard,
+                        exp,
+                        &mut self.free_regions[exp2index(exp) as usize].lock(),
+                        &mut self.free_regions[exp2index(exp + 1)].lock(),
                     ) {
                         Ok(_) => continue,
                         Err(err) => {
+                            kdebug!("merge_all_exp get wrong");
                             return Err(err);
                         }
                     }
                 } else {
                     match self.merge_all_exp(
-                        e,
-                        &mut self.free_regions[exp2index(e) as usize].lock(),
+                        exp,
+                        &mut self.free_regions[exp2index(exp) as usize].lock(),
                         list_guard,
                     ) {
                         Ok(_) => continue,
                         Err(err) => {
+                            kdebug!("merge_all_exp get wrong");
                             return Err(err);
                         }
                     }
@@ -196,11 +237,17 @@ impl MmioBuddyMemPool {
 
             //判断是否获得了exp大小的内存块
             if list_guard.num_free > 0 {
-                return Ok(list_guard.list.pop_back().unwrap());
+                match self.pop_block(list_guard) {
+                    Ok(ret) => return Ok(ret),
+                    Err(err) => return Err(err),
+                }
             }
             return Err(MmioResult::ENOFOUND);
         } else {
-            return Ok(list_guard.list.pop_back().unwrap());
+            match self.pop_block(list_guard) {
+                Ok(ret) => return Ok(ret),
+                Err(err) => return Err(err),
+            }
         }
     }
 
@@ -394,7 +441,7 @@ impl MmioBuddyMemPool {
     /// @return Ok(i32) 成功返回0
     ///
     /// @return Err(i32) 失败返回错误码
-    fn create_mmio(
+    pub fn create_mmio(
         &self,
         size: u32,
         vm_flags: vm_flags_t,
@@ -507,7 +554,7 @@ impl MmioBuddyMemPool {
     /// @return Ok(i32) 成功返回0
     ///
     /// @return Err(i32) 失败返回错误码
-    fn release_mmio(&self, vaddr: u64, length: u64) -> Result<i32, i32> {
+    pub fn release_mmio(&self, vaddr: u64, length: u64) -> Result<i32, i32> {
         //先将要释放的空间取消映射
         unsafe {
             mm_unmap(&mut initial_mm, vaddr, length, false);