具有实时任务的多核Linux软锁定

时间:2016-06-06 05:49:35

标签: c linux multithreading scheduling

我不确定它是否是Linux内核错误,而我搜索了许多文档但找不到任何提示。 我问这个问题是为了检查是否有人遇到过类似问题以及如何解决这个问题。

Environment: 
Linux Kernel: 2.6.34.10 
CPU: MIPS 64 (total 8 cores)
application running in user space`

应用程序有严格的响应时间要求,因此应用程序线程在SCHED_FIFO中设置,并且一些关键线程与专用CPU核心相关,在这种情况下一切正常。后来有人发现CPU峰值有时会出现CPU峰值(例如短峰值的60%-80%)。为了解决这个问题,将CPU 0和CPU 7保留为Linux本机应用程序,并通过在引导行中添加“isolcpus = 1-6”来为我们的应用程序隔离CPU 1-6,解决了CPU峰值问题,同时引发了以下问题

在运行一段时间和系统挂断之后,将在控制台中打印以下消息,但并非总是偶尔。 (它可能发生在多个CPU核心中)

BUG: soft lockup - CPU#4 stuck for 61s! [swapper:0]
Modules linked in: hdml softdog cmt cmm pio clock linux_kernel_bde  linux_uk_proxy linux_bcm_core mpt2sas
Cpu 4
$ 0   : 0000000000000000 ffffffffc3600020 ffffffffc1000b00 c0000001006f0010
$ 4   : 0000000000000001 0000000000000001 000000005410f8e0 ffffffffbfff00fe
$ 8   : 000000000000001e ffffffffc15b3c80 0000000000000002 0d0d0d0d0d0d0d0d
$12   : 0000000000000000 000000004000f800 0000000000000000 c000000100768000
$16   : ffffffffc36108e0 0000000000000010 ffffffffc35f0000 0000000000000000
$20   : 0000000000000000 0000000000000000 0000000000000000 0000000000000000
$24   : 0000000000000007 ffffffffc103b3a0                                  
$28   : c0000001006f0000 c0000001006f3e38 0000000000000000 ffffffffc103d774
Hi    : 0000000000000000
Lo    : 003d0980b38a5000
epc   : ffffffffc1000b20 r4k_wait+0x20/0x40
    Not tainted
ra    : ffffffffc103d774 cpu_idle+0xbc/0xc8
Status: 5410f8e3    KX SX UX KERNEL EXL IE 
Cause : 40808000

查看回调跟踪,线程始终挂起条件变量wait,伪等待/信号fnction如下

int xxx_ipc_wait(int target)    
{
struct timespec to;

.... /* other code */
clock_gettime(CLOCK_MONOTONIC, &to);
timespec_add_ns(&to, 1000000);
pthread_mutex_lock(&ipc_queue_mutex[target]);
ret = pthread_cond_timedwait (&ipc_queue_cond[target], &ipc_queue_mutex[target], &to);
pthread_mutex_unlock(&ipc_queue_mutex[target]);

return ret;
}

void xxx_ipc_signal_atonce(int target)
{
... 
pthread_mutex_lock(&ipc_queue_mutex[target]);
pthread_cond_signal(&ipc_queue_cond[target]);
pthread_mutex_unlock(&ipc_queue_mutex[target]);
}

这些等待无论如何应该被唤醒,因为它是超时条件变量。甚至创建了一个专用的Linux线程来及时发出这些条件变量的信号每隔5秒,问题仍然存在。

使用“dmesg”检查内核日志,但未找到任何有价值的日志。当启用内核调试并检查内核日志/ proc / sched_debug时,有如下奇怪的信息。

cpu#1   /* it is a normal CPU core */
  .nr_running                    : 1
  .load                          : 0
  .nr_switches                   : 1892378
  .nr_load_updates               : 167378
  .nr_uninterruptible            : 0
  .next_balance                  : 4295.060682
  .curr->pid                     : 235  /* it point to the runnable tasks */
            task   PID         tree-key  switches  prio     exec-runtime         sum-exec        sum-sleep
----------------------------------------------------------------------------------------------------------
R         aaTask   235         0.000000       157    49                0               0         

cpu#4
  .nr_running                    : 1  /* okay */
  .load                          : 0
  .nr_switches                   : 2120455  /* this value changes from time to time */
  .nr_load_updates               : 185729
  .nr_uninterruptible            : 0
  .next_balance                  : 4295.076207
  .curr->pid                     : 0   /* why this is ZERO since it has runable task */
  .clock                         : 746624.000000
  .cpu_load[0]                   : 0
  .cpu_load[1]                   : 0
  .cpu_load[2]                   : 0
  .cpu_load[3]                   : 0
  .cpu_load[4]                   : 0
cfs_rq[4]:/
  .exec_clock                    : 0.000000
  .MIN_vruntime                  : 0.000001
  .min_vruntime                  : 14.951424
  .max_vruntime                  : 0.000001
  .spread                        : 0.000000
  .spread0                       : -6833.777140
  .nr_running                    : 0
  .load                          : 0
  .nr_spread_over                : 0
  .shares                        : 0
 rt_rq[4]:/
  .rt_nr_running                 : 1
  .rt_throttled                  : 1
  .rt_time                       : 900.000000
  .rt_runtime                    : 897.915785

runnable tasks:
            task   PID         tree-key  switches  prio     exec-runtime         sum-exec        sum-sleep
----------------------------------------------------------------------------------------------------------
       bbbb_appl   299         6.664495   1059441    49               0               0               0.000000               0.000000               0.000000 /

我不知道为什么Linux系统会像这样工作,最后,我将任务优先级从SCHED_FIFO更改为SCHED_OTHER,这个问题在经过几个月的运行后才发生。由于CPU内核是隔离的,因此SCHED_FIFO和SCHED_OTHER之间的系统行为类似,SCHED_OTHER的使用也更广泛。

1 个答案:

答案 0 :(得分:0)

应用程序在条件/ mutex上永远等待可能是优先级倒置的标志,除非它使用优先级继承启用同步原语。

在FIFO实时调度模式中,线程具有CPU,直到它自愿放弃为止。这与大多数软件编写的抢占式多任务完全不同。

除非您的软件在配置要求中明确具有REALTIME_FIFO,否则我不会花时间而是坚持使用RR和/或CPU固定/隔离。