linux中断下半部实现机制之软中断
2013-08-05 15:07
507 查看
软中断保留给系统中对时间要求最严格以及最重要的下半部使用。目前,只有两个子系统---网络和SCSI直接使用软中断。此外,内核定时器和taskelet都是建立在软中断上的。对于时间要求严格并能自己高效完成加锁工作的应用,软中断会是正确的选择。
怎样使用软中断呢?
1.分配索引
在编译期间,可以通过<linux/interrupt.h>中定义的一个枚举类型来静态声明软中断。索引号小的软中断在索引号大的软中断之前执行。要添加新项的话根据赋予它的优先级来决定加入的位置而不是直接添加到列表末尾。
/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
frequency threaded job scheduling. For almost all the purposes
tasklets are more than enough. F.e. all serial device BHs et
al. should be converted to tasklets, not to softirqs.
*/
enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
#ifdef CONFIG_HIGH_RES_TIMERS
HRTIMER_SOFTIRQ,
#endif
};
2. 注册你的处理程序
在运行时 通过调用open_softirq()注册软件处理程序,该函数有三个参数:软中断的索引号、处理函数和data域存放的数值:
void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
{
softirq_vec[nr].data = data;
softirq_vec[nr].action = action;
}
3.触发你的软中断
通过在枚举类型的列表中添加新项,调用open_softirq()进行注册之后,新的软中断处理程序就能够运行。raise_softirq()函数可以将一个软中断设置为挂起状态,让它在下次调用do_softirq()函数时投入运行:
void fastcall raise_softirq(unsigned int nr)
{
unsigned long flags;
local_irq_save(flags);
raise_softirq_irqoff(nr);
local_irq_restore(flags);
}
该函数在触发一个软中断之前先要禁止中断,触发后再恢复原来的状态,如果中断本来就已经被禁止了,那么可以调用另一个函数raise_softirq_irqoff():
/*
* This function must run with irqs disabled!
*/
inline fastcall void raise_softirq_irqoff(unsigned int nr)
{
__raise_softirq_irqoff(nr);
/*
* If we're in an interrupt or softirq, we're done
* (this also catches softirq-disabled code). We will
* actually run the softirq once we return from
* the irq or softirq.
*
* Otherwise we wake up ksoftirqd to make sure we
* schedule the softirq soon.
*/
if (!in_interrupt())
wakeup_softirqd();
}
#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
#define or_softirq_pending(x) or_pda(__softirq_pending, (x))
在中断处理程序中触发软中断是最常见的形式。在这种情况下,中断处理程序执行硬件设备的相关操作,然后触发相应的软中断,最后退出。内核在执行完 中断处理程序之后,马上调用do_softirq()函数,于是软中断开始执行中断处理程序留给它要完成的剩余任务。
怎样使用软中断呢?
1.分配索引
在编译期间,可以通过<linux/interrupt.h>中定义的一个枚举类型来静态声明软中断。索引号小的软中断在索引号大的软中断之前执行。要添加新项的话根据赋予它的优先级来决定加入的位置而不是直接添加到列表末尾。
/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
frequency threaded job scheduling. For almost all the purposes
tasklets are more than enough. F.e. all serial device BHs et
al. should be converted to tasklets, not to softirqs.
*/
enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
#ifdef CONFIG_HIGH_RES_TIMERS
HRTIMER_SOFTIRQ,
#endif
};
2. 注册你的处理程序
在运行时 通过调用open_softirq()注册软件处理程序,该函数有三个参数:软中断的索引号、处理函数和data域存放的数值:
void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
{
softirq_vec[nr].data = data;
softirq_vec[nr].action = action;
}
3.触发你的软中断
通过在枚举类型的列表中添加新项,调用open_softirq()进行注册之后,新的软中断处理程序就能够运行。raise_softirq()函数可以将一个软中断设置为挂起状态,让它在下次调用do_softirq()函数时投入运行:
void fastcall raise_softirq(unsigned int nr)
{
unsigned long flags;
local_irq_save(flags);
raise_softirq_irqoff(nr);
local_irq_restore(flags);
}
该函数在触发一个软中断之前先要禁止中断,触发后再恢复原来的状态,如果中断本来就已经被禁止了,那么可以调用另一个函数raise_softirq_irqoff():
/*
* This function must run with irqs disabled!
*/
inline fastcall void raise_softirq_irqoff(unsigned int nr)
{
__raise_softirq_irqoff(nr);
/*
* If we're in an interrupt or softirq, we're done
* (this also catches softirq-disabled code). We will
* actually run the softirq once we return from
* the irq or softirq.
*
* Otherwise we wake up ksoftirqd to make sure we
* schedule the softirq soon.
*/
if (!in_interrupt())
wakeup_softirqd();
}
#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
#define or_softirq_pending(x) or_pda(__softirq_pending, (x))
在中断处理程序中触发软中断是最常见的形式。在这种情况下,中断处理程序执行硬件设备的相关操作,然后触发相应的软中断,最后退出。内核在执行完 中断处理程序之后,马上调用do_softirq()函数,于是软中断开始执行中断处理程序留给它要完成的剩余任务。
相关文章推荐
- linux中断下半部实现机制之tasklet
- linux中断下半部实现机制之软中断的实现
- linux驱动开发--中断:工作者队列实现中断底半部
- linux中断流程以及下半部机制
- linux顶半部和底半部中断机制
- Linux内核提供了三种不同形式的中断底半部实现机制:软中断、tasklet和工作队列。
- linux顶半部和底半部中断机制
- Linux 2.6中断下半部机制分析
- Linux 2.6中断下半部机制分析
- Linux2.6内核--中断下半部实现方法 工作队列
- Linux2.6中断下半部分的三种实现机制---工作队列
- linux驱动开发--中断:tasklet实现中断底半部
- Linux2.6中断下半部分的三种实现机制---软中断/tasklet/工作队列
- linux驱动开发之输入子系统编程(一)使用工作队列实现中断下半部
- Linux 2.6中断下半部机制分析
- Linux2.6中断下半部分的三种实现机制---工作队列 .
- [转]Linux 2.6中断下半部机制分析
- linux 触摸屏驱动中断下半部实现-工作队列
- Linux 2.6中断下半部机制分析
- linux中断下半部机制