考虑到内核堆栈的固定大小有限,我的猜测是,虽然理论上我们可能有一个递归函数,如果它的递归不是太深,但实用主义建议一起废除递归函数,以确保安全。毕竟,太多的递归可能会导致擦除 *thread_info_t* 结构并导致内核恐慌
答案1
是的!
也许一些递归调用要么被记录下来,要么是函数名称的一部分?然后,find/grep 应该会显示它们。这是执行此操作的命令:
find /usr/src/linux/ -name "*.c" -exec grep recursive {} ";" -ls
通过管道 | wc -l 给了我 270,也就是说,因为 -ls 为每个文件额外打印一行,所以至少有 135 个文件+函数。
我们先来看看第一场比赛:
/usr/src/linux/fs/jfs/jfs_dmap.c
比赛是这样的评论:
- 如果dmap控制页面本身的调整导致其
- root 进行更改,此更改将冒泡到下一个 dmap
- 通过递归调用此例程来控制级别,指定
- 新的根值和下一个 dmap 控制页面级别
- 予以调整。
在方法前面
static int
dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
事实上,第 2486 行及其邻居是:
if (dcp->stree[ROOT] != oldroot) {
/* are we below the top level of the map. if so,
* bubble the root up to the next higher level.
*/
if (level < bmp->db_maxlevel) {
/* bubble up the new root of this dmap control page to
* the next level.
*/
if ((rc =
dbAdjCtl(bmp, blkno, dcp->stree[ROOT], alloc,
level + 1))) {
/* something went wrong in bubbling up the new
* root value, so backout the changes to the
* current dmap control page.
*/
因为问题是,任何递归函数,我们不必访问接下来的 135 个或更多匹配项或搜索未明确提及的递归。答案是
是的!
答案2
这Linux内核编码风格不禁止递归函数。
您确实需要小心,不要溢出堆栈,但这种谨慎并不特定于递归函数。当可以使用循环时,不要无缘无故地使用递归,并记住你以及调用你的函数总共只有 8kB,但有时递归是正确的工具。
答案3
当前内核有超过 1000 万行代码。我确信所有这些代码行中的某些地方都是递归的。递归编程非常强大,您无需运行很多级别即可获得回报。