当前位置: 首页 > news >正文

sigwaittest测试超标的调试过程

1,问题描述

硬件环境:飞腾S2500(64核)

OS:kylinOS, linux preempt rt, 4.19.90

测试命令:sigwaittest -p 90 -i 1000 -a 1

测试结果:信号混洗值最大超过了80us,与飞腾其他CPU的设备相比较,增大了很多

2,调试过程

1)日志分析

使用trace-cmd命令来抓取ftrace log:trace-cmd start -e all; sigwaittest -p 90 -i 1000 -a 1 -b 80

得到如下日志:

sigwaitt-13091   1....0  1741.963614: sys_enter:            NR 131 (3321, 3322, a, 20c49ba5e353f7cf, 3b9ac9ff, 44cc0)
sigwaitt-13091   1...10  1741.963615: sys_enter_tgkill:     tgid: 0x00003321, pid: 0x00003322, sig: 0x0000000a
sigwaitt-13091   1d..11  1741.963616: sched_waking:         comm=sigwaittest pid=13090 prio=9 target_cpu=001
sigwaitt-13091   1d..21  1741.963617: sched_wakeup:         sigwaittest:13090 [9] success=1 CPU:001
sigwaitt-13091   1....1  1741.963618: signal_generate:      sig=10 errno=0 code=-6 comm=sigwaittest pid=13090 grp=0 res=0
=====chensong:70us
sigwaitt-13091   1d..21  1741.963689: sched_waking:         comm=sigwaittest pid=13089 prio=120 target_cpu=041
sigwaitt-13091   1d..31  1741.963690: sched_wakeup:         sigwaittest:13089 [120] success=1 CPU:041
=====
sigwaitt-13091   1....0  1741.963691: kfree:                (__audit_syscall_exit+0x1d8) call_site=ffff0000081d26b0 ptr=(nil)
sigwaitt-13091   1....0  1741.963691: sys_exit:             NR 131 = 0
sigwaitt-13091   1...10  1741.963692: sys_exit_tgkill:      0x0

对比正常时候的日志:

sigwaitt-13091   1....0  1741.962569: sys_enter:            NR 131 (3321, 3322, a, 20c49ba5e353f7cf, 3b9ac9ff, 44cc0)
sigwaitt-13091   1...10  1741.962570: sys_enter_tgkill:     tgid: 0x00003321, pid: 0x00003322, sig: 0x0000000a
sigwaitt-13091   1d..11  1741.962571: sched_waking:         comm=sigwaittest pid=13090 prio=9 target_cpu=001
sigwaitt-13091   1d..21  1741.962572: sched_wakeup:         sigwaittest:13090 [9] success=1 CPU:001
sigwaitt-13091   1....1  1741.962573: signal_generate:      sig=10 errno=0 code=-6 comm=sigwaittest pid=13090 grp=0 res=0
sigwaitt-13091   1....0  1741.962574: kfree:                (__audit_syscall_exit+0x1d8) call_site=ffff0000081d26b0 ptr=(nil)
sigwaitt-13091   1....0  1741.962574: sys_exit:             NR 131 = 0
sigwaitt-13091   1...10  1741.962574: sys_exit_tgkill:      0x0
sigwaitt-13091   1....0  1741.962575: sys_enter:            NR 137 (fffdf677e848, fffdf677e6b8, 0, 8, 0, fffdf677f0e0)
sigwaitt-13091   1...10  1741.962575: sys_enter_rt_sigtimedwait: uthese: 0xfffdf677e848, uinfo: 0xfffdf677e6b8, uts: 0x00000000, sigsetsize: 0x00000008
sigwaitt-13091   1d..10  1741.962576: rcu_utilization:      Start context switch
sigwaitt-13091   1d..10  1741.962577: rcu_utilization:      End context switch
sigwaitt-13091   1d..20  1741.962578: sched_switch:         sigwaittest:13091 [9] S ==> sigwaittest:13090 [9]

我们会发现,在signal_generate后,sigwaittest的测试线程又唤醒了一个线程,消耗了70us。

2)过程分析

命令“sigwaittest -p 90 -i 1000 -a 1 -b 80”会创建三个线程,一个主线程main thread,,是一个CFS的普通线程,很大一部分工作是打印测试的结果,一个是sender,是一个实时线程,负责发送信号,还有一个是receiver,负责接收信号,sigwaittest主要就是测试sender发送信号到receiver接收到信号所花费的时间。

