Sending realtime signal from a kernel module to user space fails

ぃ、小莉子 提交于 2021-02-08 03:32:28

问题


I found example code on how to send a realtime signal from a kernel module to user space here

I implemented it in the kernel module as shown below:

static int dmtimer_sendSignal(int val, int id, int sig)
{
    struct siginfo info;
    struct task_struct *t;
    int ret;

    ret = 0;

    if ((id > 0) && (sig > 0))
    {
        /* send the signal */
        memset(&info, 0, sizeof(struct siginfo));
        info.si_signo = sig;
        info.si_code = SI_QUEUE;    // this is bit of a trickery: SI_QUEUE is normally used by sigqueue from user space,
                                    // and kernel space should use SI_KERNEL. But if SI_KERNEL is used the real_time data
                                    // is not delivered to the user space signal handler function.
        info.si_int = val;          //real time signals may have 32 bits of data.
        info._sifields._rt._sigval.sival_int = val;
        info.si_errno = 0;


        rcu_read_lock();
    //  t = find_task_by_pid_type(PIDTYPE_PID, pid);  //find the task_struct associated with this pid
        t = pid_task(find_pid_ns(id, &init_pid_ns), PIDTYPE_PID);
        if(t == NULL)
        {
            printk("no such pid\n");
            rcu_read_unlock();
            return -ENODEV;
        }
        ret = send_sig_info(sig, &info, t);    //send the signal
        rcu_read_unlock();
        if (ret < 0)
        {
            printk("error sending signal\n");
            return ret;
        }
        else
            printk("Send sig %d val %d pid %d\n", sig, val, id);

    }
    return ret;
}

The function dmtimer_sendSignal() is called from an interrupt service routine in the module.

In user space:

main()
{
    sigemptyset (&alarm_sig);
    for (i = SIGRTMIN; i <= SIGRTMAX; i++)
        sigaddset (&alarm_sig, i);
    sigprocmask (SIG_BLOCK, &alarm_sig, NULL);

}

void * DATA_taskInput(void *pArg)
{
    siginfo_t   info;
    int32_t input;
    sigset_t input_sig;
    int fd;

    // Create digital input event
    sig = SIGRTMIN+1;
    sigemptyset(&gSig_input);
    sigaddset(&gSig_input, sig);


    // Set real time signal number for module to use
    if (TIMER_setParm(PARM_SIGRT, SIGRTMIN + 1 ) < 0)
        error(0, errno, "THREADS_events() called TIMER_setParm():");

    // Set PID in module
    TIMER_setParm(PARM_PID, getpid()); 

    fd = signalfd(-1, &gSig_input, 0);

    while(!gQuitInput)
    {
        sigwaitinfo(&gSig_input, &info);            // digital input event
//      read(fd, &info, sizeof(info));

        printf("val = 0x%x\n", info.si_int);
    }

    close(fd);

    printf("DATA_taskInput() end.\n");

    return NULL;

} // end: DATA_taskInput

The user space application pid, and realtime signal number are implemented as module parameters and are set by the user space application, with TIMER_setParm().

The problem is the user space application stays blocked waiting on the signal (sigwaitinfo() never returns). I see from the console the output of the printk() call:

"Send sig 35 val xxxx pid nnnn"

with the correct values for the signal (35) and pid.

sigwaitinfo() returns successfully if I call sigqueue() from within the user space application or if I enter "kill -35 nnnn" from the console.

What am I doing wrong?

Does dmtimer_sendSignal() need to be called from a work queue?

I have tried setting the code to SI_KERNEL (no difference), unblocking the signals (applications closes), and kill_proc_info() (not found).

I am using an Angstrom distribution running on a AM335x SOM from Critical Link. Angstrom version v2012.05 - Kernel 3.2.0-00351-gb80917e


回答1:


I had a similar problem to yours and I've solved it.

In my example,

  • KernelModule: send_sig_info(SIGRTMIN)

  • UserProcess: sigaction(SIGRTMIN) (Wait signal by sa_sigaction handler)

and my real problem is that "SIGRTMIN of UserProcess" is different from Kernel.

  • SIGRTMIN of UserProcess = 34

  • SIGRTMIN of Kernel = 32

So, I changed signal number from SIGRTMIN to 36 and I succeeded in fixing it.

Which signal number did you use in your kernel module?? SIGRTMIN?? If you use SIGRTMIN, I recommend you to change signal number.

Thanks.

Jinbum Park.



来源:https://stackoverflow.com/questions/33041199/sending-realtime-signal-from-a-kernel-module-to-user-space-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!