linux interrupt, deferrable function
来源:互联网 发布:网络维修基础知识 编辑:程序博客网 时间:2024/05/18 02:42
x86
Take x86 architecture for example:
kernel/include/linux/thread_info.h
kernel/arch/x86/include/asm/thread_info.h
struct thread_info 在CPU体系架构相关的thread_info.h文件中定义,不在公共的linux/thread_info.h中定义,以x86为例:
struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ __u32 flags; /* low level flags */ __u32 status; /* thread synchronous flags */ __u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ mm_segment_t addr_limit; struct restart_block restart_block; void __user *sysenter_return;#ifdef CONFIG_X86_32 unsigned long previous_esp; /* ESP of the previous stack in case of nested (IRQ) stacks */ __u8 supervisor_stack[0];#endif unsigned int sig_on_uaccess_error:1; unsigned int uaccess_err:1; /* uaccess failed */};
int preempt_count; /* 0 => preemptable, <0 => BUG */linux/hardirq.h 中:#define in_interrupt() (irq_count())===>#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK | NMI_MASK))===>both hardirq counter and softirq counter are put into the preemption counter:- bits 0-7 are the preemption count (max preemption depth: 256)- bits 8-15 are the softirq count (max # of softirqs: 256)- bits 16-25 are the hardirq count (max # of nested hardirqs: 1024)- bit 26 is the NMI_MASK- bit 27 is the PREEMPT_ACTIVE flag * PREEMPT_MASK: 0x000000ff * SOFTIRQ_MASK: 0x0000ff00 * HARDIRQ_MASK: 0x03ff0000 * NMI_MASK: 0x04000000#define in_irq() (hardirq_count())#define in_softirq() (softirq_count())#define in_interrupt() (irq_count())#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET)这些宏用来获取 irq,softirq,interrupt的数量。在 kernel/arch/x86/kernel/irq_32.c 中:asmlinkage void do_softirq(void){... if (in_interrupt()) return;...}如果in_interrupt()返回值不为0,则直接返回;
kernel/arch/x86/include/asm/thread_info.h 中定义:/* how to get the current stack pointer from C */register unsigned long current_stack_pointer asm("esp") __used;(1) register关键字C语言中的一个关键字;(2) __used 作用?此处的__used是一个宏,代码中有多处定义,例如一处是:#if GCC_VERSION >= 30300# define __used __attribute__((__used__))#else# define __used __attribute__((__unused__))#endif所以要根据包含的头文件来判断;(3) asm("esp") 是什么语法?此处的 esp 是寄存器的名字,不是汇编指令;esp points to the top of the stack
arm
Take arm architecture for example:
kernel/include/linux/thread_info.h
kernel/arch/arm/include/asm/thread_info.h
struct thread_info { unsigned long flags; /* low level flags */ int preempt_count; /* 0 => preemptable, <0 => bug */ mm_segment_t addr_limit; /* address limit */ struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ __u32 cpu; /* cpu */ __u32 cpu_domain; /* cpu domain */ struct cpu_context_save cpu_context; /* cpu context */ __u32 syscall; /* syscall number */ __u8 used_cp[16]; /* thread used copro */ unsigned long tp_value[2]; /* TLS registers */#ifdef CONFIG_CRUNCH struct crunch_state crunchstate;#endif union fp_state fpstate __attribute__((aligned(8))); union vfp_state vfpstate;#ifdef CONFIG_ARM_THUMBEE unsigned long thumbee_state; /* ThumbEE Handler Base register */#endif struct restart_block restart_block;};
/* * how to get the thread information struct from C */static inline struct thread_info *current_thread_info(void) __attribute_const__;static inline struct thread_info *current_thread_info(void){ register unsigned long sp asm ("sp"); return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));}在 kernel/arch/arm/include/asm/thread_info.h 文件中:#define THREAD_SIZE 8192THREAD_SIZE 8192,二进制10 0000 0000 0000——————————————————————————————————————8192 -1 = 8191,二进制 1 1111 1111 1111——————————————————————————————————————~(THREAD_SIZE - 1),如果是32位,则:1111 1111 1111 1111 1110 0000 0000 0000——————————————————————————————————————sp & ~(THREAD_SIZE - 1) 则是sp中的值(这个地址),低13位全部为0,有个问题,这个堆栈是从低地址到高地址吗?如果不是的话,这个函数的逻辑不成立?
local interrupt disabling
local_irq_disable() : make use of the cli assembly language instruction, disable interrupts on the local CPUlocal_irq_enable() : make use of the sti assembly language instruction, enable themlocal_irq_save()local_irq_restore()eflagscall sequence:local_irq_disable()local_irq_save()...local_irq_restore()local_irq_enable()
disabling and enabling deferrable functions
kernel sometimes needs to disable deferrable functions without disabling interrupts
0 0
- linux interrupt, deferrable function
- attachInterrupt(interrupt, function, mode)
- Linux Interrupt
- linux interrupt
- Linux Interrupt
- 【cypress】interrupt function requires address warning
- Linux interrupt & exception
- linux dts interrupt
- Linux Kernel Interrupt 分析
- Linux中断(interrupt)子系统
- Linux中断(interrupt)子系统
- interrupt
- interrupt
- interrupt()
- interrupt
- interrupt()
- Interrupt
- Interrupt
- Hadoop集群搭建
- JSP如何输出当前时间
- Android Studio如何更改JDK和SDK的路径?
- 学习笔记之智能指针简单理解
- hdu3400 Line belt 【三分搜索】
- linux interrupt, deferrable function
- 第七周项目1:成员函数、友元函数和一般函数的区别
- OpenCV颜色识别
- GitHub:怎样在参与开发时同步你的远程代码仓库
- Struts2知识点总结大全
- iOS多语言功能开发小结
- 制作mac 系统盘
- MongoDB学习 (六):查询
- SpringMVC+ibatis+MySQL+MongoDB构建博客系统(二)