2014-06-05 41 views
0

我想用定時器多次調用一個函數。 爲了實現這個,我使用了this的例子。它的默認工作沒有任何錯誤。內核模塊定時器殺死系統

當我將此代碼片段集成到我的源代碼中時,它導致內核恐慌(?)。發生長時間錯誤,虛擬機停止工作 。

印在控制檯上的錯誤:

[ 1130.520474] [<c12bf6ae>] ? no_context+0x14b/0x155  
[ 1130.520474] [<c12bf7ca>] ? bad_area_nosemaphore+0xa/0xc      
[ 1130.520474] [<c12c7370>] ? do_page_fault+0x1bf/0x35e 
[ 1130.520474] [<c100d6bf>] ? show_trace_log_lvl+0x37/0x3d      
[ 1130.520474] [<c12c71b1>] ? vmalloc_fault+0x87/0x87      
[ 1130.520474] [<c12c5377>] ? error_code+0x67/0x6c        
[ 1130.520474] [<c12c306e>] ? __schedule+0x31/0x5a4        
[ 1130.520474] [<c100fa07>] ? sched_clock+0x9/0xd  
[ 1130.520474] [<c1051896>] ? sched_clock_local+0x10/0x14b 
[ 1130.520474] [<c102abe2>] ? test_tsk_need_resched+0xa/0x13 
[ 1130.520474] [<c102abe2>] ? test_tsk_need_resched+0xa/0x13    
[ 1130.520474] [<c102e59c>] ? check_preempt_curr+0x48/0x58      
[ 1130.520474] [<c121f462>] ? __napi_complete+0x1b/0x22       
[ 1130.520474] [<c12213f0>] ? napi_complete+0x25/0x31 
[ 1130.520474] [<f825d2d6>] ? e1000_clean+0x33e/0x35c [e1000] 
[ 1130.520474] [<c105daf5>] ? arch_local_irq_save+0xf/0x14 
[ 1130.520474] [<c12c45a2>] ? _raw_spin_lock_irq+0x9/0x12     
[ 1130.520474] [<c1042307>] ? run_timer_softirq+0x1eb/0x1f3     
[ 1130.520474] [<c107b86c>] ? __rcu_process_callbacks+0x5f/0x252    
[ 1130.520474] [<c103cfdb>] ? local_bh_enable+0x2/0x2    
[ 1130.520474] [<c103d0dc>] ? __do_softirq+0x101/0x12f 
[ 1130.520474] [<c103c6e8>] ? __local_bh_enable+0x37/0x67      
[ 1130.520474] <IRQ> [<c10cd712>] ? sys_write+0x58/0x61      
[ 1130.520474] [<c12c8e5f>] ? sysenter_do_call+0x12/0x28 

我想我的問題是返回先前的前一個新的呼叫被觸發。

爲了測試這一點,我修改了上面提到的定時器玩具例子:

int i; 

void timer1_routine(unsigned long data) 
{ 
    int no; 
    no=i; 
    i++; 
    printk(KERN_INFO "process %d starts",no); 

    msleep(5000); 

    printk(KERN_INFO "process %d ends",no); 

    mod_timer(&timer1, jiffies + HZ); /* restarting timer */ 
} 

這導致了同樣的錯誤,所以我想,我的猜測是正確的:有兩個電話之間的衝突。我的問題是如何避免這個問題,如果我不知道函數的執行需要多少時間?

回答

3

linux內核有兩種主要類型的上下文:進程上下文和原子上下文。你習慣於在流程上下文中運行的東西。原子環境主要用於硬件和軟件的中斷。內核定時器從軟件中斷(原子上下文)運行。在原子上下文中運行的代碼有一些限制,包括禁止睡眠。這解釋了這次事故。

你幾乎肯定想要一個workqueue而不是一個計時器。工作隊列函數在進程上下文中執行,因此您可以進入休眠狀態。如果你要在內核的這個級別工作,你真的需要閱讀LDD3的這一章:http://lwn.net/images/pdf/LDD3/ch07.pdf

相關問題