zoukankan      html  css  js  c++  java
  • 内核抢占

    内核抢占是一个软件特性,并不是一个硬件特性

    我之所以在perf record -e kprobes:schedule -g -a 没发现时钟中断,是因为我的内核根本就没有开启内核的抢占,不对啊,用户态也应该发生调度啊!

    -- 所以啊并不是说我不能找到这个值而是说

    --为啥没有抓到时钟中断引起的调度呢?时钟中断是如何作用调度的?时钟中断只会判断是否need resched,并不会在中断函数中发生调度!中断函数返回用户态的时候可能会发生调度比如抓到了大量的函数prepare_exit_to_usermode,所以中断处理函数是干嘛的呀

     2f6a31 do_timer (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      2fe48c tick_sched_do_timer (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      2fe519 tick_sched_timer (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      2ef212 __hrtimer_run_queues (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      2ef9d8 hrtimer_interrupt (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      252f88 local_apic_timer_interrupt (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      a26f9d smp_apic_timer_interrupt (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      a25262 apic_timer_interrupt (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      8bbbc7 cpuidle_enter (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      2c3d52 call_cpuidle (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
                      2c4010 cpu_startup_entry (/usr/lib/debug/boot/vmlinux-4.4.0-21-generic)
    

    能抓到do_timer函数,说明时钟中断没有被屏蔽,但是

    (3) 通过把抢占计数器设置为正而显式禁止内核抢占,由preempt_disable完成。 当从中断返回内核空间时,内核会检preempt_count和need_resched的值(返回用户空间时只需要检查need_resched),如查preempt_count为0且need_resched设置,则调用schedule(),完成任务抢占。一般来说,内核抢占发生以下情况: (1) 从中断(异常)返回时,preempt_count为0且need_resched置位(见从中断返回); (2) 在异常处理程序中(特别是系统调用)调用preempt_enable()来允许内核抢占发生; --------------------- 作者:Tommy_wxie 来源:CSDN 原文:https://blog.csdn.net/tommy_wxie/article/details/7425728?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!link

    #ifdef CONFIG_PREEMPT
    ENTRY(resume_kernel)
        DISABLE_INTERRUPTS(CLBR_ANY)
    need_resched:
        cmpl    $0, PER_CPU_VAR(__preempt_count)
        jnz restore_all
        testl   $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ?
        jz  restore_all
        call    preempt_schedule_irq
        jmp need_resched
    

     也就是说在内核抢占关闭的情况下,__preempt_count

    在抢占开启的情况下,是会有抢占发生的,真是揪心:

      64 #ifdef CONFIG_PREEMPT
      65 # define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF
      66 #else //----------->在CONFIG_PREEMPT关闭的情况下,resume_kernel竟然直接就替换成了restore_all,这个restore_all不就是上文中在config_preempt开启的情况下要走到的那个路径嘛。。。所以这就没跑了,当内核中关闭了抢占之后,时钟中断根本就不会发生调度。
      67 # define preempt_stop(clobbers)
      68 # define resume_kernel      restore_all
      69 #endif
      70

    那么几乎所有的博客中都会提到的thread_info中的又是啥呢?这就是抢占的软件机制之所在了;首先,这个问题只会出现在抢占内核中呢,在抢占内核中,有的地方要避免抢占,只要抢占关闭了,那么肯定就不会发生抢占了呀,为啥还要关闭中断呢

    每次进入临界区都要关闭抢占,抢占是针对同一个和上的操作
     

  • 相关阅读:
    POJ2001Shortest Prefixes[Trie]
    UVA
    POJ2528Mayor's posters[线段树 离散化]
    COGS130. [USACO Mar08] 游荡的奶牛[DP]
    POJ1962Corporative Network[带权并查集]
    BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]
    洛谷U4859matrix[单调栈]
    COGS247. 售票系统[线段树 RMQ]
    COGS1008. 贪婪大陆[树状数组 模型转换]
    COGS182 [USACO Jan07] 均衡队形[RMQ]
  • 原文地址:https://www.cnblogs.com/honpey/p/9821478.html
Copyright © 2011-2022 走看看