Processes blocked in system calls can be unkillable. In the Linux kernel, what typically happens is that the process is blocked on a wait queue (what userspace usually call a "condition variable" or "monitor") in one of the wait_event() family of functions. Because the kernel doesn't implement any kind of exception handling, there is no way to automatically break out of this; you have to wait for some other task to call wake_up().
It's possible to wait in a "interruptible" way, and many subsystems do. But that's hard, because it means that the resources you would otherwise be responsible for clean up need to be detected and cleaned up by someone else (or alternatively that someone else needs to pick up and finish what you started, or you need to be able to roll back a partially completed action, etc...). Userspace usually ignoes this problem (because the task got killed, right?), but in the kernel a leak is a huge bug.
So the default is that waiting in the kernel means that the kernel can't allow the process to be terminated (or otherwise be delivered a signal that would invalidate the stack). And the side effect is that userspace sees an unkillable process in the "D" state.