You can send a signal to the user space stream from the kernel API, which can help you run non-blocking:
send_sig(int sig, struct task_struct *p, int priv)
But there is a limitation: you need to know the pid of the user thread in the kernel. You can do this by writing the pid of the user process via / proc, and then the kernel reading the pid. With this arrangement, when there is an interrupt, the kernel can send a signal to the user thread. If your process reboots or gets killed, you will have to update the pid via proc.
, , . Netlink - .