中斷中不能睡眠的原因


為什么interrupt context中不能調用導致睡眠的kernel API呢?如果驅動這么做會導致什么樣的后果呢?

本文的實驗在X86 64bit + 標准4.4內核上完成。

看下一個中斷:

    #define DRIVER_DESC "context schedule test driver"

    static struct timer_list cst_timer;

    static void cst_timer_handler (unsigned long data)
    {
            struct task_struct *p = current;

            pr_info("=====in timer handler=====\n");
            pr_info("cst shoot %16s [%x] task:\n", p->comm, preempt_count());
            mod_timer(&cst_timer, jiffies + HZ);
            schedule();
    }

    static int __init cst_init(void)
    {
            init_timer(&cst_timer);
            cst_timer.function = cst_timer_handler;
            cst_timer.expires = jiffies + HZ;
            add_timer(&cst_timer);

            pr_info(DRIVER_DESC " : init on cpu:%d\n", smp_processor_id());
            return 0;
    }
    module_init(cst_init);

    static void __exit cst_exit(void)
    {
            del_timer_sync(&cst_timer);
            pr_info(DRIVER_DESC " : exit\n");
    }
    module_exit(cst_exit);

    MODULE_DESCRIPTION(DRIVER_DESC);
    MODULE_AUTHOR("sylas ");
    MODULE_LICENSE("GPL");

  另外,再構造一個被中斷的受害者:

    int main(int argc, char **argv)
    {
        int i = 0;

        while (1) {
            sqrt (rand ());

            if ((i % 0xffffff) == 0)
                printf ("=\n");

            if ((i % 0xfffffff) == 0)
                printf ("haha......still alive\n");

            i++;
        }

        return 0;
    }

  測試時先把受害者跑起來,注意,必須把核都占滿。然后插入內核模塊。

  后面就可以看Log了。

  sudo tail –f /var/log/messages

  結果分析:

  系統並沒有掛掉,而是每隔一秒打一次call trace。

  當然,這里的測試看起來一切OK,但這並不是說可以自由的在中斷上下文中調用導致睡眠的內核API,因為我這里給出了一個簡單的例子,實際上也有可能導致系統死鎖。例如在內核態持有鎖的時候被中斷,然后發生調度。有興趣的同學可以自己修改上面的代碼實驗這種情況。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM