Linux内核中断系列之多处理器系统中的中断处理(七)【转】

摘要:
IPI中断信号通过APIC总线传输到目标APIC,接收到中断的APIC像自己的CPU一样发送中断。请注意,它不能设置为0x0,即关闭所有CPU以处理中断。

转自:https://blog.csdn.net/zhao2272062978/article/details/70600344?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

一、处理器间中断(IPI)
1、在多处理器系统中,操作系统需要在多个处理器间协调操作,通常是通过处理期间中断(IPI)实现的。
2、IPI是一种特殊的硬件中断,由处理器发出,被其他处理器接收,以便于处理器间通信或同步。
3、通常并不明确区分IPI和设备中断,当一个处理器接收到一个中断时,如果发现另一个处理器处理该终端更加合理,则可以通过IPI机制将该终端传递到其他的处理器,实现处理器的负载平衡。
4、当一个CPU相对另一个CPU发送中断信号时,就在自己的本地APIC的ICR(中断命令寄存器)中存放其中断向量,和目标CPU拥有的本地APIC的标识符,触发中断。IPI中断信号经由APIC总线传递到目标APIC,那个收到中断的APIC就像自己所属的CPU发送一个中断。
5、Linux针对IA32的SMP系统定义了5中IPI,中断向量号为251~255:
  (1) CALL_FUNCTION_VECTOR:发往除自己以外的所有CPU,强制它们执行指定的函数;
  (2) RESCHEDDULE_VECTOR:是终端的CPU重新调度;
  (3) INVLIDATE_TLB_VECTOR:使被中断的CPU废弃自己的TLB缓存内容;
  (4) ERROR_APIC_VECTOR:错误的APIC向量,应该从不发生;
  (5) SPUROUS_APIC_VECTOR:假的APIC向量,应该从不发生;
另外请参考:http://www.docin.com/p-70820238.html
二、中断亲和力
1、中断亲和力是将一个或多个中断服务程序绑定到特定的CPU上运行。
2、中断亲和力通过操作/proc/irq目录下的文件来控制。对于已注册的中断服务程序的硬件设备,在/proc/irq目录下存在一个该中断号命名的目录,该目录下有一个smp_affinity         文件(SMP体系结构下才有)。它是一个CPU的位掩码,其中的每一位对应一个CPU,可以用来设置该中断的亲和力,默认为0xFFFFFFFF,表示把中断送到所有的CPU上去         处理。如果中断控制器不支持IRQ  affinity,则不能改变此默认值。
     注意不能设置为0x0,即关闭所有CPU对该中断的处理。
3、利用亲和力,可以在多处理系统中均衡各个CPU的负载。
三、中断负载均衡
是将重负载CPU上的中断迁移到较空闲的CPU上进行处理;
实现代码位于archi386kernelio-apic.c,其中balanced_irq_init函数进行中断负载均衡模块儿的初始化,同时创建一个内核线程kirqd用于执行具体的均衡处理。
而kirqd每隔5s调用一次do_irq_balanced函数,进行中断的迁徙。

    static int __init balanced_irq_init(void)
    {
        int i;
        struct cpuinfo_x86 *c;
        cpumask_t tmp;
     
     
        cpus_shift_right(tmp, cpu_online_map, 2);
            c = &boot_cpu_data;
        /* When not overwritten by the command line ask subarchitecture. */
        if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH)
            irqbalance_disabled = NO_BALANCE_IRQ;
        if (irqbalance_disabled)
            return 0;
        
         /* disable irqbalance completely if there is only one processor online */
        if (num_online_cpus() < 2) {
            irqbalance_disabled = 1;
            return 0;
        }
        /*
         * Enable physical balance only if more than 1 physical processor
         * is present
         */
        if (smp_num_siblings > 1 && !cpus_empty(tmp))
            physical_balance = 1;
     
     
        for (i = 0; i < NR_CPUS; i++) {
            if (!cpu_online(i))
                continue;
            irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
            irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
            if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) {
                printk(KERN_ERR "balanced_irq_init: out of memory");
                goto failed;
            }
            memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS);
            memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS);
        }
        
        printk(KERN_INFO "Starting balanced_irq ");
        if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0)
            return 0;
        else
            printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
    failed:
        for (i = 0; i < NR_CPUS; i++) {
            if(irq_cpu_data[i].irq_delta)
                kfree(irq_cpu_data[i].irq_delta);
            if(irq_cpu_data[i].last_irq)
                kfree(irq_cpu_data[i].last_irq);
        }
        return 0;
    }


————————————————
版权声明:本文为CSDN博主「_嵌入式_爱好者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhao2272062978/article/details/70600344

免责声明:文章转载自《Linux内核中断系列之多处理器系统中的中断处理(七)【转】》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#四舍五入vue中dom元素和组件的获取下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux下查看CPU、内存占用率

我们经常需要查看 CPU和内存占用率,否则一旦存在情况很快就会有IDC(或客户)找上门,Linux上查看资源使用情况有多种命令可以参考,CPU、内存、IO、NETWORK等资源使用情况都可以通过某些命令查询到,本文只说CPU/内存及简单的问题追踪方法。 一、top查看Linux资源占用情况 top命令可以查看CPU、内存利用率,当然这些值都是平均利用率,以...

Java获取Linux上指定文件夹下所有第一级子文件夹

说明:需要只获得第一级文件夹目录 packagecom.sunsheen.jfids.studio.monitor.utils; importjava.io.BufferedReader; importjava.io.IOException; importjava.io.InputStream; importjava.io.InputStreamRead...

[#Linux] CentOS 7 安装微信详细过程

微信安装 微信安装过程如下: 1,下载最新版本tar.gz压缩包 wget https://github.com/geeeeeeeeek/electronic-wechat/releases/download/V2.0/linux-64.tar.gz 2,解压下载的压缩包。 3,把解压的文件夹放在/opt下。 sudo mv electronic-wech...

Linux中.bash_profile 加载及profile和bashrc的区别

转载:https://www.cnblogs.com/markleaf/p/7794528.html 参考:https://www.linuxidc.com/Linux/2013-01/78005.htm 1.profile的加载顺序和优先级 1.Debian默认的shell是Bash,   1.1 命令行 和 ssh 登录 ,首先读入 /etc/pro...

安装cfssl证书工具

安装版本 cfssl 1.2 https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 下载安装包 wget http...

【转载】Linux系统下源代码包方式安装PHP开发环境

########节选自《细说PHP》################ 2.2 Linux系统下源代码包方式安装环境 在Linux平台下安装PHP有几种方法:使用配置和编译过程,或是使用各种预编译的包。在Linux上安装软件,用户最好的选择是下载源代码包,并编译一个适合自己的版本。LAMP组合中每个成员都是开源的软件,都可以从各自的官方网站上免费下载安装程序...