본문 바로가기

Core BSP 분석/리눅스 커널 핵심 분석

LKML - [PATCH v2] clk: fix reentrancy of clk_enable() on UP systems

최근 시스템이 복잡해져서 대부분의 시스템은 SMP를 적용한다고 생각하지만 
안정성을 가장 중요하게 보는 자동차 시스템은 하나의 CPU만 적용해요.
 
이런 UP 시스템에서,
spin_trylock_irqsave() API를 쓰게 되면 무조건 return true를 수행하게 됩니다.
무엇보다 중요한 점은 얼마만큼 시간 차이가 있는지 출력하죠.
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 83c8df7..5add75b 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -143,10 +143,18 @@ static unsigned long clk_enable_lock(void)
 {
        unsigned long flags;
 
-       if (!spin_trylock_irqsave(&enable_lock, flags)) {
+       /*
+        * On UP systems, spin_trylock_irqsave() always returns true, even if
+        * we already hold the lock. So, in that case, we rely only on
+        * reference counting.
+        */
+       if (!IS_ENABLED(CONFIG_SMP) ||
+           !spin_trylock_irqsave(&enable_lock, flags)) {
                if (enable_owner == current) {
                        enable_refcnt++;
                        __acquire(enable_lock);
+                       if (!IS_ENABLED(CONFIG_SMP))
+                               local_save_flags(flags);
                        return flags;
                }
                spin_lock_irqsave(&enable_lock, flags);