软中断知识
来源:互联网 发布:十堰房产每日成交数据 编辑:程序博客网 时间:2024/06/03 23:39
参考:http://blog.csdn.net/yiyeguzhou100/article/details/49909787
http://blog.csdn.net/adaptiver/article/details/6177646
http://yaoyang.blog.51cto.com/7657153/1261841
在说软中断前,先说一下preempt_count()
thread_info中的成员preempt_count,它是一个32位的字段,分为几个部分,:
0-7位: 抢占计数器, 最大值255
8-15位: 软中断计数器, 最大值255
16-27位: 硬中断计数器, 最大值4096
28位: PREEMPT_ACTIVE标志
因此,在hardirq.h中定义了几个宏:
#define PREEMPT_BITS 8#define SOFTIRQ_BITS 8#define HARDIRQ_BITS 12#define PREEMPT_SHIFT 0#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
因此, 函数调用add_preempt_count(HARDIRQ_OFFSET)是增加其中硬中断的计数.
in_interrupt()–>irq_count()–>(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK | NMI_MASK))
其中SOFTIRQ_MASK是软中断计数器所在位的全部为1的数。掩码就是全为1,如PREEMPT_BITS的掩码为11111111。
如:在中断退出时irq_exit有:
void irq_exit(void){ account_system_vtime(current); trace_hardirq_exit(); sub_preempt_count(IRQ_EXIT_OFFSET); if (!in_interrupt() && local_softirq_pending()) 检验是否在软中断或者硬中断中,和检验是否有软中断挂起需要执行 invoke_softirq(); rcu_irq_exit();#ifdef CONFIG_NO_HZ /* Make sure that timer wheel updates are propagated */ if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched()) tick_nohz_stop_sched_tick(0);#endif preempt_enable_no_resched();}分析__do_softirq函数asmlinkage void __do_softirq(void){ struct softirq_action *h; __u32 pending; int max_restart = MAX_SOFTIRQ_RESTART; int cpu; pending = local_softirq_pending(); 提取出挂起的软中断掩码,先将其保存起来,以免发生中断后不可靠 account_system_vtime(current); __local_bh_disable((unsigned long)__builtin_return_address(0)); 软件抢占计数加1,即屏蔽其他的软中断 lockdep_softirq_enter(); 软中断上下文计数加1 cpu = smp_processor_id();restart: /* Reset the pending bitmask before enabling irqs */ set_softirq_pending(0); 先把软中断任务清空 local_irq_enable(); h = softirq_vec; do { if (pending & 1) { //这是针对每大类,如:TASKLET_SOFTIRQ HI_SOFTIRQ等 int prev_count = preempt_count(); kstat_incr_softirqs_this_cpu(h - softirq_vec); trace_softirq_entry(h, softirq_vec); h->action(h); 将一个个软中断提取出来并执行其操作函数 trace_softirq_exit(h, softirq_vec); if (unlikely(prev_count != preempt_count())) { printk(KERN_ERR "huh, entered softirq %td %s %p" "with preempt_count %08x," " exited with %08x?\n", h - softirq_vec, softirq_to_name[h - softirq_vec], h->action, prev_count, preempt_count()); preempt_count() = prev_count; } rcu_bh_qs(cpu); } h++; pending >>= 1; } while (pending); local_irq_disable(); pending = local_softirq_pending(); if (pending && --max_restart) 最多就只循环十次 goto restart; if (pending) wakeup_softirqd(); 唤醒软中断的守护线程 lockdep_softirq_exit(); 软中断上下文计数减1 account_system_vtime(current); _local_bh_enable();}
阅读全文
0 0
- 软中断知识
- linux中断相关知识
- 中断知识整理
- stm32F429中断优先级相关知识
- 【详解】中断相关的知识
- 软中断,硬中断
- 中断、软中断、信号
- 中断 陷阱 软中断
- 硬中断、软中断
- 硬中断、软中断
- 中断下半部-软中断
- 关于单片机中断方面的知识
- 汇编中断知识之INT 1CH
- 自学计算机中断知识--INT 21
- 由ARM-Linux中断知识的拓展
- 汇编中断知识之INT 1CH
- 数码管与中断系统知识笔记
- 软中断
- Ubuntu16.04系统中配置ParaviewWeb5.3+Apache2
- 求字符串中的“最长重复子串”
- nginx入门级配置案例
- 多线程下双重检查锁的问题及解决方法
- JAVA集合知识点汇总<一> List集合
- 软中断知识
- 5. Longest Palindromic Substring
- python入门(三十八):自定义线程池
- web.xml中load-on-startup的作用(转载)
- codeigniter读取数据库的公共配置并全局缓存的实现方案
- 设计模式之外观模式
- nodejs 关于log4js输出到指定文件中
- JAVA集合知识点汇总<二> Set集合
- NScoder / NScoding (iOS对象序列化与反序列化)