rcore-os / rCore-Tutorial-v3

Let's write an OS which can run on RISC-V in Rust from scratch!
https://rcore-os.github.io/rCore-Tutorial-Book-v3/index.html
GNU General Public License v3.0
1.58k stars 452 forks source link

ch8 主线程彻底退出之前正在使用的内核栈就被回收 #144

Closed wyfcyx closed 6 months ago

wyfcyx commented 6 months ago

感谢@dalekdalekdalek 参考:

作者您好, 在阅读代码后有一点不清楚的地方, 希望向您请教: 在 exit_current_and_run_next 函数中主线程调用 process_inner.tasks.clear() 时也会 Drop 掉该 task 的 KernelSack, 随即在 KERNEL_SPACE.pagetable 中 unmap 掉主线程的内核栈. 那么之后的代码 drop(process); let mut _unused = TaskContext::zero_init(); schedule(&mut unused as *mut ); 对内核栈使用为什么不会出现 Page Fault 呢? 或者是现在主线程的内核栈并没有被回收调? 十分感谢!

Reply:

这确实是个bug,加了一些打印之后可以发现,task.clear会导致当前正在使用的内核栈被unmap,后面的操作都属于UB了。可以手动加一条sfence.vma指令强制同步,就会卡死在这里了。

dalekdalekdalek commented 6 months ago

作者您好, 我们是否可以在 ProcessControlBlockInner 中添加一个当前使用的内核栈的引用 Arc, 免得它在 clear 时被回收, 最后于 sys_waitpid 中让其父进程回收这个内核栈? 就如您在退出非主线程中提出的让主线程帮助释放内核栈的思想类似 :)

wyfcyx commented 6 months ago

嗯,可以这样改一下。

wyfcyx commented 6 months ago

弄了一种更简单的方法,tasks.clear的时候绕过主线程就行了,反正也就剩内核栈没回收。