zoukankan      html  css  js  c++  java
  • Linux内核中断系列之多处理器系统中的中断处理(七)【转】

    转自: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

  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/13361574.html
Copyright © 2011-2022 走看看