• Linux 内核irq_stack遍历


    环境Centos 4.18.0-80.el8.x86_64

    一、x86架构堆栈类型说明

    https://www.kernel.org/doc/Documentation/x86/kernel-stacks

    int get_stack_info(unsigned long *stack, struct task_struct *task,
    		   struct stack_info *info, unsigned long *visit_mask)
    {
       
    	if (!stack)
    		goto unknown;
    
    	task = task ? : current;
    
    	if (in_task_stack(stack, task, info))
    		goto recursion_check;
    
    	if (task != current)
    		goto unknown;
    
    	if (in_exception_stack(stack, info))
    		goto recursion_check;
    
    	if (in_irq_stack(stack, info))
    		goto recursion_check;
    
    	if (in_entry_stack(stack, info))
    		goto recursion_check;
    
    	goto unknown;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    从上述函数可以看出堆栈类型存在4种,在函数show_trace_log_lvl中有一段说明如下:

    	/*
    	 * Iterate through the stacks, starting with the current stack pointer.
    	 * Each stack has a pointer to the next one.
    	 *
    	 * x86-64 can have several stacks:
    	 * - task stack
    	 * - interrupt stack
    	 * - HW exception stacks (double fault, nmi, debug, mce)
    	 * - entry stack
    	 *
    	 * x86-32 can have up to four stacks:
    	 * - task stack
    	 * - softirq stack
    	 * - hardirq stack
    	 * - entry stack
    	 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    x86架构中一般用寄存器sp来存在栈指针。

    类型 说明
    task_stack 进程栈 stack_trace_save可导出进程栈
    exception_stack 异常栈
    irq_stack 中断栈,大小为IRQ_STACK_SIZE 16KB
    entry_stack 入口栈

    二、Linux 内核函数 dump_stack

    在之前的文章也介绍过这个函数的作用,可以打印函数调用栈。

    lib/dump_stack.c

    /**
     * dump_stack - dump the current task information and its stack trace
     *
     * Architectures can override this implementation by implementing its own.
     */
    #ifdef CONFIG_SMP
    static atomic_t dump_lock = ATOMIC_INIT(-1);
    
    asmlinkage __visible void dump_stack(void)
    {
       
    	unsigned long flags;
    	int was_locked;
    	int old;
    	int cpu;
    
    	/*
    	 * Permit this cpu to perform nested stack dumps while serialising
    	 * against other CPUs
    	 */
    retry:
    	local_irq_save(flags);
    	cpu = smp_processor_id();
    	old = atomic_cmpxchg(&dump_lock, -1, cpu);
    	if (old == -1) {
       
    		was_locked = 0;
    	} else if (old == cpu) {
       
    		was_locked = 1;
    	} else {
       
    		local_irq_restore(flags);
    		cpu_relax();
    		goto retry;
    	}
    
    	__dump_stack();
    
    	if (!was_locked)
    		atomic_set(&dump_lock, -1);
    
    	local_irq_restore(flags);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    |- dump_stack();	// lib/dump_stack.c
    	|- __dump_stack();	// arch/x86/kernel/dumpstack.c
    		|- 
    • 1
    • 2
  • 相关阅读:
    整理MyBatis 2022-8-11
    3个ui自动化测试痛点
    Ubuntu快速搭建内网NTP Server
    SpringBoot框架分层(View层、Controller层、Service层、Mapper层、pojo层)
    java通过minio下载pdf附件
    Kotlin 乘法、我怎么越乘越小?
    Python数据分析与机器学习29-支持向量机(SVM)
    机器学习第五课--广告点击率预测项目以及特征选择的介绍
    python强制停止线程学习
    12_MySQL数据库_CentOS7下C-C++链接MySQL
  • 原文地址:https://blog.csdn.net/qq_42931917/article/details/136386268