Chinaunix首页 | 论坛 | 博客
  • 博客访问: 131090
  • 博文数量: 22
  • 博客积分: 698
  • 博客等级: 上士
  • 技术积分: 265
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-17 09:53
文章分类
文章存档

2012年(2)

2011年(15)

2010年(5)

我的朋友

分类: LINUX

2011-01-27 16:18:09

一、中断处理为什么要下半部?
Linux在中断处理中间中断处理分了上半部和下半部,目的就是提高系统的响应能力和并发能力。通俗一点来讲:当一个中断产生,调用该中断对应的处理程序(上半部)然后告诉系统,对应的后半部可以执行了。然后中断处理程序就返回,下半部会在合适的时机有系统调用。这样一来就大大的减少了中断处理所需要的时间。

二、那些工作应该放在上半部,那些应该放在下半部?
没有严格的规则,只有一些提示:
1、对时间非常敏感,放在上半部。
2、与硬件相关的,放在上半部。
3、不能被其他中断打断的工作,放在上半部。
以上三点之外的,考虑放在下半部。

三、下半部机制在Linux中是怎么实现的?
下半部在Linux中有以下实现机制:
1、BH(在2.5中删除)
2、任务队列(task queue,在2.5删除)
3、软中断(softirq,2.3开始。本文重点)
4、tasklet(2.3开始)
5、工作队列(work queue,2.5开始)

四、软中断是怎么实现的(以下代码出自2.6.32)?
软中断不会抢占另外一个软中断,唯一可以抢占软中断的是中断处理程序。
软中断可以在不同CPU上并发执行(哪怕是同一个软中断)

1、软中断是编译期间静态分配的,定义如下:
    NR_SOFTIRQS 
};


说明:
(1)、软中断的个数书上说是32,看来到这个版本已经发生变化了。
(2)、void (*action)(struct softirq_action *);传递整个结构体指针在于当结构体成员发生变化是,接口不变。

2、系统执行软中断一个注册的软中断必须被标记后才会执行(触发软中断),通常中断处理程序会在返回前标记它的软中断。在下列地方,待处理的软中断会被执行:
(1)、从一个硬件中断代码处返回。
(2)、在ksoftirqd内核线程。
(3)、在那些显示检查和执行待处理的软中断代码中。

ksoftirqd说明:
每个处理器都有一个这样的线程。所有线程的名字都叫做ksoftirq/n,区别在于n,它对应的是处理器的编号。在一个双CPU的机器上就有两个这样的线程,分别叫做ksoftirqd/0和ksoftirqd/1。为了保证只要有空闲的处理器,它们就会处理软中断,所以给每个处理器都分配一个这样的线程。

执行软中断的代码如下:
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));
    lockdep_softirq_enter();

    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) {
            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();

    account_system_vtime(current);
    _local_bh_enable();
}

3、编写自己的软中断

4、软中断处理程序注意
(1)、软中断处理程序执行的时候,允许响应中断,但自己不能休眠。
(2)、如果软中断在执行的时候再次触发,则别的处理器可以同时执行,所以加锁很关键。

阅读(3287) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~