linux 内核(特别是 2.6 以后)有递归函数吗?

gja*_*ain 4 linux kernel kernel-panic linux-kernel

鉴于内核堆栈的固定大小有限,我的猜测是,虽然理论上我们可能有一个递归函数,如果它的递归不会太深,实用主义会建议一起取消递归函数,以便更安全。毕竟,太多的递归会导致擦除 *thread_info_t* 结构并导致内核恐慌

use*_*own 10

是的!

也许一些递归调用要么被记录在案,要么是函数名称的一部分?然后, find/grep 应该显示它们。这是执行此操作的命令:

find /usr/src/linux/ -name "*.c" -exec grep recursive {} ";" -ls 
Run Code Online (Sandbox Code Playgroud)

管道这个通过| wc -l 给了我 270,也就是说,因为 -ls 每个文件多打印一行,至少 135 个文件+函数。

我们先来看看第一场比赛:

/usr/src/linux/fs/jfs/jfs_dmap.c
Run Code Online (Sandbox Code Playgroud)

比赛是一个评论:

  • 如果 dmap 控制页面的调整本身导致其
  • root 更改,此更改将冒泡到下一个 dmap
  • 通过递归调用此例程来控制级别,指定
  • 新的根值和下一个 dmap 控制页面级别
  • 进行调整。

在方法前面

static int
dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
Run Code Online (Sandbox Code Playgroud)

事实上,第 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.
             */
Run Code Online (Sandbox Code Playgroud)

由于问题是,是否有任何递归函数,我们不必访问接下来的 135 个或更多匹配项或搜索未明确提及的递归。答案是

是的!


Gil*_*il' 7

Linux内核编码风格并不禁止递归函数。

您确实需要小心,不要让堆栈溢出,但这种谨慎并非特定于递归函数。当循环执行时不要无故使用递归,并记住您和调用您的函数总共只能获得 8kB,但有时递归是正确的工具。