3)代码分析

首先看一下发送信号的kill函数,对应内核中系统调用tgkill:

使用function_grath来看一下tgkill的调用过程:trace-cmd start -p function_graph -g sys_tgkill;sigwaittest -p 90 -i 1000 -a 1 -l 100;trace-cmd stop

# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |1)               |  sys_tgkill() {1)               |    do_tkill() {1)               |      __task_pid_nr_ns() {1)   0.770 us    |        __rcu_read_lock();1)   0.500 us    |        __rcu_read_unlock();1)   3.062 us    |      }1)               |      from_kuid_munged() {1)   0.500 us    |        map_id_up();1)   1.563 us    |      }1)               |      do_send_specific() {1)   0.479 us    |        __rcu_read_lock();1)   0.666 us    |        find_task_by_vpid();1)               |        __task_pid_nr_ns() {1)   0.500 us    |          __rcu_read_lock();1)   0.479 us    |          __rcu_read_unlock();1)   2.542 us    |        }1)               |        check_kill_permission() {1)               |          audit_signal_info() {1)               |            auditd_test_task() {1)   0.500 us    |              __rcu_read_lock();1)   0.479 us    |              __rcu_read_unlock();1)   2.604 us    |            }1)               |            audit_signal_info_syscall() {1)   0.500 us    |              __rcu_read_lock();1)   0.500 us    |              __rcu_read_unlock();1)   2.458 us    |            }1)   7.042 us    |          }1)   0.604 us    |          security_task_kill();1)   9.271 us    |        }1)               |        do_send_sig_info() {1)               |          __lock_task_sighand() {1)   0.500 us    |            __rcu_read_lock();1)               |            rt_spin_lock() {1)   0.500 us    |              __rcu_read_lock();1)   0.500 us    |              migrate_disable();1)   2.480 us    |            }1)   0.500 us    |            __rcu_read_unlock();1)   5.459 us    |          }1)               |          send_signal() {1)   0.563 us    |            siginfo_layout();1)   0.479 us    |            __rcu_read_lock();1)   0.500 us    |            __rcu_read_lock();1)   0.500 us    |            __rcu_read_unlock();1)   0.500 us    |            __rcu_read_unlock();1)   0.563 us    |            task_active_pid_ns();1)               |            __task_pid_nr_ns() {1)   0.500 us    |              __rcu_read_lock();1)   0.480 us    |              __rcu_read_unlock();1)   2.479 us    |            }1)               |            __send_signal() {1)   0.583 us    |              prepare_signal();1)               |              __sigqueue_do_alloc() {1)   0.563 us    |                __rcu_read_lock();1)   0.480 us    |                __rcu_read_unlock();1)               |                kmem_cache_alloc() {1)   0.479 us    |                  should_failslab();1)   1.708 us    |                }1)   4.833 us    |              }1)               |              complete_signal() {1)   0.604 us    |                _raw_spin_lock_irqsave();1)   0.500 us    |                _raw_spin_unlock_irqrestore();1)               |                signal_wake_up_state() {1)               |                  wake_up_state() {1)               |                    try_to_wake_up() {1)   0.562 us    |                      _raw_spin_lock_irqsave();1)   0.542 us    |                      _raw_spin_lock();1)   0.541 us    |                      update_rq_clock();1)               |                      ttwu_do_activate() {1)               |                        activate_task() {1)               |                          enqueue_task_rt() {1)               |                            dequeue_rt_stack() {1)   0.521 us    |                              dequeue_top_rt_rq();1)   1.521 us    |                            }1)   0.500 us    |                            update_rt_migration();1)   0.500 us    |                            _raw_spin_lock();1)   0.521 us    |                            enqueue_top_rt_rq();1)   5.604 us    |                          }1)   6.958 us    |                        }1)               |                        ttwu_do_wakeup() {1)               |                          check_preempt_curr() {1)   0.625 us    |                            check_preempt_curr_rt();1)   1.625 us    |                          }1)   0.521 us    |                          task_woken_rt();1)   4.605 us    |                        }1) + 13.084 us   |                      }1)   0.541 us    |                      _raw_spin_unlock_irqrestore();1) + 19.104 us   |                    }1) + 20.146 us   |                  }1) + 21.188 us   |                }1) + 24.542 us   |              }1) + 32.709 us   |            }1) + 42.792 us   |          }1)               |          rt_spin_unlock() {1)   0.563 us    |            migrate_enable();1)   0.521 us    |            __rcu_read_unlock();1)   2.750 us    |          }1) + 53.271 us   |        }1)   0.541 us    |        __rcu_read_unlock();1) + 70.500 us   |      }1) + 77.562 us   |    }1) + 81.333 us   |  }------------------------------------------1) sigwait-31931  => sigwait-31930 ------------------------------------------

