精华内容
下载资源
问答
  • 关中断时间:指的是程序中有一些临界段代码(关于这个详细了解可以看我这篇文章,临界区,临界资源),需要关闭中断才能安全访问那么访问这段代码前关总中断,访问完后打开总中断,在这个时间内,系统是无法响应外部...

    关中断时间:指的是程序中有一些临界段代码(关于这个详细了解可以看我这篇文章,临界区,临界资源),需要关闭中断才能安全访问那么访问这段代码前关总中断,访问完后打开总中断,在这个时间内,系统是无法响应外部任何中断的。

    最大关中断时间:指的是这么多个临界段代码的关中断时间中最大的那个,即这个时间就代表了最差最坏情况下中断的关闭时间了,因为实时操作系统中很多时间问题都是基于最差情况下考虑的。

    中断响应时间:接收到此中断到此中断对应的中断服务函数的第一条语句执行所经历的时间。其计算公式是:中断响应时间=最大关中断时间+保护CPU 内部寄存器的时间+进入中断服务函数的执行时间(会根据中断向量表找到对应的终端服务函数地址即入口)+开始执行中断服务例程(ISR)的第一条指令时间

    中断恢复时间:指从中断响应成功(即开始执行中断服务例程(ISR)的第一条指令时刻)一直到中断服务函数执行完毕再到切换回被中断的任务的接着一条代码执行所经历的时间。其计算公式是:中断恢复时间=中断服务函数执行所需时间(这样说不太准确,意思就是基本执行完所需时间,不包括退出中断服务函数前会调用一下OSIntExit()函数)+OSIntExit()(这个函数在中断服务函数末尾调用的,退出中断前来发生任务切换的)+OSIntCtxSw()(真正发生任务切换的函数,会进行寄存器数据弹出等操作)。

    任务等待(延迟)时间:指中断发生到任务代码重新开始执行的时间。参考公式是这个,我感觉不太正确,欢迎探讨。中断响应时间+中断恢复时间+调度器锁定时间。

    展开全文
  • [中断饱和] [通道、DMA、中断三种基本I/O方式的异同点] 如果认为CPU等待设备的状态信号是处于非工作状态(即踏步等待),那么在下面几种主机与设备之间的数据传送中: (1)主程序与主机与设备是串行工作的:程序查询...

    第八章 输入输出系统 习题

    [中断处理]
    [中断饱和]
    [通道、DMA、中断三种基本I/O方式的异同点]

    1. 如果认为CPU等待设备的状态信号是处于非工作状态(即踏步等待),那么在下面几种主机与设备之间的数据传送中:
      (1)主程序与主机与设备是串行工作的:程序查询方式
      (2)主机与设备是并行工作的:DMA方式
      (3)主程序与设备是并行运行的:程序中断方式

    2. 中断向量地址是:中断服务程序人口地址指示器

    3. 利用微型机制作了对输人数据进行采样处理的系统。在该系统中,每抽取一个输人数据就要中断CPU一次,中断处理程序接收采样的数据,将其放到主存的缓冲区内。该中断处理需时x秒,另一方面缓冲区内每存储n个数据,主程序就将其取出进行处理,这种处理需时y秒。因此该系统可以跟踪到每秒( n/(n*x+y) )次的中断请求。

    4. 采用DMA方式传送数据时,每传送一个数据就要占用一个(存储周期)的时间。

    5. 通道的功能是:(执行通道指令,组织外围设备和内存进行数据传输)、以及(向CPU报告中断);按通道的工作方式分,通道有(选择通道)、(字节多路通道)、(数组多路通道)三种类型。

    6. 在图8.9中,当CPU对设备B的中断请求进行服务时,如设备提出请求,CPU能够响应吗?为什么?如果设备B一提出请求总能立即得到服务,问怎样调整才能满足此要求?
      【答】(1)CPU 不能响应中断设备
      (2)因为同级中断不能嵌套,而A、B设备属于同级中断
      (3)如果想要设备B一提出请求即能得到服务,则应该使设备B为最高优先级,这里可将B单独接至3级IR,处于最高优先级。

    7. [中断饱和] 在图8.9中,假定 CPU取指并执行一条指令的时间为t1,保护现场需t2,恢复现场需t3,中断周期需t4,每个设备的设备服务时间为tA,tB,…,tG。试计算只有设备A,D,G时的系统中断饱和时间。
      在这里插入图片描述

    8. [中断处理] 设某机有5级中断:L0,L1,L2,L3,L4,其中断响应优先次序为:L0最高,L1次之,L4最低。现在要求将中断处理次序改为L1-L3-L0-L4-L2,试问:
      (1)下表中各级中断处理程序的各中断级屏蔽值如何设置(每级对应一位,该位为“0”表示允许中断,该位为“1”表示中断屏蔽)?
      在这里插入图片描述
      (2)若这5级中断同时都发出中断请求,按更改后的次序画出进入各级中断处理程序的过程示意图。
      在这里插入图片描述

    9. 某机器CPU中有16个通用寄存器,运行某中断处理程序时仅用到其中2个寄存器,请问响应中断而进人该中断处理程序时是否要将通用寄存器内容保存到主存中去?需保存几个寄存器?
      【答】 响应中断而进入该中断处理程序时,需将通用寄存器内容保存到主存中去,但为减少中断处理时间,不必保存所有通用寄存器内容,这里只需将2个中断处理程序中用到的寄存器内容保存起来。

    10. 参见图8.9所示的二维中断系统。
      (1)若CPU现执行E的中断服务程序,IM2.IM1.IM0 的状态是什么?
      【答】执行E的中断服务程序,则E级别及以下的IM置1关闭,IM2.IM1.IM0=011。
      (2) CPU现执行H的中断服务程序,IM2.IM1.IM0 的状态是什么?
      【答】执行H的中断服务程序,则H级别及以下的IM置1关闭,IM2.IM1.IM0=001。
      (3)若设备B一提出中断请求,CPU立即进行响应,应如何调整才能满足要求?
      【答】可将B从第2级取出单独放到第三级,使第三级优先级最高,即令IM3=0。

    11. 比较通道、DMA、中断三种基本I/O方式的异同点。
      【答】
      (1)通道方式:可以实现对外设的统一管理和外设与内存之间的数据传送,大大提高了 CPU的工作效率。
      (2)DMA方式:数据传送速度很高,传送速率仅受到内存访问时间的限制。需要更多硬件,适用于内存和高速外设之间大批数据交换的场合。
      (3)中断方式:一般适用于随机出现的服务,且一旦提出要求应立即进行,节省了 CPU的时间开销,但硬件结构稍复杂一些。
      一、相同点:通道、DMA、中断三种基本I/O方式均为外围设备和内存之间的输入/输出控制方式。
      二、不同点:
      (1)驱动方式不同:
      中断:允许I/O设备主动打断CPU的运行并请求服务,从而“解放”CPU,使得其向I/O控制器发送读命令后可以继续做其他有用的工作;
      DMA:直接存储器存取方式的基本思想是在I/O设备和内存之间开辟直接的数据交换通路,彻底“解放” CPU;
      I/O通道方式:DMA方式的发展,它可以进一步减少CPU的干预,即把对一个数据块的读(或写)为单位的干预,减少为对一组数据块的读(或写)及有关的控制和管理为单位的干预。
      (2)适用场景不同:
      中断:适用于高效场合
      DMA:不需要CPU干预介入的控制器来控制内存与外设之间的数据交流的场合
      I/O通道方式:适用于以字节为单位的干预,同时实现CPU、通道和I/O设备三者并行操作的场合
      (3)处理方法不同:
      中断:在系统中具有多个中断源的情况下,常用的处理方法有,多中断信号线法.中断软件查询法.雏菊链法、总线仲裁法和中断向量表法。
      DMA:获取总线的3种方式分别为:暂停方式、周期窃取方式和共享方式。
      I/O通道方式:通道是一种通过执行通道程序管理I/O操作的控制器,它使主机与1/0操作之间达到更高的并行程度。按照所采取的传送方式,可将通道分为字节多路通道、选择通道和数组多路通道3种。

    12. 用多路DMA控制器控制光盘、软盘、打印机三个设备同时工作。光盘以 20μs的间隔向控制器发DMA请求,软盘以90μs的间隔向控制器发DMA请求,打印机以180μs的间隔发 DMA 请求。请画出多路DMA控制器的工作时空图。
      在这里插入图片描述

    展开全文
  • 此外,还研究了中断概率的渐近行为,表明二次系统表现出中断饱和现象和零分集增益。 仿真结果表明,严格的干扰温度约束对中断概率具有明显的不利影响,但是,可以通过增加SR天线的数量来基本缓解这种影响。
  • 中断/异常相量的装入和执行方式。中断和异常都是异步发生的事件,当该事件发生,系统将停止目前正在执行的代码转而执行事件响应的服务程序。而事件服务程序的入口点就是中断/异常向量所在的位置。arm的中断向量可以...

    作者一看就知道是个牛人了。http://blog.csdn.net/yeyueyeyue/archive/2006/12/11/1438221.aspx

    1。中断/异常相量的装入和执行方式。

    中断和异常都是异步发生的事件,当该事件发生,系统将停止目前正在执行的代码转而执行事件响应的服务程序。而事件服务程序的入口点就是中断/异常向量所在的位置。arm的中断向量可以是0x0开始的低地址向量,也可以是在FFFF0000位置的高向量地址。winCE下使用高地址作为trap区,所以在CE下arm使用高地址向量。下面我们来了解一下中断/异常向量的安装和执行过程。

    在kernelStart的过程中通过程序将如下代码复制到ffff0000的位置.

    VectorInstructions

    ldr     pc, [pc, #0x3E0-8]              ; reset

    ldr     pc, [pc, #0x3E0-8]              ; undefined instruction

    ldr     pc, [pc, #0x3E0-8]              ; SVC

    ldr     pc, [pc, #0x3E0-8]              ; Prefetch abort

    ldr     pc, [pc, #0x3E0-8]              ; data abort

    ldr     pc, [pc, #0x3E0-8]              ; unused vector location

    ldr     pc, [pc, #0x3E0-8]              ; IRQ

    ldr     pc, [pc, #0x3E0-8]              ; FIQ

    而在ffff03e0的位置放上如下的数据,每一项(32bit)对应一个异常的跳转地址也就是winCE的异常/中断向量跳转表。该表项的内容就是发生异常后将要执行的服务程序的入口地址。具体如下。

    VectorTable

    DCD     -1                              ; reset

    DCD     UndefException                  ; undefined instruction

    DCD     SWIHandler                      ; SVC

    DCD     PrefetchAbort                   ; Prefetch abort

    IF :DEF:ARMV4T :LOR: :DEF:ARMV4I

    DCD     OEMDataAbortHandler             ; data abort

    ELSE

    DCD     DataAbortHandler                ; data abort

    ENDIF

    DCD     -1                              ; unused vector

    DCD     IRQHandler                      ; IRQ

    DCD     FIQHandler                      ; FIQ

    在上面的这些代码/数据在内存空间上按照上述要求放置好以后,每次触发一个异常就自动运行到相应跳转表项所对应的地址执行。

    2.异常/中断服务程序

    在arm下,由于有7种异常状态包括reset、Undef exception、software interrupt(swi)、Prefech Abort、DataAbort、IRQ、FIQ七种异常/中断。reset仅在复位时发生,其他6种都是在系统运行时发生。当任何一个异常发生并得到响应时,ARM 内核自动完成以下动作:

    拷贝 CPSR 到 SPSR_

    设置适当的 CPSR 位:

    改变处理器状态进入 ARM 状态

    改变处理器模式进入相应的异常模式

    设置中断禁止位禁止相应中断

    更新 LR_

    设置 PC 到相应的异常向量

    同时不管异常发生在ARM 还是Thumb 状态下,处理器都将自动进入ARM 状态。并且中断使能会自动被关闭。在这个时候由于部分通用寄存器是不同模式公用的,所以还需要保存这些将会被破坏的寄存器,待到处理完成的时候恢复这些寄存器被中断前的状态。另外在进入异常模式后,lr的值不一定就是我们所需恢复执行的位置,该位置受到异常类型和流水线误差的影响。在SWI模式下,LR就是返回值。在IRQ和FIQ中LR=LR-4,DataAbort下LR=LR-8;具体原因我们就不讨论了,有兴趣可以参看一文。下面分别对这些服务程序进行分析。

    2-1.undef exception服务程序

    undef exception在执行到过非法的指令时产生,通常来模拟一些处理器不支持的功能,如浮点运算。简单说一下undef exception的过程:当当前指令为一条处理器不支持的指令时,处理器会自动动将该指令送交各协处理器(如MMU、FPU)处理,如果这些协处理器都无法识别这条指令的时候,就产生该异常。下面开始看相应的代码。

    NESTED_ENTRY    UndefException

    sub     lr, lr, #4                      ; (lr) = address of undefined instruction

    stmdb   sp, {r0-r3, lr}

    mov     r1, #ID_UNDEF_INSTR

    b       CommonHandler

    ENTRY_END UndefException

    上面就是undef Exception的服务程序的入口处(已经将不参与编译和Thumb模式下的代码去掉),通过lr-=4计算出触发异常前的指令地址,同时保存r0-r3和lr入undef_exception stack用于最后恢复现场和取得异常指令本身,随后进入分发程序CommonHandler.CommonHandler是一个公共的异常服务程序,它通过不同的传入参数来进行处理,在这里mov r1,#ID_UNDEF_INSTR就是指定异常模式为undef Exception.

    2-2.swi服务程序

    按在ARM处理器的设计意图,系统软件的系统调用(SystemCalls)都是通过SWI指令完成。SWI相当于一个中断指令,不同的是SWI不是由外部中断源产生的,同时对应于SWI的异常向量位于0xc的位置或0xffff 000c的位置。也就是说当执行一个swi指令后,当前程序流中断,并转入0xc或0xffff000c执行,同时将CPSR_mode(当前程序状态寄存器)复制入SPSR_svc,转入SVC模式运行(使用特权模式的寄存器组)。也就是说系统通过执行SWI引发系统swi异常后切换入特权模式,系统调用功能号由swi xx后的xx决定,在运行完指定功能的代码后返回异常时的地址并恢复用户模式。我们看看,Wince中这部分代码是如何实现的。

    DCD     SWIHandler                      ; SVC<

    LEAF_ENTRY SWIHandler

    IF {FALSE}

    ...

    ENDIF

    movs    pc, lr

    ENTRY_END SWIHandler

    上面IF {FALSE}到ENDIF之间的代码在编译的时候是得不到编译的(事实上这部分代码是用于开发中调试使用的,针对特殊的硬件平台,一般与我们使用的硬件平台无关。所以下面摘抄的代码都不将不参与编译的内容写入),因此SWI服务程序就是一句话。movs    pc, lr也就是直接回到SWI的地方,同时将SPSR_svc恢复到CPSR_mode中。这个过程中并没有进行在系统态执行特定系统指令序的工作,而仅仅是简单的返回,所以这不是系统调用,系统调用还需要根据调用号的不同运行指定的核心态代码。也就是说Wince的系统调用不是通过SWI来完成的,而是通过其他的异常处理手段达成的。

    2-3 中断服务程序

    IRQ(大概是最熟悉的异常方式了)在外部中断源在需要向处理器请求服务时发生,比如:时钟、外围器件FIFO上/下溢出、按键等等。IRQHandler就是中断的处理句柄,下面我们来具体看看。

    ----------------------------------------------------------------------------------

    NESTED_ENTRY IRQHandler

    sub     lr, lr, #4                      ; fix return address

    stmfd   sp!, {r0-r3, r12, lr}       ;保存将要用到的寄存器和lr压入stack_irq

    PROLOG_END

    和上面一样,服务程序的入口处都是例行公事的计算返回位置以抵消流水线误差。再将要用到的寄存器压入STACK_IRQ,这样,准备工作就做完了。

    ; Test interlocked API status.

    ;INTERLOCKED_START EQU USER_KPAGE+0x380

    ;INTERLOCKED_END EQU USER_KPAGE+0x400

    sub     r0, lr, #INTERLOCKED_START

    cmp     r0, #INTERLOCKED_END-INTERLOCKED_START

    bllo    CheckInterlockedRestart

    上面这部分的内容是关于互锁的检测,由于如信号量这些同步手段都必须作为原子操作进行,不允许打断。所以如果中断发生在互锁API的执行过程中,就需要专门的处理了。这些API都是放在INTERLOCKED_START和INTERLOCKED_END之间的,通过LR很容易就检查出是否是INTERLOCKEDXXX的过程中。这里并不关心互锁的实现就绕开这部分代码继续往下看,当作中断没有发生在interlock过程处理。

    ;

    ; CAREFUL! The stack frame is being altered here. It's ok since

    ; the only routine relying on this was the Interlock Check. Note that

    ; we re-push LR onto the stack so that the incoming argument area to

    ; OEMInterruptHandler will be correct.

    ;

    mrs     r1, spsr                        ; (r1) = saved status reg

    stmfd   sp!, {r1}                       ; save SPSR onto the IRQ stack

    mov     r0,lr                           ; parameter to OEMInterruptHandler

    msr     cpsr_c, #SVC_MODE:OR:0x80       ; switch to supervisor mode w/IRQs disabled

    stmfd   sp!, {lr}                       ; save LR onto the SVC stack

    stmfd   sp!, {r0}                       ; save IRQ LR (in R0) onto the SVC stack (param)

    ;

    ; Now we call the OEM's interrupt handler code. It is up to them to

    ; enable interrupts if they so desire. We can't do it for them since

    ; there's only on interrupt and they haven't yet defined their nesting.

    ;

    CALL    OEMInterruptHandler

    ldmfd   sp!, {r1}                       ; dummy pop (parameter)

    ldmfd   sp!, {lr}                       ; restore SVC LR from the SVC stack

    msr     cpsr_c, #IRQ_MODE:OR:0x80       ; switch back to IRQ mode w/IRQs disabled

    ; Restore the saved program status register from the stack.

    ;

    ldmfd   sp!, {r1}                       ; restore IRQ SPSR from the IRQ stack

    msr     spsr, r1                        ; (r1) = saved status reg

    ldr     lr, =KData                      ; (lr) = ptr to KDataStruct

    cmp     r0, #SYSINTR_RESCHED      ;->时间片已到,进行调度

    beq     %F10

    ;SYSINTR_DEVICES EQU 8         ;是否设备中断,中断号是否有效

    ;SYSINTR_MAX_DEVICES EQU 32

    sub     r0, r0, #SYSINTR_DEVICES

    cmp     r0, #SYSINTR_MAX_DEVICES

    ;由此可以看出windowsCE的系统中断号最大支持32种从9-40.

    ;其中第16号(24)被定义为SYSINTR_FIRMWARE

    ; If not a device request (and not SYSINTR_RESCHED)

    ldrhsb  r0, [lr, #bResched]             ; (r0) = reschedule flag

    bhs     %F20                            ; not a device request

    ;PendEvents  EQU 0x340             ; offset 0x10*sizeof(DWORD) of aInfo

    ;device 中断

    ldr     r2, [lr, #PendEvents]           ; (r2) = pending interrupt event mask

    mov     r1, #1

    orr     r2, r2, r1, LSL r0              ; (r2) = new pending mask

    str     r2, [lr, #PendEvents]           ; save it

    ;*PendEvents = *PendEvents|(1<

    ;

    ; mark reschedule needed

    ;情况1:r0=SYSINTR_RESCHED=1

    ;情况2: r0 =r0-SYSINTR_DEVICES>=SYSINTR_MAX_DEVICES

    10      ldrb    r0, [lr, #bResched]             ; (r0) = reschedule flag

    orr     r0, r0, #1                      ; set "reschedule needed bit"

    strb    r0, [lr, #bResched]             ; update flag

    20      mrs     r1, spsr                        ; (r1) = saved status register value

    and     r1, r1, #0x1F                   ; (r1) = interrupted mode

    cmp     r1, #USER_MODE                  ; previously in user mode?

    cmpne   r1, #SYSTEM_MODE                ; if not, was it system mode?

    cmpeq   r0, #1                          ; user or system: is resched == 1

    ;if(SytemMode(spsr)||UserMode(spsr))&&r0!=1) return;

    ldmnefd sp!, {r0-r3, r12, pc}^          ; can't reschedule right now so return

    *************************************************************************************

    sub     lr, lr, #4

    ldmfd   sp!, {r0-r3, r12}

    stmdb   lr, {r0-r3}

    ldmfd   sp!, {r0}

    str     r0, [lr]                        ; save resume address

    mov     r1, #ID_RESCHEDULE              ; (r1) = exception ID

    b       CommonHandler

    ENTRY_END IRQHandler

    将spsr_irq压入IRQ堆栈保存。为调用OEMInterruptHandler作准备。(通常中断处理程序切换入系统态执行的目的在于避免使用终端模式下的寄存器,以方便是实现终端套嵌,这儿切入系统态时终端使能是关闭的,对于模态切换的原因我很迷惑。)OEMInterrupt需要在特权模式下执行,所以这里增加了切换入特权(SVC)模式的内容。紧接着将要用与传递参数的寄存器保存。设定传入参数,r0就可以开始调用OEMInterruptHandler了,这里的调用规则遵循windowsCE的规范而不是ATPCS的规范。具体过程参考ARM Parameter Passing@msdn。下面是函数原形。int OEMInterruptHandler(unsigned int ra);这里传入的参数就是上面的r0,事实上r0代表的参数ra并没有实质的作用在这里仅仅是形式上的实现一下而已,不过在这儿可以看到这个传入的ra实际上就是被中断的地址,如果需要知道被中断的位置可以通过ra来查询,而msdn里面说这个参数是保留的。返回的参数也是保存在r0中。其中返回值是系统中断类型。其中SYSINTR_RESCHED为系统时钟中断,每次时间片用完,该时钟便产生中断,并设置kData结构的bResched位,进入调度流程。如果中断类型是系统设备中断,那就设置PendEvents,待再次调度的时候处理中断。所以OEMInterruptHandler必须提前就要对中断进行响应对该中断源设置mask,防止在这过程中同一中断不停发生,导致中断饱和影响程序流的执行,直道中断处理真正完成后再次开放该中断的mask。在这里还可以看到的是系统设备中断号的范围是从SYSINTR_DEVICES到SYSINTR_MAX_DEVICES,也就是从9-40一共32个设备中断号,其中SYSINTR_FIRMWARE为8+16号,这个在编写OAL的中断服务程序时需要注意。如果当前的返回值既不是设备中断号又不是调度中断号,则读出当前调度标示,根据该标示进行判断是否调度/或返回.如果是进入调度流程则恢复初始的寄存器状态,再按CommonHandler的要求保存寄存器。进入CommonHandler,等待分发。

    2-3 FIQ服务程序

    照例看看程序

    NESTED_ENTRY FIQHandler

    sub     lr, lr, #4                      ; fix return address

    stmfd   sp!, {r0-r3, r12, lr}

    PROLOG_END

    CALL    OEMInterruptHandlerFIQ

    ldmfd   sp!, {r0-r3, r12, pc}^          ; restore regs & return for NOP

    ENTRY_END FIQHandler

    LTORG

    FIQ是arm体系下特有的异常方式,其工作过程与IRQ类似都是由外部引脚触发但设计用途不同,IRQ用于通常的外部中断源的处理,是作为统一、通用的与外部器件交互的手段,而IRQ仅仅用于处理周期短同时又需要快速处理的场合其触发的事件源通常也来此外部FIQ中断。如:更换电池、数据传输这类工作。可想而知FIQ讲究的是快速,精干。因此FIQ服务程序通常没有分发,而仅仅是针对单一的工作进行处理保证处理的实时性。因此FIQ的处理相对IRQ就简单很多,直接调用OEMInterruptHandlerFIQ进行处理后返回就完成了整个 FIQ服务程序。    2-4 DataAbort服务程序

    由数据异常触发,通常有三种指令引发数据异常,这些指令都是访存操作,而且都是由MMU的引入后才可能会发生的情况。1.LDR/STR指令.2.SWAP指令。3.LDM/STM指令。而MMU的失效类型又分为4种:存储访问失效、地址对齐失效、地址变换失效、域控制器失效、访问控制权限失效.因此当异常发生后,需要通过访问CP15来获知异常的产生具体原因和情况。mfc是微软的asmarm宏汇编器专用的宏指令,相当于mcr指令。数据异常和中断模式一样都有可能在互锁时发生,所以同样需要对执行互锁的情形进行处理。正常的情况下在保存完相关的寄存器后就会读取CP15的c6,c5,c13三个寄存器。这三个寄存器分别是失效地址寄存器(FAR)、失效状态寄存器(FSR)、进程号寄存器(这个翻译得不好PCP15)然后根据具体的失效类型来进行处理。在ARM处理器中对于CP15有三种地址类型,VA,PA,MVA。VA(virtual address)也就是我们通常说的虚拟地址或逻辑地址也就是通过CP15按照PT转换后的地址,而PA(physical Address)则是对应于AMBA上的地址,对应的是电气介质也就是物理地址。而MVA(Modified virtual address)则是对应于Cache和TLB中转换地址。

    NESTED_ENTRY    DataAbortHandler

    sub     lr, lr, #8                      ; repair continuation address

    stmfd   sp!, {r0-r3, r12, lr}

    PROLOG_END

    sub     r0, lr, #INTERLOCKED_START

    cmp     r0, #INTERLOCKED_END-INTERLOCKED_START

    bllo    CheckInterlockedRestart

    mfc15   r0, c6                          ; (r0) = FAR

    mfc15   r1, c5                          ; (r1) = FSR

    mfc15   r2, c13                         ; (r2) = process base address

    ;  FAR=Fault address register

    ;  CP = 15: CRn = 6, CRm = 0, op_1 = 0, op_2 = 0

    ;  FSR=Fault status register

    ;  CP = 15: CRn = 5, CRm = 0, op_1 = 0, op_2 = 0

    ;  PCP15: PID  Process ID register

    ;  CP = 15: CRn = 13, CRm = 0, op_1 = 0, op_2 = 0

    tst     r0, #0xFE000000                 ; slot 0 reference?

    orreq   r0, r0, r2                      ; (r0) = process slot based address

    and     r1, r1, #0x0D                   ; type of data abort

    cmp     r1, #0x05                       ; translation error?

    movne   r0, #0

    CALLEQ  LoadPageTable                   ; (r0) = !0 if entry loaded

    tst     r0, r0

    ldmnefd sp!, {r0-r3, r12, pc}^          ; restore regs & continue

    ;*********************************************************************

    ldr     lr, =KData-4

    ldmfd   sp!, {r0-r3, r12}

    stmdb   lr, {r0-r3}

    ldmfd   sp!, {r0}

    str     r0, [lr]                        ; save resume address

    mov     r1, #ID_DATA_ABORT              ; (r1) = exception ID

    b       CommonHandler

    ENTRY_END DataAbortHandler

    在DataAbort发生后c6中的数据保存的就是导致异常的MVA地址,通过windowsCE memory layout可以了解到,当前进程的运行空间是在slot0,也就是0x0-0x1fffffff的位置,事实上这个slot上的数据仅仅是实际进程的一个副本所以如果数据异常发生在slot0就需要去找到进程所在的实际slot的存放地址,然后尝试将内核的页表复制到硬件实际使用的页表以达到恢复的目的。如果复制动作成功则返回,否则进入异常分发程序CommonHandler。

    2-5 PrefetchAbort服务程序

    对于ARM处理器来说,由于其内部使用了哈佛结构---独立的数据的指令总线因此,在数据/指令的读取过程中产生的异常也就很自然地可以区分开来,本质上而言,这些异常都是同属于存储访问失败产生的异常,因此这些异常都由MMU相关,在ARM手册中DataAbort和PrefetchAbort都称为Memory abort。Prefetch也就是在预取指令的动作后产生的,当处理器运行到这个无效的指令时(这个无效与undefined exception中的不可识别不同,是指不存在或是无法得到)就触发该异常。所以不是所有的指令无效都产生异常,例如:一个分支程序指向一个不可访问的区域,而之前的分支指向另一个可访问区域时。后一个区域尽管预取无效但是由于该分支并不执行所以并不产生异常。所以prefetch的准确定义应该是prefetch and executes Abort:).在ARMV5指令集中BKPT也可以产生预取无效但由于这儿的ARM通常都是ARM9的,也就是使用ARMV4指令所以不讨论BKPT的情形。由于数据异常和指令异常同属存储异常而且两个异常不可能会相互中断所以在ARM的设计上这两个异常使用同一组寄存器abort组。

    ALTERNATE_ENTRY PrefetchAbort

    sub     lr, lr, #0xF0000004  ;考察产生异常的地址是否在0xf0000000-0xf0010400

    cmp     lr, #0x00010400    ;之间,如果是进入系统调用处理

    bhs     ProcessPrefAbort      ;->>正常的预取异常 执行ProcessPrefAbort

    ...

    ProcessPrefAbort

    add     lr, lr, #0xF0000000             ; repair continuation address

    stmfd   sp!, {r0-r3, r12, lr}

    mov     r0, lr                          ; (r0) = faulting address

    mfc15   r2, c13                         ; (r2) = process base address

    tst     r0, #0xFE000000                 ; slot 0 reference?

    orreq   r0, r0, r2                      ; (r0) = process slot based address

    CALL    LoadPageTable                   ; (r0) = !0 if entry loaded

    tst     r0, r0

    ldmnefd sp!, {r0-r3, r12, pc}^          ; restore regs & continue

    ldmfd   sp!, {r0-r3, r12}

    ldr     lr, =KData-4

    stmdb   lr, {r0-r3}

    ldmfd   sp!, {r0}

    str     r0, [lr]                        ; save resume address

    mov     r1, #ID_PREFETCH_ABORT          ; (r1) = exception ID

    b       CommonHandler

    下面来结合windowsCE的情形。PrefetchAbort就是该服务程序的入口,在程序的一开始将lr,也就是产生异常的地址+4(流水线导致)的地址减掉0xf000 0004并比较是否在0-0x10400之间,这是为什么呢?原来windowsCE除了使用PrefetchAbort服务程序作为正常的异常处理以外还使用这个异常作为系统调用的手段。通过0xf0000000-0xf0010400这段地址的预取异常来进行系统调用。我们下面看处理预取失败的情况,绕开系统调用的先不管。也就是ProcessPrefAbort的分支。 这个分支的内容就与上面DataAbort的内容一样了,我就不再重复了。

    展开全文
  • 网卡中断与软中断

    千次阅读 2018-09-26 16:10:33
    查看命令 1. mpstat -P ALL 1 或 mpstat -I SUM -P ALL 1(有的机器得用这...3. cat /proc/interrupts | grep eth1 通过这个可以查看网卡队列数目,也可以查看哪个cpu占用的软中断 4.top命令查看 Cpu(s): 0...

    查看命令

    1. mpstat -P ALL 1  或 mpstat -I SUM -P ALL 1(有的机器得用这个命令),

    2. sar -n DEV 1         显示 网络读写发生在eth1

    3. cat /proc/interrupts | grep eth1    通过这个可以查看网卡队列数目,也可以查看哪个cpu占用的软中断

    4.top命令查看

    Cpu(s):  0.1%us,  0.0%sy,  0.0%ni, 99.9%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

    第三行,cpu状态信息,具体信息说明如下:

    0.1%us — 用户空间占用CPU的百分比

    0.0% sy — 内核空间占用CPU的百分比

    0.0% ni — 改变过优先级的进程占用CPU的百分比

    99.9% id — 空闲CPU百分比

    0.0% wa — IO等待占用CPU的百分比

    0.0% hi — 硬中断(Hardware IRQ)占用CPU的百分比

    0.0% si — 软中断(Software Interrupts)占用CPU的百分比

    问题描述

    Linux内核在性能方面已经经历了很长一段时间的考验,尤其是2.6/3.x内核。然而,在高IO,尤其是网络方面的情况下,对中断的处理可能成为问题。我们已经 在拥有一个或多个饱和1Gbps网卡的高性能系统上发现过这个问题,近来在有许多小包并发(大约10000packets/second)超载的虚拟机上 也发现了这个问题。

    原因很清楚:在最简单的模式中,内核通过硬件中断的方式来处理每个来自于网卡的包。但是随着 数据包速率的增长,带来的中断渐渐超过了单个cpu可处理的范围。单cpu概念很重要,系统管理员对此往往认识不足。在一个普通的4-16核的系统中,因 为整体cpu的使用率在6-25%左右并且系统看上去很正常,所以一个过载的内核很难被发现,。但是系统将运行很慢,并且会在没有告警,没有dmesg日 志,没有明显征兆的情况下严重丢包。

    分析

    但是你使用top查看多个cpu模式(运行top,接着键入1)时,%si 列(系统中断)或者mpstat命令中 irq列(mpstat -P ALL 1),在一些繁忙的系统中你会发现中断明显很高,通过经进一步mpstat使用,你会看到哪个cpu或者哪个设备存在问题。

    你需要一个较新版本的mpstat,可以运行-I 模式,用以列出irq负载,运行如下命令:

    mpstat -I SUM -P ALL 1

    超过5000/秒 有点繁忙, 1万-2万/秒相当高了。

    运行如下命令来确认那个设备/项目导致负载:

    mpstat -I CPU -P ALL 1 这个输出很难被阅读,但是你可以跟踪正确的列用来确认哪个中断导致负载,例如:15,19,995. 你也可以定义你想查看的cpu

    mpstat -I CPU -P 3 1 # 3 在top,htop中可以定位不同的cpu。(top和mpstat都是从0开始,htop是从1开始计数)

    记录下中断数,你就可以查看中断表 ,"cat /proc/interrupts" 找到mpstat's得到的数字,你可以发现是哪个设备在使用中断。这个文件也指示了使用该中断的#可以告诉你是什么导致过载。

    查看中断分布情况即CPU都在哪些设备上干活

    root@geekwolf:~# cat /proc/interrupts
    
               CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7       CPU8       CPU9       CPU10      CPU11      CPU12      CPU13      CPU14      CPU15      CPU16      CPU17      CPU18      CPU19      CPU20      CPU21      CPU22      CPU23      CPU24      CPU25      CPU26      CPU27      CPU28      CPU29      CPU30      CPU31      
      0:        620          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC-edge      timer
      8:          1          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC-edge      rtc0
      9:      20774          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC-fasteoi   acpi
     16:         28          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC-fasteoi   ehci_hcd:usb1
     23:        243          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC-fasteoi   ehci_hcd:usb2
     88:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  DMAR_MSI-edge      dmar0
     89:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  DMAR_MSI-edge      dmar1
     90:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     91:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     92:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     93:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     94:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     95:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     96:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     97:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     98:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
     99:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
    100:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      PCIe PME
    101:     169988          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      mpt2sas0-msix0
    134:    1900138          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      eth2-q0
    150:    4262209          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      eth3-q0
    166:          4          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    167:          4          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    168:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    169:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    170:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    171:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    172:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    173:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    174:          4          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    175:          4          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    176:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    177:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    178:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    179:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    180:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    181:          2          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-edge      ioat-msix
    NMI:        710        280        658        235        114         91         76         74        208        123        176        128        106         93        102         95         30        360        790         46         28         17         10          8         10        129       1166         22         18         16         11          7   Non-maskable interrupts
    LOC:    4230314    2640664    2427443    1337890    1091372     892129     819153     816781    2695809    1563153    1368637    1608410    1241692    1166692    1205270    1124865     120831    1966946     328048     816162     163492     222276     129805     121126     111906     599782    1247371     194215     162828     145678     118762     114295   Local timer interrupts
    SPU:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0   Spurious interrupts
    PMI:        710        280        658        235        114         91         76         74        208        123        176        128        106         93        102         95         30        360        790         46         28         17         10          8         10        129       1166         22         18         16         11          7   Performance monitoring interrupts
    IWI:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0   IRQ work interrupts
    RES:     679921    1369165    1013002     573776     543083     540027     593345     588120     842115     846190     874862     890102     873810     860080     867322     848916       3879      63916      10863      12850       7463       6350      10889      16041       2065      13207       6870       6817       4030       4700       5190       7430   Rescheduling interrupts
    CAL:      46507      67439      67569      67567      67565      67566      67566      67568     154689      67553      67511      67538      67568      67557      67534      67519      67520      26471      67470      67470      67476      67525      67518      67525      67545      64065      67210      67506      67485      67492      67526      67521   Function call interrupts
    TLB:       6547       3416       1798       1015        361        637        271        447        822        113       1079        222        259        198        265        844        157       1470       3468        767        499        262        338        230         41       1457       4023        290        105         93         46        177   TLB shootdowns
    TRM:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0   Thermal event interrupts
    THR:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0   Threshold APIC interrupts
    MCE:          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0   Machine check exceptions
    MCP:        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569        569   Machine check polls
    ERR:          0
    MIS:          0

    RPS/RFS

    Receive Packet Steering/Receive Flow Streering,软件方式实现CPU均衡,接收包中断的优化 
    RPS: 网卡驱动对每一个数据库包根据四元组(SIP,SPORT,DIP,DPORT)生成HASH值,通过HASH值将每个连接和CPU 绑定 
    RFS: 由于RPS只是单纯的把数据包均衡到不同的CPU上,此时如果应用程序所在CPU和中断处理的CPU不在同一个核,将会对CPU Cache影响很大,RFS的作用就是将应用程序和软中断处理分配到同一个CPU

     

    需要做什么呢?

    首先,确认你是否运行irqbalance,这个是nice守护进程它会自动在cpu间扩展中断。在繁忙的系统中很重要,尤其是两块网卡,因为默认cpu0 将处理所有中断,系统很容易过载。irqbalance扩散这些中断用以降低负载。为了性能最大化,你可以手动平衡这些中断将套接字和超线程共享内核分 散,但是通常没必要这么麻烦。

    但是即使扩展了中断,某块网卡还是可能导致某一个cpu过载。这取决于你的网卡和驱动,但通常有两种有效的方法来防止这样的事情发生。

    第一种是多网卡队列,有些Intel网卡就可以这么做。如果他们有4个队列,就可以有四个cpu内核同时处理不同的中断用以分散负载。通常驱动会自动这么做,你也可以通过mpstat命令来确认。

    第二种,并且通常也是更加重要的,网卡驱动选项——'IRQ coalescing',中断请求合并。这个选项有着强大的功能,允许网卡在调用中断请求前缓存数个数据包,从而为系统节约大量的时间和负载。

    举个例子: 如果网卡缓存10个包,那么cpu负载将大约降低90%。这个功能通常用ethtool工具来控制,使用'-c/-C'参数,但是有些驱动要求在驱动初次 加载时就做好相关设置。如何设置需要查看本机文档。举个例子,有些网卡,譬如我们使用的Intel网卡,就有automatic模式可以根据负载自动做到 最优化。 最后,就像我们在虚拟机中看到的一些驱动,它们不支持多队列或者中断请求合并。这种情况下,一旦处理中断的cpu繁忙,就会产生性能瓶颈,除非你更换设备或者驱动。 这是一个复杂的区域,并不广为人知,但有些不错的技术真的可以提高繁忙系统的性能。此外,一些额外的针对性监控,可以帮助到查找和诊断这些难以发现的问题。

     

    前些天发现XEN虚拟机上的Nginx服务器存在一个问题:软中断过高,而且大部分都集中在同一个CPU,一旦系统繁忙,此CPU就会成为木桶的短板。

    在问题服务器上运行「top」命令可以很明显看到「si」存在异样,大部分软中断都集中在 1 号CPU上,其它的CPU完全使不上劲儿:

    shell> top
    Cpu0: 11.3%us,  4.7%sy,  0.0%ni, 82.5%id,  ...  0.8%si,  0.8%st
    Cpu1: 21.3%us,  7.4%sy,  0.0%ni, 51.5%id,  ... 17.8%si,  2.0%st
    Cpu2: 16.6%us,  4.5%sy,  0.0%ni, 77.7%id,  ...  0.8%si,  0.4%st
    Cpu3: 15.9%us,  3.6%sy,  0.0%ni, 79.3%id,  ...  0.8%si,  0.4%st
    Cpu4: 17.7%us,  4.9%sy,  0.0%ni, 75.3%id,  ...  1.2%si,  0.8%st
    Cpu5: 23.6%us,  6.6%sy,  0.0%ni, 68.1%id,  ...  0.9%si,  0.9%st
    Cpu6: 18.1%us,  4.9%sy,  0.0%ni, 75.7%id,  ...  0.4%si,  0.8%st
    Cpu7: 21.1%us,  5.8%sy,  0.0%ni, 71.4%id,  ...  1.2%si,  0.4%st

    查询一下软中断相关数据,发现主要集中在 NET_RX 上,猜测是网卡问题:

    shell> watch -d -n 1 'cat /proc/softirqs'
                    CPU0       CPU1       CPU2 ...       CPU7
          HI:          0          0          0 ...          0
       TIMER: 3692566284 3692960089 3692546970 ... 3693032995
      NET_TX:  130800410  652649368  154773818 ...  308945843
      NET_RX:  443627492 3802219918  792341500 ... 2546517156
       BLOCK:          0          0          0 ...          0
    BLOCK_IOPOLL:      0          0          0 ...          0
     TASKLET:          0          0          0 ...          0
       SCHED: 1518716295  335629521 1520873304 ... 1444792018
     HRTIMER:        160       1351        131 ...        196
         RCU: 4201292019 3982761151 4184401659 ... 4039269755

    补充:有一个查看中断(Interrupt)的top风格小工具 itop ,推荐试试。

    确认一下宿主机上的网卡信息,发现其运行在单队列模式下:

    shell> grep -A 10 -i network /var/log/dmesg
    Initalizing network drop monitor service
    Intel(R) Gigabit Ethernet Network Driver - version 3.0.19
    igb 0000:05:00.0: Intel(R) Gigabit Ethernet Network Connection
    igb 0000:05:00.0: eth0: (PCIe:2.5GT/s:Width x4) 00:1b:21:bf:b3:2c
    igb 0000:05:00.0: eth0: PBA No: G18758-002
    igb 0000:05:00.0: Using MSI-X ... 1 rx queue(s), 1 tx queue(s)
    igb 0000:05:00.1: Intel(R) Gigabit Ethernet Network Connection
    igb 0000:05:00.1: eth1: (PCIe:2.5GT/s:Width x4) 00:1b:21:bf:b3:2d
    igb 0000:05:00.1: eth1: PBA No: G18758-002
    igb 0000:05:00.1: Using MSI-X ... 1 rx queue(s), 1 tx queue(s)

    接着确认一下网卡的中断号,因为是单队列,所以只有一个中断号 45:

    shell> grep eth /proc/interrupts | awk '{print $1, $NF}'
    45: eth0

    知道了网卡的中断号,就可以查询其中断亲缘性配置「smp_affinity」:

    shell> cat /proc/irq/45/smp_affinity
    02

    这里的 02 实际上是十六进制,表示 1 号CPU,计算方法如下(参考资料):

              Binary       Hex 
      CPU 0    0001         1 
      CPU 1    0010         2
      CPU 2    0100         4
    + CPU 3    1000         8
      -----------------------
      both     1111         f

    说明:如果 4 个CPU都参与中断处理,那么设为 f;同理 8 个CPU的就设置成 ff:

    shell> echo ff > /proc/irq/45/smp_affinity

    此外还有一个类似的配置「smp_affinity_list」:

    shell> cat /proc/irq/45/smp_affinity_list
    1

    两个配置是相通的,修改了一个,另一个会跟着变。不过「smp_affinity_list」使用的是十进制,相比较「smp_affinity」的十六进制,可读性更好些。

    了解了这些基本知识,我们可以尝试换一个CPU试试看会发生什么:

    echo 0 > /proc/irq/45/smp_affinity_list

    再通过「top」命令观察,会发现处理软中断的CPU变成了 0 号CPU。

    说明:如果希望多个CPU参与中断处理的话,可以使用类似下面的语法:

    echo 3,5 > /proc/irq/45/smp_affinity_list
    echo 0-7 > /proc/irq/45/smp_affinity_list

    坏消息是对单队列网卡而言,「smp_affinity」和「smp_affinity_list」配置多CPU无效。

    好消息是Linux支持RPS,通俗点来说就是在软件层面模拟实现硬件的多队列网卡功能。

    首先看看如何配置RPS,如果CPU个数是 8 个的话,可以设置成 ff:

    shell> echo ff > /sys/class/net/eth0/queues/rx-0/rps_cpus

    接着配置内核参数rps_sock_flow_entries(官方文档推荐设置: 32768):

    shell> sysctl net.core.rps_sock_flow_entries=32768

    最后配置rps_flow_cnt,单队列网卡的话设置成rps_sock_flow_entries即可:

    echo 32768 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt

    说明:如果是多队列网卡,那么就按照队列数量设置成 rps_sock_flow_entries / N 。

    做了如上的优化后,我们再运行「top」命令可以看到软中断已经分散到了两个CPU:

    shell> top
    Cpu0: 24.8%us,  9.7%sy,  0.0%ni, 52.2%id,  ... 11.5%si,  1.8%st
    Cpu1:  8.8%us,  5.1%sy,  0.0%ni, 76.5%id,  ...  7.4%si,  2.2%st
    Cpu2: 17.6%us,  5.1%sy,  0.0%ni, 75.7%id,  ...  0.7%si,  0.7%st
    Cpu3: 11.9%us,  7.0%sy,  0.0%ni, 80.4%id,  ...  0.7%si,  0.0%st
    Cpu4: 15.4%us,  6.6%sy,  0.0%ni, 75.7%id,  ...  1.5%si,  0.7%st
    Cpu5: 20.6%us,  6.9%sy,  0.0%ni, 70.2%id,  ...  1.5%si,  0.8%st
    Cpu6: 12.9%us,  5.7%sy,  0.0%ni, 80.0%id,  ...  0.7%si,  0.7%st
    Cpu7: 15.9%us,  5.1%sy,  0.0%ni, 77.5%id,  ...  0.7%si,  0.7%st

    疑问:理论上讲,我已经设置了RPS为ff,应该所有 8 个CPU一起分担软中断才对,可实际结果只有两个,有知道原因的请赐教,但是不管怎么说,两个总好过一个。

    此外,因为这是一台Nginx服务器,所以通过「worker_cpu_affinity」指令可以配置Nginx使用哪些CPU,如此一来我们便可以绕开高负载的CPU,对性能会有一些帮助。

    补充:如果服务器是NUMA架构的话,那么「numactl –cpubind」可能也会有用。

    最后,推荐看看香草总结的一些关于软中断方面的资料工具,很全面。

     

    相关文章

    展开全文
  • 考点:中断饱和 解:根据题给条件可得各设备处理时间: TA=t1+t2+t3+tA+t4 T_A=t_1+t_2+t_3+t_A+t_4 TA​=t1​+t2​+t3​+tA​+t4​ TD=t1+t2+t3+tD+t4 T_D=t_1+t_2+t_3+t_D+t_4 TD​=t1​+t2​+t3​+tD​+t4​ TG=...
  • 在来自ab的负载下,第一个CPU内核饱和,其余的负载不足.在/ proc / interrupts中,我看到CPU0比其他任何内核服务的中断数量级更多.他们大多数来自eth1.我可以做些什么来提高这个VM的性能?有没有办法更均匀地平衡中断?...
  • 根据人体血液中氧合和还原血红蛋白不同的吸光特性,采用非损伤的光电体积描记技术,用红光和红外光两种不同波长的光源,实现血氧饱和度生理参数的实时检测。系统设计的硬件包括指夹式的光电传感器、单片机控制与信号...
  • 本文探讨了用于汽车结构应用的拉挤玻璃纤维/不饱和聚酯方管的准静态挠曲性能和断裂行为。 三点弯曲测试是在Instron万能测试机中进行的,其中钢夹具支撑着管道的顶部和底部。 在弯曲测试期间记录声发射(AE)测量值,...
  • 有志者,事竟成。———《后汉书·耿弇传》 ...但是如果有限队列已经满了,则会交给饱和策略来处理这个任务。 ThreadPoolExecutor 的饱和策略可以通过调用 setRejectedExecutionHandler 来修改。JDK 提供了...
  • 线程池工作队列饱和策略

    万次阅读 2016-07-03 00:13:03
    近段时间在看《Java并发编程实战》,第一遍每天看一章也没敲代码,并没吸收多少。看第二遍的时候压下速度,并敲代码,感觉理解深刻好多,废话止...无界队列不存在饱和的问题,但是其问题是当请求持续高负载的话,任务会
  • 饱和策略,默认为AbortPolicy, 饱和就废弃,但是会抛出 RejectedExecutionException(非检查异常) 线程池 使用说明 corepoolsize maxpoolsize 后台使用队列 newCachedThreadPool 无限容量线程池运行队列;...
  • 使用 Arduino 测量血氧饱和

    千次阅读 2021-08-24 06:32:48
    我们所经历的,并且在某种意义上仍在经历的冠状病毒疫情,已经把间质性肺炎、肺呼吸机、重症监护和饱和度计等词放在了大家的嘴边。;新闻媒体每天都会带入我们家中的东西,幸运的是,对于那些不是内部人员或直接涉及...
  • 血氧饱和度研究方法总结

    千次阅读 2021-11-24 13:50:13
    之前向购买血氧饱和度检测的厂家(慧创医疗)要了一些使用我们同款设备的学校发的一些论文,阅读并总结了一部分方法如下: 1.中国科学院 计算技术研究所 发表于International Journal of Human-Computer Studies...
  • 在此基础上,进行基于信干噪比的认知中继选择和性能分析,推导出认知中继系统中断概率的闭式表达式,并通过理论分析和仿真结果证明,随着主用户发射信噪比的增大,频谱共享干扰会导致认知系统中断饱和现象的发生,而...
  • 线程池四个中断策略

    2014-09-23 10:11:03
    中断策略实际上是指饱和策略(concurent包中的RejectedExecutionHandler接口),这里需要先解释一下,什么叫饱和策略, 实际就是说, 线程池中的线程容器已经放不下新的任务了,饱和了, 必须要有一个相应的策略来...
  • 无界队列不存在饱和的问题,但是其问题是当请求持续高负载的话,任务会无脑的加入工作队列,那么很可能导致内存等资源溢出或者耗尽。而有界队列不会带来高负载导致的内存耗尽的问题,但是有引发工作队列已满情况下,...
  • 先测量身高,然后站到我们的体重秤上,此时身高,体重,体温,血氧饱和度这几个数据就会在前端页面上进行显示,然后测量血压,血压测量结束之后,收缩压,舒张压,脉搏的数据就会在前端进行显示,这个就是我们整个...
  • 我们已经在拥有一个或多个饱和1Gbps网卡的高性能系统上发现过这个问题,近来在有许多小包并发(大约10000packets/second)超载的虚拟机上也发现了这个问题。原因很清楚:在最简单的模式中,内核通过硬件中断的方式来...
  • 作者:SUKHOI27SMK ... ... 中断和异常都是异步发生的事件,当该事件发生,系统将停止目前正在执行的代码转而执行事件响应的服务程序。而事件服务程序的入口点就是中断/异常向量所在的位置。arm的
  • 《计算机组成原理》第二版第五章课后习题解答

    千次阅读 多人点赞 2020-06-05 13:28:04
    主要内容包括I/O设备与主机交换信息的三种控制方式(程序查询、中断和DMA)及其相应的接口功能和组成。
  • eCos中断模型

    2015-01-06 11:15:00
    http://blog.csdn.net/chychc/article/details/8313458 ...     eCos中断模型(1)ISR和DSR 英文全称 Interrupt Service Routine   中断处理是实时操作系统一个重...
  • 原文网址:Java线程池--流程/原理--使用步骤/大小设置/饱和策略(拒绝策略)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Java的线程池的流程和原理,包括:使用步骤/大小设置/饱和策略(拒绝策略)。 为什么要用...
  • 判断三极管的饱和:(如下图)将B区看成一个可变的电阻,开始截至时因为电不导通,电阻无穷大,后随着P级加上电压导通,处于放大状态,三条线电流E=B+C,B端电压恒定电流增大电阻变小,导致C端电压减小,最终B和C端...
  • 快速定位性能瓶颈,检查出所有资源(CPU、内存、磁盘IO等)的利用率(utilization)、饱和度(saturation)和错误(error)度量,即USE方法 转载:https://www.cnblogs.com/anai/p/5889694.html 命令:uptime 说明...
  • ARM 汇编指令说明

    2020-12-22 12:31:12
    1、MRS:将CPSR或SPSR的内容移动到一个通用寄存器2、MSR:将立即数或通用寄存器的内容加载到CPSR或SPSR的指定字段中3、PRIMASK:用于disable NMI和硬 fault之外的所有异常,它...CPSID就是中断禁止,CPSIE中断允许,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,801
精华内容 4,320
热门标签
关键字:

中断饱和