In short, user preemption can occur
When returning to user-space from a system call
When returning to user-space from an interrupt handler
Kernel preemption can occur
When an interrupt handler exits, before returning to kernel-space
When kernel code becomes preemptible again
If a task in the kernel explicitly calls schedule()
If a task in the kernel blocks (which results in a call to schedule())