Why can't I stop this thread from the Linux kernel?

1

Edit: Clarification -- This is Linux kernel code.

I send SIGSTOP to a thread and then call wait_task_inactive to make sure it stopped. But the CPU RCU-stalls judging by the kernel log. I have no spin-lock acquired and I should have root privileges. I should also mention that the thread I'm trying to stop is not special in any way, it's just a single-threaded user script. Also, if someone has a better suggestion on how to make sure the thread woke up, I'm all ears.

With the Linus' tree comment at wait_task_inactive() in mind, I can only think of two possibilities:

  • There is some spinlock acquired which I'm not aware of. I don't think is this one.

  • The signal is never received or handled by the thread. I don't know why could this happen other than privileges (i.e. I don't have enough to send that signal, which I doubt) or that wait_task_inactive has higher priority and the thread starves waiting. But there are plenty of CPU and the thread is runned by me so...

In conclusion, I am stalled too!

Code:

void __send_signal(int sig_num, struct task_struct* p){
       struct siginfo info;
       unsigned long previous_state = p->state;
       int ret = 0;
       memset(&info, 0, sizeof(struct siginfo));
       info.si_signo = sig_num;
       info.si_code = 0;
       info.si_int = 1234;
       ret = send_sig_info(sig_num, &info,  p);
       /* Make sure the signal has been captured */
       switch(sig_num){
        case SIGSTOP:
            wait_task_inactive(p, p->state); /* It believe it stalls here */
            break;
        case SIGCONT:
            /* You definitely don't want to send a SIGCONT to a non-runnable thread. */
            while (previous_state != TASK_RUNNING && previous_state != TASK_WAKING &&
                     p->state == previous_state){
                cpu_relax();
            }
            break;
        default:
            printk(KERN_INFO "Signal %d was only sent...\n",sig_num);
       }
        if (ret < 0) {
               printk(KERN_ALERT "Error sending signal to PID %d\n",p->pid);
       }
}

Kernel buffer:

INFO: rcu_preempt detected stalls on CPUs/tasks:
[  184.838479]  6-...: (1 GPs behind) idle=315/140000000000000/0 softirq=40955/40956 fqs=2625 
[  184.846927]  (detected by 0, t=5252 jiffies, g=16297, c=16296, q=5592)
[  184.853610] Task dump for CPU 6:
[  184.856919] executable    R  running task    14288  5286   5172 0x0000000c
[  184.864198]  0000000000000086 ffffffff8a047a20 ffffb69449493b00 ffffffff89a6aab2
[  184.871992]  00000000ffffffff ffffb69449493b20 ffffffff894c004e 0000000000000006
[  184.879783]  000000000000002c ffffb69449493b38 ffffffff894c4fc9 ffffffff89a6a89a
[  184.887576] Call Trace:
[  184.890111]  [<ffffffff89a6aab2>] ? _raw_spin_unlock_irqrestore+0x32/0x60
[  184.896979]  [<ffffffff894c004e>] ? down_trylock+0x2e/0x40
[  184.902550]  [<ffffffff894c4fc9>] console_trylock+0x19/0x70
[  184.908202]  [<ffffffff89a6a89a>] ? _raw_spin_unlock+0x1a/0x30
[  184.914113]  [<ffffffff894c6eb5>] vprintk_emit+0x2f5/0x520
[  184.919679]  [<ffffffff894c724f>] vprintk_default+0x1f/0x30
[  184.925338]  [<ffffffff89577eb1>] printk+0x48/0x50
[  184.930222]  [<ffffffffc1a2c0db>] send_signal+0x70/0xe2 [module]
c
linux
linux-kernel
kernel
posix
asked on Stack Overflow Feb 14, 2020 by Carlos Bilbao • edited Feb 14, 2020 by Carlos Bilbao

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0