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

孙凯文

当我搜索许多文档并且找不到任何提示时,我不确定这是否是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%)。为了解决这个问题,通过在引导行中添加“ isolcpus = 1-6”,保留了用于Linux本机应用程序的CPU 0和CPU 7,并为我们的应用程序隔离了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

查看回调跟踪,该线程始终在条件变量等待时处于挂起状态,伪等待/信号功能如下

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也被更广泛地使用。

鲍巴

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

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

软实时Linux调度

来自分类Dev

使用带有超时任务列表的wait_for

来自分类Dev

如果硬实时任务超过其截止日期会发生什么?

来自分类Dev

创建超时任务

来自分类Dev

在Ubuntu上运行具有多核的应用程序

来自分类Dev

蝙蝠超时任务技能

来自分类Dev

java ScheduleExecutorService超时任务

来自分类Dev

如何使用序言指定软约束?(具有软约束的拼图)

来自分类Dev

如何使用序言指定软约束?(具有软约束的难题)

来自分类Dev

尝试重命名/删除文件时,Linux是否具有文件锁定保护功能

来自分类Dev

ln中具有硬链接和软链接的路径

来自分类Dev

具有转发时间的任务

来自分类Dev

具有参数的WCF任务

来自分类Dev

具有多个动作的任务

来自分类Dev

具有记录级别锁定的收集?

来自分类Dev

具有更新锁定的ServiceStack OrmLite Select

来自分类Dev

调用Wait()或WaitAll()时任务总是取消

来自分类Dev

耗时任务(或查询)的进度栏

来自分类Dev

异步/等待方法中的耗时任务

来自分类Dev

马拉松的临时任务

来自分类Dev

在RxJava中取消超时任务

来自分类Dev

调用Wait()或WaitAll()时任务总是取消

来自分类Dev

异步/等待方法中的耗时任务

来自分类Dev

马拉松的临时任务

来自分类Dev

如何按顺序执行定时任务?

来自分类Dev

大数据处理的定时任务

来自分类Dev

jQuery具有JavaScript效果的实时预览

来自分类Dev

具有近实时搜索Solr的Drupal

来自分类Dev

具有实时dmesg输出的终端