精华内容
下载资源
问答
  • irq 默认linux自动启动的,但是往往它自己控制不是很好(CPU SI经常某个CPU占用大)通常碰到大流量的,通常我们会把自动启动的irqblance关闭,然后手动指定一下IRQ进行优化:看CPU的 si利用率: 看设备的ID号: 配置...

    irq 默认linux自动启动的,但是往往它自己控制不是很好(CPU SI经常某个CPU占用大)

    通常碰到大流量的,通常我们会把自动启动的irqblance关闭,然后手动指定一下IRQ进行优化:

    看CPU的 si利用率:

    54f92bb8ac3a3079d164819c10a47fe8.png

    看设备的ID号:

    7a87bf7e638b67ca0768f6fda74dde75.png

    配置指定的CPU: (1表示第1个,2表示第2个,4表示第4个,8表示第4个,这是16进制化2进制,显示的数值是16进制的)

    3210cf6e297ba9fc71c65e66dc5c99ab.png

    例子:我本机是8核心的。。。。我的操作是。。。。

    /etc/init.d/irqbalance stop

    echo 1 > /proc/irq/59/smp_affinity

    echo 2 > /proc/irq/60/smp_affinity

    echo 4 > /proc/irq/61/smp_affinity

    echo 8 > /proc/irq/62/smp_affinity

    echo 10 > /proc/irq/63/smp_affinity

    echo 20 > /proc/irq/64/smp_affinity

    echo 40 > /proc/irq/65/smp_affinity

    echo 80 > /proc/irq/66/smp_affinity

    展开全文
  • 其实除了 iowait,软中断(softirq)CPU 使用率升高也是最常见的一种性能问题。 1. 从“外卖”看中断 说到中断,我在前面关于“上下文切换”的文章,简单说过中断的含义,先来回顾一下。中断是系统用来响应硬件...

    怎么理解linux中断

        其实除了 iowait,软中断(softirqCPU 使用率升高也是最常见的一种性能问题。

    1. 从“外卖”看中断

        说到中断,我在前面关于上下文切换的文章,简单说过中断的含义,先来回顾一下。中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来响应设备的请求。

        你可能要问了,为什么要有中断呢?我可以举个生活中的例子,让你感受一下中断的魅力。

        比如说你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了。所以你只能苦苦等着,时不时去门口看看外卖送到没,而不能干其他事情。

        不过呢,如果在订外卖的时候,你就跟配送员约定好,让他送到后给你打个电话,那你就不用苦苦等待了,就可以去忙别的事情,直到电话一响,接电话、取外卖就可以了。这里的打电话,其实就是一个中断。没接到电话的时候,你可以做其他的事情;只有接到了电话(也就是发生中断),你才要进行另一个动作:取外卖。

        这个例子你就可以发现,中断其实是一种异步的事件处理机制,可以提高系统的并发处理能力

        由于中断处理程序会打断其他进程的运行,所以,为了减少对正常进程运行调度的影响,中断处理程序就需要尽可能快地运行。但如果中断要处理的事情很多,中断服务程序就有可能要运行很长时间。特别是,中断处理程序在响应中断时,还会临时关闭中断。这就会导致上一次中断处理完成之前,其他中断都不能响应,也就是说中断有可能会丢失

        那么还是以取外卖为例。假如你订了 2 份外卖,一份主食和一份饮料,并且是由 2 个不同的配送员来配送。这次你不用时时等待着,两份外卖都约定了电话取外卖的方式。但是,问题又来了。当第一份外卖送到时,配送员给你打了个长长的电话,商量发票的处理方式。与此同时,第二个配送员也到了,也想给你打电话。但是很明显,因为电话占线(也就是关闭了中断响应),第二个配送员的电话是打不通的。所以,第二个配送员很可能试几次后就走掉了(也就是丢失了一次中断)。

     

    2. 硬中断/软中断

        如果你弄清楚了取外卖的模式,那对系统的中断机制就很容易理解了。事实上,为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:

    1. 上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。
    2. 下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行。

        除了取外卖,我再举个最常见的网卡接收数据包的例子,让你更好地理解。

        网卡接收到数据包后,会通过硬件中断的方式,通知内核有新的数据到了。这时,内核就应该调用中断处理程序来响应它。你可以自己先想一下,这种情况下的上半部和下半部分别负责什么工作呢?

        对上半部来说既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个软中断信号,通知下半部做进一步的处理。而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。

        所以,这两个阶段你也可以这样理解:

    1. 上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
    2. 而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行

        不过要注意的是,软中断不只包括了刚刚所讲的硬件设备中断处理程序的下半部,一些内核自定义的事件也属于软中断,比如内核调度和 RCU 锁(Read-Copy Update 的缩写,RCU Linux 内核中最常用的锁之一)等。

     

    3. 查看软中断和内核线程

        不知道你还记不记得,前面提到过的 proc 文件系统。它是一种内核空间和用户空间进行通信的机制,可以用来查看内核的数据结构,或者用来动态修改内核的配置。其中:/proc/softirqs 提供了软中断的运行情况;/proc/interrupts 提供了硬中断的运行情况。运行下面的命令,查看 /proc/softirqs 文件的内容,你就可以看到各种类型软中断在不同 CPU 上的累积运行次数:

        在查看 /proc/softirqs 文件内容时,你要特别注意以下这两点。

        第一,要注意软中断的类型,也就是这个界面中第一列的内容。从第一列你可以看到,软中断包括了网络收发、定时、调度、RCU 锁等 10 个类别。比如。TIMER(定时中断)、NET_RX (网络接收中断)、NET_TX (网络发送中断)、SCHED(内核调度)、RCURCU 锁)、SCHED(非自愿上下文切换)等

        第二,要注意同一种软中断在不同 CPU 上的分布情况,也就是同一行的内容。正常情况下,同一种中断在不同 CPU 上的累积次数应该差不多。比如这个界面中,NET_RX CPU0 CPU1 上的中断次数基本是同一个数量级,相差不大。

        不过你可能发现,TASKLET 在不同 CPU 上的分布并不均匀。TASKLET 是最常用的软中断实现机制,每个 TASKLET 只运行一次就会结束 ,并且只在调用它的函数所在的 CPU 上运行。

        因此,使用 TASKLET 特别简便,当然也会存在一些问题,比如说由于只在一个 CPU 上运行导致的调度不均衡,再比如因为不能在多个 CPU 上并行运行带来了性能限制。

        另外,刚刚提到过,软中断实际上是以内核线程的方式运行的,每个 CPU 都对应一个软中断内核线程,这个软中断内核线程就叫做 ksoftirqd/CPU 编号。那要怎么查看这些线程的运行状况呢?

        其实用 ps 命令就可以做到,比如执行下面的指令:

        注意,这些线程的名字外面都有中括号,这说明 ps 无法获取它们的命令行参数(cmline)。一般来说,ps 的输出中,名字括在中括号里的,一般都是内核线程。

     

    4. 案例分析

        现在我们再回到第一个终端,你应该发现了异常。是不是感觉系统响应明显变慢了,即便只是在终端中敲几个回车,都得很久才能得到响应?这个时候应该怎么办呢?

        那么,该从什么地方入手呢?先看看系统的整体资源使用情况应该是个不错的注意,比如执行下 top 看看是不是出现了 CPU 的瓶颈。我们在第一个终端运行 top 命令,看一下系统整体的资源使用情况。

        这里你有没有发现异常的现象?我们从第一行开始,逐个看一下:

    1. 平均负载全是 0,就绪队列里面只有一个进程(1 running)。
    2. 每个 CPU 的使用率都挺低,最高的 CPU1 的使用率也只有 4.4%
    3. 再看进程列表,CPU 使用率最高的进程也只有 0.3%,还是不高呀。

        仔细看 top 的输出,两个 CPU 的使用率虽然分别只有 3.3% 4.4%,但都用在了软中断上;而从进程列表上也可以看到,CPU 使用率最高的也是软中断进程 ksoftirqd。看起来,软中断有点可疑了

        根据上一期的内容,既然软中断可能有问题,那你先要知道,究竟是哪类软中断的问题。停下来想想,上一节我们用了什么方法,来判断软中断类型呢?没错,还是 proc 文件系统。观察 /proc/softirqs 文件的内容,你就能知道各种软中断类型的次数。

        不过,这里的各类软中断次数,又是什么时间段里的次数呢?而所以我们直接查看文件内容,得到的只是累积中断次数,对这里的问题并没有直接参考意义。因为,这些中断次数的变化速率才是我们需要关注的

        执行下列命令:

        其中,NET_RX,也就是网络数据包接收软中断的变化速率最快。而其他几种类型的软中断,是保证 Linux 调度、时钟和临界区保护这些正常工作所必需的,所以它们有一定的变化倒是正常的。

       那么接下来,我们就从网络接收的软中断着手,继续分析。既然是网络接收的软中断,第一步应该就是观察系统的网络接收情况。这里你可能想起了很多网络工具,不过,我推荐今天的主人公工具 sar

       sar 可以用来查看系统的网络收发情况,还有一个好处是,不仅可以观察网络收发的吞吐量(BPS,每秒收发的字节数),还可以观察网络收发的 PPS,即每秒收发的网络帧数。

       我们在第一个终端中运行 sar 命令,并添加 -n DEV 参数显示网络收发的报告:

        对于 sar 的输出界面,我先来简单介绍一下,从左往右依次是:

    1. 第一列:表示报告的时间。
    2. 第二列:IFACE 表示网卡。
    3. 第三、四列:rxpck/s txpck/s 分别表示每秒接收、发送的网络帧数,也就是 PPS
    4. 第五、六列:rxkB/s txkB/s 分别表示每秒接收、发送的千字节数,也就是 BPS。后面的其他参数基本接近 0,显然跟今天的问题没有直接关系,你可以先忽略掉。

        我们具体来看输出的内容,你可以发现:

    1. 对网卡 eth0 来说,每秒接收的网络帧数比较大,达到了 12607,而发送的网络帧数则比较小,只有 6304;每秒接收的千字节数只有 664 KB,而发送的千字节数更小,只有 358 KB
    2. docker0 veth9f6bbcd 的数据跟 eth0 基本一致,只是发送和接收相反,发送的数据较大而接收的数据较小。这是 Linux 内部网桥转发导致的,你暂且不用深究,只要知道这是系统把 eth0 收到的包转发给 Nginx 服务即可。具体工作原理,我会在后面的网络部分详细介绍。

        从这些数据,你有没有发现什么异常的地方?

        既然怀疑是网络接收中断的问题,我们还是重点来看 eth0 :接收的 PPS 比较大,达到 12607,而接收的 BPS 却很小,只有 664 KB。直观来看网络帧应该都是比较小的,我们稍微计算一下,664*1024/12607 = 54 字节,说明平均每个网络帧只有 54 字节,这显然是很小的网络帧,也就是我们通常所说的小包问题。

        通过使用 tcpdump 抓取 eth0 上的包就可以了。我们事先已经知道, Nginx 监听在 80 端口,它所提供的 HTTP 服务是基于 TCP 协议的,所以我们可以指定 TCP 协议和 80 端口精确抓包。

        注:Flags [S] 则表示这是一个 SYN 包。

        再加上前面用 sar 发现的, PPS 超过 12000 的现象,现在我们可以确认,这就是从 192.168.0.2 这个地址发送过来的 SYN FLOOD 攻击。

        到这里,我们已经做了全套的性能诊断和分析。从系统的软中断使用率高这个现象出发,通过观察 /proc/softirqs 文件的变化情况,判断出软中断类型是网络接收中断;再通过 sar tcpdump ,确认这是一个 SYN FLOOD 问题。

    展开全文
  • linux内核模块中 软中断例子

    千次阅读 2010-05-22 18:38:00
    直接上例子吧。只是捕获某个设备的中断而已。。。 该文件的名字是irq.c #include #include #include #include #include #define DEBUG#ifdef DEBUG#define MSG(message, args...) printk(KERN_DEBUG "irq:" ...

    直接上例子吧。只是捕获某个设备的中断而已。。。

     

    该文件的名字是irq.c

     

     

    对应的makefile的内容是

     

     

    我的当前内核版本为:2.6.27.5-117.fc10.i686

    执行步骤:

    1:首先make一下生成irq.ko

    2:查看 cat /proc/interrupts

     

    我的打印结果是:

     

     

    这个19就是我需要使用的中断号,eth0其实就是网卡(第一块,我也就这么一块)。。。

     

    然后我使用插入内核模块的命令是:

    2.1:insmod irq.ko interface=eth1 irq=19

     

    如果没有报任何信息就是插入正确了,

     

    接着

    2.2:输入 dmesg 回车。。就会看到如下截图的信息了。。就是我们程序中打印的信息。。

     

    好了这就是算成功了。。。

     

    2.3:原理就是,,注册了一个捕获中断号为19的程序。。。然后当发出19的中断号的设备发出中断时。。我程序捕获一下。。。

     

     

    3:最后使用命令 cat /proc/interrupts 查看一下刚才的变化

     

     

     

    那个19的记录后面是不是多出了个eth1?这个eth1就是刚才insmod irq.ko interface=eth1 irq=19 命令中的eth1哈 咱们设备的名字。。。ok了。。。

     

    算是入门了。。

     

     

     

     

    展开全文
  • linux内核模块中 软中断例子

    千次阅读 2011-06-27 20:18:00
     // 注册中断捕获,第三个参数的意思是和其他设备共享该中断号,最后一个参数是设备的id,其实对于共享下的设备这个号码据说是随便写,一般都写irq的了。   //只要注册成功就可以等待对应设备的该中断号的到来 就...

    该文件的名字是irq.c


    1. #include <linux/module.h>   
    2. #include <linux/kernel.h>   
    3. #include <linux/init.h>   
    4. #include <linux/interrupt.h>   
    5. #include <linux/timer.h>   
      #define DEBUG  
       
      #ifdef DEBUG  
      #define MSG(message, args...) printk(KERN_DEBUG "irq:" message, ##args)  
      #else  
      #define MSG(message, args...)  
      #endif  
       
      MODULE_LICENSE("GPL");  
      MODULE_AUTHOR("silence1214");  
       
      int irq;  
      char *interface;  
       
      // 下面这2个参数通过插入内核模块的时候赋值的...  
      module_param(irq, int, 0644);  
      module_param(interface, charp, 0644);  
       
      // 中断捕获的时候的处理函数  
      int irq_handle_function(int irq, void *device_id)  
      {  
          static int count = 1;  
          MSG("[%d]receive the irq at %ld.../n", count, jiffies);  
          count++;  
          return IRQ_NONE;  
      }  
       
      int init_module()  
      {  
          // 注册中断捕获,第三个参数的意思是和其他设备共享该中断号,最后一个参数是设备的id,其实对于共享下的设备这个号码据说是随便写,一般都写irq的了。  
          //只要注册成功就可以等待对应设备的该中断号的到来 就可以处理回调函数了。。  
          if(request_irq(irq, irq_handle_function, IRQF_SHARED, interface, (void *)&irq))  
          {  
              MSG("regist irq failure.../n");  
              return -EIO;  
          }  
          MSG("interface=%s and irq=%d.../n", interface, irq);  
          MSG("regist irq success.../n");  
          return 0;  
      }  
       
      void cleanup_module()  
      {  
          free_irq(irq, &irq);  
          MSG("unregist irq.../n");  

    对应的makefile的内容是

    view plaincopy to clipboardprint?
    obj-m:=irq.o  
     
    default:  
        make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules 
    obj-m:=irq.o

    default:
     make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules

    我的当前内核版本为:2.6.27.5-117.fc10.i686

    执行步骤:

    1:首先make一下生成irq.ko

    2:查看 cat /proc/interrupts

    我的打印结果是:

     

    这个19就是我需要使用的中断号,eth0其实就是网卡(第一块,我也就这么一块)。。。

    然后我使用插入内核模块的命令是:

    2.1:insmod irq.ko interface=eth1 irq=19

    如果没有报任何信息就是插入正确了,

    接着

    2.2:输入 dmesg 回车。。就会看到如下截图的信息了。。就是我们程序中打印的信息。。

     

    好了这就是算成功了。。。

    2.3:原理就是,,注册了一个捕获中断号为19的程序。。。然后当发出19的中断号的设备发出中断时。。我程序捕获一下。。。

    3:最后使用命令 cat /proc/interrupts 查看一下刚才的变化

     

    那个19的记录后面是不是多出了个eth1?这个eth1就是刚才insmod irq.ko interface=eth1 irq=19 命令中的eth1哈 咱们设备的名字。。。ok了。。。

    算是入门了。。

     

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/silence1214/archive/2010/05/22/5616782.aspx

    展开全文
  • 举个生活中的例子,让你感受一下中断的魅力。比如说你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了。所以你只能...
  • 为了解决中断处理程序执行过长和中断丢失的问题,Linux中断处理过程分成了两个阶段,也就是上半部和下半部: 上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。 下...
  • irq 默认linux自动启动的,但是往往它自己控制不是很好(CPU SI经常某个CPU占用大)通常碰到大流量的,通常我们会把自动启动的irqblance关闭,然后手动指定一下IRQ进行优化:看CPU的 si利用率: 看设备的ID号: 配置...
  • irq 默认linux自动启动的,但是往往它自己控制不是很好(CPU SI经常某个CPU占用大)通常碰到大流量的,通常我们会把自动启动的irqblance关闭,然后手动指定一下IRQ进行优化:看CPU的 si利用率: 看设备的ID号: 配置...
  • 1. 注册软中断当然是通过open_softirq 例子如下: void __init init_timers(void) { int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, ...
  • irq 默认linux自动启动的,但是往往它自己控制不是很好(CPU SI经常某个CPU占用大)通常碰到大流量的,通常我们会把自动启动的irqblance关闭,然后手动指定一下IRQ进行优化:看CPU的 si利用率:看设备的ID号:配置...
  • Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,可以通过查看 /proc/softirqs 来观察软中断的运行情况。 网卡接收数据包的例子,让你更好地理解。网卡接收到数据包后,会通过硬件中断的方式,通知...
  • 软中断/tasklet/工作队列

    千次阅读 2010-07-12 15:26:00
    软中断、tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的“下半部”(bottom half)演变而来。下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只...
  • linux内核研究-3-中断

    千次阅读 2012-04-05 09:06:57
    上一节说到的系统调用使用的内核陷入就是异常(软中断)。 2》中断的实现需要硬件的支持,比如要让硬件工程师把设备的某个引脚连接到CPU的跟中断相关的某个引脚。 3》中断比较特殊,不能占用太多时间,所以有必要
  • 本文介绍一个例子linux软中断是谁触发谁执行,这有点各司其职的意思,可是到了触发软中断的时候往往已经丢失触发这个“触发软中断”事件的源头,因此这种各司其职不是那么完善,于是2.6.28在bio的完成通知中完善了...
  • linux信号

    2019-09-27 22:03:32
    软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一的异步...
  • 想到linus当年在写下系统函数调用时,其实基于的思想是一样的,就是查表,每一种系统函数都对应一种中断服务号,然后通过0x80系统调用进入内核,然后查表,这里就可以找到对应的内核系统函数,回顾一下linus是怎么...
  • linux之信号量

    2019-01-30 20:52:50
    信号:相当于软中断 信号量:调协进程对共享资源的访问,让一个临界区同一时间只有一个线程在访问它,为什么要引入信号量呢?举个例子,有两个进程要使用打印机,但是没有保证在同一时刻只有一个进程使用打印机,那...
  • arm linux 系统调用过程

    千次阅读 2018-08-16 16:57:35
    Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的。 t8.c 1: #include &lt;stdio.h&gt; 2: #include &lt;sys/types.h&gt...
  • Linux信号处理

    千次阅读 2015-07-04 14:09:57
    信号(signal)是软中断。信号提供了一种处理异步事件的方式。当各种各样的事件发生时,程序相应的会收到各种各样的信号。对于大部分信号,程序可以自行决定如何处理他们。 程序在什么情况下会收到信号,下面是...
  • irq),当然少不了对中断的处理,常用的中断处理方法有tasklet,工作队列以及软中断,其中tasklet和工作队列的使用法方类似,定义一个结构和一个处理函数,然后将结构与处理函数联系起来就可以了,下面通过2个例子说明...
  • Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的。在glibc库中,通过封装例程(Wrapper Routine)将API和系统调用关联起来。API是头文件中所...
  • linux 内核线程概念的简单表述:内核采用一致的数据结构收集和处理用户进程线程的信息,内核线程依托于这些内核数据结构并依此产生,它的动作受动于进程的明确的要求,信号,软中断,硬中断,内核管理及异常,分别的...
  • Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的。 t8.c 1: #include &lt;stdio.h&gt; 2: #include &lt;sys/types.h&...

空空如也

空空如也

1 2 3
收藏数 49
精华内容 19
关键字:

linux例子软中断

linux 订阅