Quick question.
In this situation, should I use "spin_lock_bh"?
Since preemption is "disabled", even though kernel context holds "spin_lock", tasklet cannot preempt the kernel context which is calling ioctl and this kernel context is kind of "safe" from BH.
or is it possible for following scenario to happen?
When this kernel context is getting serviced, IRQ comes and ISR will schedule tasklet. Then, after returning from IRQ, kernel schedule will pickup tasklet even though there is kernel context.
I'm not sure which one is correct?
Preemption status is irrelevant. Upon return from the ISR, the tasklet could run whether preemption is enabled or disabled. So, yes you need to use spin_lock_bh()
.
Regarding synchronization issues, SoftIRQs/Tasklets behave like the ISRs, the only difference is that ISRs interrupt BHs. Since the ISR interrupted the kernel while it was holding a lock, so can the tasklet.