Well, there are different types of pre-emptions, a user process or a kernel context on behalf of user-space.
User-space may always pre-empt. There are various situations and configurations where the kernel code may block this pre-emption.
The ISR is always serviced (unless IRQs are masked; very rare and short). A kernel routine (like already running a process swap) may disable kernel/user space per-emption until it is finished its business. The source is usually in assembler and may depend on kernel options. When the kernel context resumes pre-emption, then a context switch may occur.
See the diagram below....
The blue part is where the kernel keeps doing an sbrk()
for task 2. If pre-emption wasn't disabled, it would go to task 1 immediately. It may need to atomically get some memory page for that task. Usually this is short. When it re-ables the pre-emption, we will notice that an IRQ has occurred and data is ready for the task 1 and then a context switch will occur. The task 2 will still be waiting for the sbrk()
to finish.
There are actually two task context (kernel stacks) for each of task 1 and task 2; but it is running the same kernel code and the higher kernel memory space all looks the same (I put this all under the heading 'kernel'). The user space is completely different (virtual memory). My UML is probably really mixed up. I don't have some Dia sequence view.