Non sono un guru dello scheduler, ma vorrei spiegare come la vedo io. Ecco diverse cose.
- preempt_disable() non disabilita l'IRQ . Aumenta solo un
thread_info->preempt_count
variabile. - La disabilitazione degli interrupt disabilita anche la prelazione perché lo scheduler non funziona dopo, ma solo su una macchina a CPU singola. Su SMP non è sufficiente perché quando chiudi gli interrupt su una CPU l'altra/le altre fanno/fanno ancora qualcosa in modo asincrono.
- Il Big Lock (significa - chiudere tutti gli interrupt su tutte le CPU) sta rallentando drasticamente il sistema - quindi è per questo che non è più in uso. Questo è anche il motivo per cui preempt_disable() non chiude l'IRQ.
Puoi vedere cos'è preempt_disable(). Prova questo:1. Ottieni uno spinlock.2. Programma chiamate()
Nel dmesg vedrai qualcosa come "BUG:scheduling while atomic". Questo accade quando lo scheduler rileva che il tuo processo è in un contesto atomico (non preventivo) ma pianifica se stesso.
Buona fortuna.
In un modulo del kernel di test che ho scritto per monitorare/profilare un'attività, ho provato a disabilitare gli interrupt:
1 - Utilizzo di local_irq_save()
2 - Utilizzo di spin_lock_irqsave()
3 - Disabilita manualmente_irq() a tutti gli IRQ in /proc/interrupts
In tutti e 3 i casi potevo ancora usare l'hrtimer per misurare il tempo anche se gli IRQ erano disabilitati (e anche un'attività che stavo monitorando è stata anticipata).
Trovo questo moooooooolto strano... Personalmente stavo anticipando quello che ha sottolineato Sebastian Mountaniol -> Nessuna interruzione - nessun orologio. Nessun orologio, nessun timer...
Kernel Linux 2.6.32 su un singolo core, singola CPU... Qualcuno può avere una spiegazione migliore?