简化一下调用过程就是:

tgkill--> do_tkill-->do_send_specific-->do_send_sig_info--> lock_task_sighand //申请锁tsk->sighand->siglocksend_signal //唤醒receiverunlock_task_sighand(p, &flags); //释放tsk->sighand->siglock

在通常情况下,sender调用send_signal唤醒receiver,这个过程就结束了。但在发生错误的日志中,我们发现sender还唤醒了main thread,那么,很可能main thread也在申请tsk->sighand->siglock,这个时候它正在siglock的等待队列中等待,那么,当sender调用unlock_task_sighand的时候,就会去唤醒main thread。

我们再来看看main thread的代码:

26     while (!mustshutdown) {
527         int printed;
528         int errorlines = 0;
529 
530         for (i = 0; i < num_threads; i++)
531             mustshutdown |= receiver[i].shutdown |
532                 sender[i].shutdown;
533 
534         if (receiver[0].samples > oldsamples || mustshutdown) {...//打印结果581         pthread_sigmask(SIG_SETMASK, &sigset, NULL);
582 
583         nanosleep(&maindelay, NULL);
584 
585         sigemptyset(&sigset);
586         pthread_sigmask(SIG_SETMASK, &sigset, NULL);}其中pthread_sigmask(SIG_SETMASK, &sigset, NULL)会进入内核调用:
2870 int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
2871 {
2872     struct task_struct *tsk = current;
2873     sigset_t newset;
2874 
2875     /* Lockless, only current can change ->blocked, never from irq */
2876     if (oldset)
2877         *oldset = tsk->blocked;
2878 
2879     switch (how) {
2880     case SIG_BLOCK:
2881         sigorsets(&newset, &tsk->blocked, set);
2882         break;
2883     case SIG_UNBLOCK:
2884         sigandnsets(&newset, &tsk->blocked, set);
2885         break;
2886     case SIG_SETMASK:
2887         newset = *set;
2888         break;
2889     default:
2890         return -EINVAL;
2891     }
2892 
2893     __set_current_blocked(&newset);
2894     return 0;
2895 }
在函数 __set_current_blocked(&newset)中,也需要申请tsk->sighand->siglock
2846 void __set_current_blocked(const sigset_t *newset)
2847 {
2848     struct task_struct *tsk = current;
2849 
2850     /*
2851      * In case the signal mask hasn't changed, there is nothing we need
2852      * to do. The current->blocked shouldn't be modified by other task.
2853      */
2854     if (sigequalsets(&tsk->blocked, newset))
2855         return;
2856 
2857     spin_lock_irq(&tsk->sighand->siglock);
2858     __set_task_blocked(tsk, newset);
2859     spin_unlock_irq(&tsk->sighand->siglock);
2860 }

所形成的关系大概是这样

sender                                          main threadlock_task_sighandsend_signal(sig, info, p, type)         spin_lock_irq(&tsk->sighand->siglock) //被阻塞unlock_task_sighand(p, &flags)           获取锁,继续调用sigprocmask其他的事情 __set_task_blocked(tsk, newset); spin_unlock_irq(&tsk->sighand->siglock);//释放锁      

本来这个锁的释放,唤醒进程都是很简短的过程,通常都是几微秒,为什么这个设备上会出现70us的问题呢,我们看sender和receiver都运行在CPU1上,而main thread是运行在CPU41上,是不是不在一个numa node上,对远端的内存访问会消耗很长时间?

3, 解决方案:将main thread与sender,receiver放到同一个node上

taskset -c 2 ./sigwaittest -p 90 -i 1000 -a 1 -b 80  //不再重现

如果将main thread强制放在CPU41上呢:

taskset -c 41 ./sigwaittest -p 90 -i 1000 -a 1 -b 80 // 很快重现

相关文章:

sigwaittest测试超标的调试过程

1&#xff0c;问题描述硬件环境&#xff1a;飞腾S2500&#xff08;64核&#xff09;OS&#xff1a;kylinOS, linux preempt rt&#xff0c; 4.19.90测试命令&#xff1a;sigwaittest -p 90 -i 1000 -a 1测试结果&#xff1a;信号混洗值最大超过了80us&#xff0c;与飞腾其他CPU…...

Python进阶-----面对对象4.0(面对对象三大特征之--继承)

目录 前言&#xff1a; Python的继承简介 1.什么是继承 2.继承的好处 3.object类 继承的相关用法 1.继承的定义与法则 2.对继承的重写 3.&#xff08;单继承&#xff09;多层继承 4.多继承 5.多继承重写时调用父类方法 前言&#xff1a; 在讲之前&#xff0c;我想说说中…...

九龙证券|利好政策密集发布,机构扎堆看好的高增长公司曝光

新能源轿车销量和保有量快速增长&#xff0c;带来了充电桩商场的微弱需求。 日前&#xff0c;商务部部长王文涛表明&#xff0c;本年将在落实好方针的一起&#xff0c;活跃出台新方针办法&#xff0c;比方辅导当地展开新能源轿车下乡活动&#xff0c;优化充电等使用环境&#x…...

stm32CubeIDE FMC 驱动LCD(8080)

一&#xff0c;TFT屏硬件接口16位&#xff0c;80并口。二&#xff0c;FMC介绍。FSMC&#xff08;Flexible Static Memory Controller&#xff09;&#xff0c;译为灵活的静态存储控制器。STM32F1 系列芯片使用 FSMC 外设来管理扩展的存储器&#xff0c;它可以用于驱动包括 SRAM…...

Java 数据类型

数据类型用于对数据归类&#xff0c;以便开发者理解和操作。 基本数据类型 Java 确定了每种基本数据类型所占存储空间的大小&#xff0c;不会像其它语言那样随机器硬件架构的变化而变化&#xff0c;这使 Java 程序更具可移植性。 Java 中定义了如下的基本数据类型。 byte …...

Prometheus 监控云Mysql和自建Mysql(多实例)

本文您将了解到 Prometheus如何配置才能监控云Mysql(包括阿里云、腾讯云、华为云)和自建Mysql。 Prometheus 提供了很多种Exporter&#xff0c;用于监控第三方系统指标&#xff0c;如果没有提供也可以根据Exporter规范自定义Exporter。 本文将通过MySQL server exporter 来监控…...

Vue3中的h函数

文章目录简介简单使用参数使用计数器进阶使用函数组件插槽专栏目录请点击 简介 众所周知&#xff0c;vue内部构建的其实是虚拟DOM&#xff0c;而虚拟DOM是由虚拟节点生成的&#xff0c;实质上虚拟节点也就是一个js对象事实上&#xff0c;我们在vue中写的template,最终也是经过…...

阿尔法开发板 IMX6ULL 说明

一. IMX6ULL开发板 IMX6ULL开发板即正点原子的阿尔法(ALPHA)开发板&#xff0c;采用恩智浦芯片&#xff0c;cortex-A7架构的。 二. IM6ULL开发板说明 1. IO说明 对于IMX6ULL芯片&#xff0c;一个IO对应两个寄存器&#xff0c;第一个寄存器负责配置其复用功能&#xff0c;…...

Altium Designer19 #学习笔记# | 基础应用技巧汇总

全文目录一.元件符号库二.元件封装库1.AD09 集成元件库/封装库三.电路原理图1. 巧用查找"相似对象功能"1.1 查找相同元件1.2. 查找相同文本1.3. 查找相同网络 &#xff1a;E - S - C四.PCB原理图【AD PCB模式下的常用快捷键】PCB视图放大/缩小PCB视图左/右移动PCB切换…...

Python 元类编程实现一个简单的 ORM

概述 什么是ORM?    ORM全称“Object Relational Mapping”&#xff0c;即对象-关系映射&#xff0c;就是把关系数据库的一行映射为一个对象&#xff0c;也就是一个类对应一个表&#xff0c;这样&#xff0c;写代码更简单&#xff0c;不用直接操作SQL语句。 现在我们就要实…...

《C++ Primer Plus》第18章:探讨 C++ 新标准(7)

C11 新增的其他功能 C11 增加了很多功能&#xff0c;本书无法全面介绍&#xff1b;另外&#xff0c;本书编写期间&#xff0c;其中很多功能还未得到广泛实现。然而&#xff0c;有些功能有必要简要地介绍一下。 并行编程 当前&#xff0c;为提高计算机性能&#xff0c;增加处…...

Redis学习(二):Redis安装测试

概述 Redis是什么 Redis, Remote Dictionary Server, 即远程字典服务。免费开源的数据库。 由C语言编写&#xff0c;支持网络&#xff0c;可基于内存亦可持久化的日志型、KV数据库&#xff0c;并提供所种语言的API。 Redis能干嘛 用于内存存储&#xff0c;持久化。rdb、ao…...

Vector - CAPL - 简介及数据结构

对于想进入车载行业或者已经在车载行业工作的朋友对于CAPL这个词都会相当的熟悉&#xff0c;都知道他是做车载网络测试脚本的语言&#xff0c;并且跟C有点类似&#xff0c;但是它到底是什么呢&#xff1f;CAPL全称&#xff08;Communication Access Programming Language&#…...

20230304英语学习

What Would Happen if the Moon Disappeared Tomorrow? 如果明天月球消失了会怎样&#xff1f; The closest object to our planet, the Moon, may seem like Earth’s little sibling.Since its birth, the satellite has mostly just hung around, playing gravitational t…...

【基础算法】单链表的OJ练习(3) # 移除链表元素 # 相交链表 #

文章目录前言移除链表元素相交链表写在最后前言 本章的OJ练习也是相对简单的&#xff0c;只要能够理解解题的思路&#xff0c;并且依照这个思路能够快速的写出代码&#xff0c;我相信&#xff0c;你的链表水平已经足够了。 对于OJ练习&#xff08;2&#xff09; : ->传送门…...

【自用】SpringBoot项目通用类整理

文章目录全局Json序列化Controller日志切面全局异常拦截GlobalExceptionHandlerApiResultBusinessExceptionResponseEntityUtil全局返回体包装MP自动填充接口文档配置类自定义Async异步线程池本文主要整理各类项目中通用的配置类、工具类&#xff0c;便于复查自用。 全局Json序…...

动态规划法(总述)多阶段决策最优化问题

动态规划: 研究最优控制问题提出的 该问题有n个输入&#xff0c;问题的解由这n个输入组成&#xff0c;这个子集必须满足事先给定的条件&#xff0c;这些条件称为约束条件&#xff0c;满足约束条件的可行解可能不只有一个为了衡量可行解的优劣&#xff0c;通常以一些函数的形式&…...

MySQL跨服务器数据映射

MySQL跨服务器数据映射环境准备1. 首先是要查看数据库的federated引擎 开启/关闭 状态2. 打开任务管理器&#xff0c;并重启mysql服务3. 再次查看FEDERATED引擎状态&#xff0c;引擎已启动映射实现问题总结在日常的开发中经常进行跨数据库进行查询数据。 同服务器下跨数据库进…...

利用反射实现通过读取配置文件对类进行实例化-课后程序(JAVA基础案例教程-黑马程序员编著-第十二章-课后作业)

【案例12-3】&#xff1a;利用反射实现通过读取配置文件对类进行实例化 【案例介绍】 1.案例描述 现在有一个项目&#xff0c;项目中创建了一个Person类&#xff0c;在Person类中定义了一个sleep()方法。在工程中还定义了一个Student类继承Person类&#xff0c;在Student类中…...

1.2 CSS文本属性

CSS Text(文本)属性&#xff1a; 定义文本外观&#xff0c;颜色&#xff0c;装饰&#xff0c;缩进&#xff0c;行间距来修饰文本 文本样式 文本缩进 text-indent文本水平对齐方式&#xff1a;text-align文本修饰&#xff1a;text-decoration行高 line-height CSS文本颜色属性…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...