2013-02-04 20 views
5

Unreliable Guide To Hacking The Linux Kernel stwierdza, że ​​Czy jest on niezawodny?

Można powiedzieć, że jesteś w przerwanie sprzętowe, ponieważ in_irq() zwraca true.
Uwaga. Pamiętaj, że zwróci to fałszywy alarm, jeśli przerywacze są wyłączone (patrz poniżej).

Czy rzeczywiście jest tak, że in_irq() może zwracać niezerowy nie w kontekście hardirq w jądrach Linuksa 2.6.32 lub nowszych na x86?

W moich doświadczeniach z jądrem 2.6.32 (Debian 6) i 3,4 (OpenSUSE 12.1), in_irq() zawsze zwrócone 0, gdy wywołana z kontekstu procesu, nawet jeśli została wywołana między local_irq_disable() i . Wyniki były takie same, gdy użyłem funkcji spinlock, które wyłączały przerywanie zamiast local_irq*.

Z kodu źródłowego jądra nie mogę obecnie zobaczyć, w jaki sposób in_irq() może zwrócić fałszywy alarm. Czy ktokolwiek mógłby to wyjaśnić?

EDIT: Próbowałem również zarówno *_irqsave() i *_irq() Spinlock API jak również local_irq_save()/local_irq_restore(), wyniki były takie same, czyli in_irq() zwrócone 0, gdy przerwania zostały wyłączone. Wyłączenie przerwań jawnie za pomocą instrukcji maszynowej x86 również nie wymusiło, aby funkcja in_irq() zwróciła wartość niezerową.

Odpowiedz

3

in_irq() to zawijany papierek, który looks at some bits in preempt_count, który jest w Int thread_info struktury, a wartość 0 oznacza, że ​​nie jest wstępnie opróżniona tak, że nie znajduje się w przerwania.

local_irq_disable() samo przez się nie wpływa na tę liczbę, ale spin_lock_irqsave()does, więc może to prowadzić do fałszywych alarmów. Mówisz, że użyłeś funkcji spinlock, czy użyłeś tego? Jeśli tak, sprawdź, czy zmienia się wartość preempt_count.

EDYCJA: Aby pokryć wszystkie bazy, sprawdź, czy włączono opróżnianie jądra.

+0

CONFIG_PREEMPT to oczywiście "y". Tak, sprawdziłem * _irqsave, * _irq i * _bh warianty API spinlock. W każdym przypadku 'in_irq()' zwróciło 0, nawet gdy blokada spinlock była zablokowana. – Eugene

+0

Tak, widziałem implementację 'in_irq()'. Dlatego nie rozumiem, dlaczego nie generuje fałszywych alarmów na moich maszynach. – Eugene

+0

Czy 'in_irq()' zwraca wartość niezerową, gdy blokada spinlock jest zablokowana lub przerywania są wyłączone w inny sposób w twoich eksperymentach? – Eugene