2
votes

I have written a kernel module that supplies some information about a hardware interrupt to user-space. Currently, the user-space application uses IOCTL to send its PID x to the kernel module. The kernel module then uses this PID to find the task and send the signal:

#define CUSTOM_SIGNAL 44
struct siginfo info;
memset(&info, 0, sizeof(struct siginfo));
info.si_signo = CUSTOM_SIGNAL;
info.si_code = SI_QUEUE;
info.si_int = 0;
struct task_struct *t = pid_task(find_pid_ns(x, &init_pid_ns), PIDTYPE_PID);
send_sig_info(CUSTOM_SIGNAL, &info, t); 

This works really well. However, I find it rather tricky to maintain a dynamic list of PID receivers for a single signal. For this reason I would like to broadcast the signal be default to all running processes (so they need not register to be notified -- it just happens).

One example I can think of that mimics this behaviour is the system shutdown signal. Is it possible to simply broadcast my CUSTOM_SIGNAL, or do I need to iterate over all PIDs, sending one-by-one as above. Or is there a special task representing broadcast?

1
Oof, I really wouldn't advise this. Some process not under your control may have decided to use 44 as a userspace-raised signal for some other purpose.Sneftel
I agree with @Sneftel -- it's unusual and kind of ugly to broadcast a signal like this (I don't think the system shutdown signal really works this way BTW). Anyway, why not simply have interested processes create a separate thread that blocks in an ioctl (or even a read) until a hardware interrupt occurs? No reason to use a signal at all, simply return the fact of an interrupt by unblocking the ioctl/read. This maintains a clean association between process and driver. (And you could always have this thread send a signal to its own PID if you need it that way.)Gil Hamilton
This sounds horrible. If the default disposition for the signal is not SIG_IGN, so the signal is never delivered to a process unless it requests it, there will be major problems. I don't recommend trying to suggest this to the Linux Kernel Mailing List; I'd be tolerably certain it would be shot down in flames, or laughed out of court, in a very short time. It simply isn't the way things are done.Jonathan Leffler
Thank you to everybody for pointing out that the direction I have taken is incorrect. I have decided to drop the use of signals entirely and use a threaded poll of the ioctl, as advised.Andrew

1 Answers

2
votes

This is downright incorrect.

I have written a kernel module that supplies some information about a hardware interrupt to user-space. Currently, the user-space application uses IOCTL to send its PID x to the kernel module. The kernel module then uses this PID to find the task and send the signal

First off, you have access to calling thread task structure by the means of current. Obtaining a PID like this and then finding it makes no sense whatsoever.

Also your code sample suggests you don't lock RCU, which is a bug you would learn about if you had debug enabled.

This works really well. However, I find it rather tricky to maintain a dynamic list of PID receivers for a single signal. For this reason I would like to broadcast the signal be default to all running processes (so they need not register to be notified -- it just happens).

This is similarly wrong on its principle. You will cause spurious wake ups and that has potential for a lot of weird-ass fun (not everything is as 'atomic' as people think).

Instead create a device driver to which a file descriptor can be obtained. Interested threads will poll the descriptor and that's how they will learn about the event.