深入解读Linux进程调度系列(4)——调度与时钟中断

本文深入探讨Linux系统中的时钟中断及其在进程调度中的作用。时钟中断是调度和抢占的关键驱动力,涉及中断注册、执行过程、IRQ管理和固定间隔计时器中断等内容。文中以Powerpc FSL Booke架构为例,详细阐述了时钟中断的各个阶段,包括注册中断处理函数、中断执行流程、调度触发以及中断向量的计算。
摘要由CSDN通过智能技术生成
日期 内核版本 CPU架构 作者
2019.04.06 Linux-5.0 PowerPC LoneHugo

系列文章:https://blog.csdn.net/Vince_/article/details/89054330

时钟中断是系统中调度和抢占的驱动因素,在时钟中断中会进行进程运行时间的更新等,并更新调度标志,以决定是否进行调度。下面以Powerpc FSL Booke架构芯片ppce500为例来看具体代码,其他架构类似,设计思想相同。

1. 时钟中断的注册


首先在系统最开始的启动阶段注册中断处理函数,这个过程发生在start_kernel执行之前的汇编初始化部分,在系统初始化完成后时钟中断发生时执行中断回调函数。

IBM的PowerPC架构的内核启动入口head文件在arch/powerpc/kernel/下,其中e500架构的内核入口文件为head_fsl_booke.S,其中定义了中断向量列表:

interrupt_base:
    /* Critical Input Interrupt */
    CRITICAL_EXCEPTION(0x0100, CRITICAL, CriticalInput, unknown_exception)
    ......
    
    /* Decrementer Interrupt */
    DECREMENTER_EXCEPTION
    ......

时钟中断的定义为DECREMENTER_EXCEPTION,实际展开过程在arch/powerpc/kernel/head_booke.h头文件中:

#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)    \
    li    r10,trap;                    \
    stw    r10,_TRAP(r11);                    \
    lis    r10,msr@h;                    \
    ori    r10,r10,msr@l;                    \
    copyee(r10, r9);                    \
    bl    tfer;                         \
    .long    hdlr;                        \
    .long    ret

#define EXC_XFER_LITE(n, hdlr)        \
    EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
              ret_from_except)

#define DECREMENTER_EXCEPTION                              \
    START_EXCEPTION(Decrementer)                          \
    NORMAL_EXCEPTION_PROLOG(DECREMENTER);              \
    lis     r0,TSR_DIS@h;           /* Setup the DEC interrupt mask */    \
    mtspr   SPRN_TSR,r0;        /* Clear the DEC interrupt */          \
    addi    r3,r1,STACK_FRAME_OVERHEAD;                      \
    EXC_XFER_LITE(0x0900, timer_interrupt)

再来看timer_interrupt函数:

static void __timer_interrupt(void)
{
    struct pt_regs *regs = get_irq_regs();
    u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
    struct clock_event_device *evt = this_cpu_ptr(&decrementers);
    u64 now;

    trace_timer_interrupt_entry(regs);

    if (test_irq_work_pending()) {
        clear_irq_work_pending();
        irq_work_run();
    }

    now = get_tb_or_rtc();
    if (now >= *next_tb) {
        *next_tb = ~(u64)0;
        if (evt->event_handler)
            evt->event_handler(evt);
        __this_cpu_inc(irq_stat.timer_irqs_event);
    } else {
        now = *next_tb - now;
        if (now <= DECREMENTER_MAX)
            set_dec((int)now);
        /* We may have raced with new irq work */
        if (test_irq_work_pending())
            set_dec(1);
        __this_cpu_inc(irq_stat.timer_irqs_others);
    }

#ifdef CONFIG_PPC64
    /* collect purr register values often, for accurate calculations */
    if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
        struct cpu_usage *cu = this_cpu_ptr(&cpu_usage_array);
        cu->current_tb = mfspr(SPRN_PURR);
    }
#endif

    trace_timer_interrupt_exit(regs);
}

/*
 * timer_interrupt - gets called whe
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值