修复了mmio buddy的bug (#189)

* 修改buddy_query
This commit is contained in:
houmkh 2023-03-09 23:31:25 +08:00 committed by GitHub
parent c1396d2771
commit ef9f9732b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -134,26 +134,51 @@ impl MmioBuddyMemPool {
// 找到最小符合申请范围的内存块 // 找到最小符合申请范围的内存块
// 将大的内存块依次分成小块内存直到能够满足exp大小即将exp+1分成两块exp // 将大的内存块依次分成小块内存直到能够满足exp大小即将exp+1分成两块exp
for e in exp + 1..MMIO_BUDDY_MAX_EXP + 1 { 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; continue;
} }
for e2 in (exp + 1..e + 1).rev() { for e2 in (exp + 1..e + 1).rev() {
match self.pop_block(&mut self.free_regions[exp2index(e2) as usize].lock()) { if e2 == e {
Ok(region) => { match self.pop_block(pop_list) {
if e2 != exp + 1 { Ok(region) => {
// 要将分裂后的内存块插入到更小的链表中 if e2 != exp + 1 {
let low_list_guard: &mut SpinLockGuard<MmioFreeRegionList> = // 要将分裂后的内存块插入到更小的链表中
&mut self.free_regions[exp2index(e2 - 1) as usize].lock(); let low_list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
self.split_block(region, e2, low_list_guard); &mut self.free_regions[exp2index(e2 - 1) as usize].lock();
} else { self.split_block(region, e2, low_list_guard);
// 由于exp对应的链表list_guard已经被锁住了 不能再加锁 } else {
// 所以直接将list_guard传入 // 由于exp对应的链表list_guard已经被锁住了 不能再加锁
self.split_block(region, e2, list_guard); // 所以直接将list_guard传入
self.split_block(region, e2, list_guard);
}
}
Err(err) => {
kdebug!("buddy_pop_region get wrong");
return Err(err);
} }
} }
Err(err) => { } else {
kdebug!("buddy_pop_region get wrong"); match self.pop_block(&mut self.free_regions[exp2index(e2) as usize].lock())
return Err(err); {
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大小的内存块 // 判断是否获得了exp大小的内存块
if list_guard.num_free > 0 { 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合成一块exp+1 // 即将两块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 { for e in MMIO_BUDDY_MIN_EXP..exp {
if e != exp - 1 { if e != exp - 1 {
let high_list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
&mut self.free_regions[exp2index(exp + 1)].lock();
match self.merge_all_exp( match self.merge_all_exp(
e, exp,
&mut self.free_regions[exp2index(e) as usize].lock(), &mut self.free_regions[exp2index(exp) as usize].lock(),
high_list_guard, &mut self.free_regions[exp2index(exp + 1)].lock(),
) { ) {
Ok(_) => continue, Ok(_) => continue,
Err(err) => { Err(err) => {
kdebug!("merge_all_exp get wrong");
return Err(err); return Err(err);
} }
} }
} else { } else {
match self.merge_all_exp( match self.merge_all_exp(
e, exp,
&mut self.free_regions[exp2index(e) as usize].lock(), &mut self.free_regions[exp2index(exp) as usize].lock(),
list_guard, list_guard,
) { ) {
Ok(_) => continue, Ok(_) => continue,
Err(err) => { Err(err) => {
kdebug!("merge_all_exp get wrong");
return Err(err); return Err(err);
} }
} }
@ -196,11 +237,17 @@ impl MmioBuddyMemPool {
//判断是否获得了exp大小的内存块 //判断是否获得了exp大小的内存块
if list_guard.num_free > 0 { 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); return Err(MmioResult::ENOFOUND);
} else { } 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 Ok(i32) 成功返回0
/// ///
/// @return Err(i32) 失败返回错误码 /// @return Err(i32) 失败返回错误码
fn create_mmio( pub fn create_mmio(
&self, &self,
size: u32, size: u32,
vm_flags: vm_flags_t, vm_flags: vm_flags_t,
@ -507,7 +554,7 @@ impl MmioBuddyMemPool {
/// @return Ok(i32) 成功返回0 /// @return Ok(i32) 成功返回0
/// ///
/// @return Err(i32) 失败返回错误码 /// @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 { unsafe {
mm_unmap(&mut initial_mm, vaddr, length, false); mm_unmap(&mut initial_mm, vaddr, length, false);