Sending Signal from Kernel to User Space

How to send signal from Linux kernel space to user space in order to notify about an input hardware event

I will concentrate on sending a signal, since that is what you asked for, although sending signals to a process is quite brutal. It would be better to implement poll and read file operations so the user code can wait for events from the device and read them.

Anyway, for sending a signal to the processes that opened the device, the things you need are:

  1. You need a struct fasync_struct * in the private data of your device:

    struct fasync_struct *pasync_queue;

    It needs to be initialized to NULL by some means during initialization of your device private data. How you do that is up to you.

  2. You need a fasync file operation handler pointed to by the fasync member of your struct file_operations. The implementation of the fasync handler is very simple as it just needs to call fasync_helper() using supplied parameters and a pointer to your device's private struct fasync_struct *:

    static int exer_fasync(int fd, struct file *pfile, int mode)
    {
    // N.B. Change this code to use the pasync_queue member from your device private data.
    struct fasync_struct **fapp = &pasync_queue;
    return fasync_helper(fd, pfile, mode, fapp);
    }

    struct file_operations exer_file_operations = {
    .owner = THIS_MODULE,
    .open = exer_open,
    .read = exer_read,
    .write = exer_write,
    .release = exer_close,
    .fasync = exer_fasync,
    };
  3. Your device driver can send a SIGIO signal by calling kill_fasync() as follows:

         // N.B. Change this code to use the pasync_queue member from your device private data.
    struct fasync_struct **fapp = &pasync_queue;
    kill_fasync(fapp, SIGIO, POLL_IN);

    N.B. The last parameter (value POLL_IN in this case) affects the value of the si_band member of the siginfo_t that your application sees in its signal handler.

  4. Your application needs to set a signal handler for the SIGIO signal. I recommend usingsigaction() to set this up.

  5. Your application needs to set the O_ASYNC flag when it opens the device file, or set it by calling fcntl(fd, F_SETFL, O_ASYNC); after opening the device file.

How to send a signal from kernel module to user-space application?

  • You can always use normal sockets, like UDP or UNIX.
  • You can export this information via /proc or /sys (see this question).
  • You can use Netlink (see this question).


Related Topics



Leave a reply



Submit