ユニ プロセッサ マシンで spin_lock_irqsave に関する奇妙な問題に直面しています。rx_timeout と rx_callback の 2 つの関数で共有される rx_process という名前の重要なコード/関数があります。これは、Linux カーネル ドライバー omap-serial.c の下にあります。
rx_process ( uartNum)
{
//critical section
}
rx_timeout (uartNum)//this is called from softIrq context upon timer expiry
{
rx_process (uartNum);
}
rx_callback(uartNum)//this is called when interrupt handler registers upon interrupt and when 4k buf is full in rx_process function which invokes start_rx_dma which results in this call back function.
{
rx_process (uartNum);
}
これら 2 つの関数間で競合状態が発生していることがわかったので、関数の開始時と終了時に rx_process に spin_lock_irqsave を導入することにしましたが、それでも競合状態が発生し、時々、データ損失とカーネル パニックを観察します。
rx_process ( uartNum)
{ spin_lock_irqsave(&lock, flags);
//critical section
spin_unlock_irqrestore(&lock, flags);
}
rx_timeout (uartNum)//this is called from softIrq context upon timer expiry
{
rx_process (uartNum);
}
rx_callback(uartNum)//this is called when interrupt handler registers upon interrupt and when 4k buf is full in rx_process function which invokes start_rx_dma which results in this call back function
{
rx_process (uartNum);
}
ここで、spin_lock_irqsave を rx_timeout と rx_callback 関数に移動しましたが、競合状態は見られません。
rx_process ( uartNum)
{
//critical section
spin_unlock_irqrestore(&lock, flags);
}
rx_timeout (uartNum)//this is called from softIrq context upon timer expiry
{
spin_lock_irqsave(&lock, flags);
rx_process (uartNum);
spin_unlock_irqrestore(&lock, flags);
}
rx_callback(uartNum)//this is called when interrupt handler registers upon interrupt and when 4k buf is full in rx_process function which invokes start_rx_dma which results in this call back function
{
spin_lock_irqsave(&lock, flags);
rx_process (uartNum);
spin_unlock_irqrestore(&lock, flags);
}
rx_process 内で使用される spin_lock_irqsave が失敗し、競合状態を防げない理由を誰かが説明できれば、本当にありがたいです。