Edit: Clarification - это Linux код ядра.
Я отправляю SIGSTOP в поток, а затем вызываю wait_task_inactive, чтобы убедиться, что он остановился. А вот процессор RCU-зависает судя по логу ядра. У меня нет полученной спин-блокировки, и у меня должны быть права root. Следует также отметить, что поток, который я пытаюсь остановить, ни в коем случае не является особенным, это всего лишь однопоточный пользовательский скрипт. Кроме того, если у кого-то есть лучшее предложение о том, как убедиться, что поток проснулся, у меня все уши.
Имея в виду комментарий дерева Линуса в wait_task_inactive (), я могу думать только о двух возможностях :
Получен какой-то спинлок, о котором я не знаю. Я не думаю, что это.
Сигнал никогда не принимается и не обрабатывается потоком. Я не знаю, почему это могло произойти, кроме привилегий (то есть у меня недостаточно для отправки этого сигнала, в чем я сомневаюсь) или что wait_task_inactive имеет более высокий приоритет, и поток перестает ждать. Но процессоров много, а нить запущена мной, так что ...
В заключение я тоже застопорился!
Код:
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);
}
}
Буфер ядра:
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]