【问题标题】:Why disable interrupts in XV6 scheduler?为什么要在 XV6 调度程序中禁用中断?
【发布时间】:2020-06-11 21:53:09
【问题描述】:

对于 XV6 中的 sched() 函数 (proc.c)

  1. 为什么在进行上下文切换时必须禁用中断?是不是因为如果开启了中断,sched函数会被重复调用?
  2. 为什么 ncli(pushcli 嵌套的深度)必须等于 1?
   sched(void) {
      int intena;

      if(readeflags()&FL_IF)
        panic("sched interruptible");
      if(cp->state == RUNNING)
        panic("sched running");
      if(!holding(&ptable.lock))
        panic("sched ptable.lock");
      if(c->ncli != 1)
        panic("sched locks");

      intena = c->intena;
      swtch(&cp->context, &c->context);
      c->intena = intena;
    }

【问题讨论】:

    标签: locking scheduler interrupt osdev xv6


    【解决方案1】:
    1. 为什么在进行上下文切换时必须禁用中断?是不是因为如果开启了中断,sched函数会被重复调用?

    每个任务都有状态,其中包括 CPU 的状态和操作系统用来跟踪事物的各种变量的状态(例如,当前正在运行的任务)。 switch() 函数从一个任务的状态切换到另一个;但它不会以原子方式执行此操作。如果在switch() 正在从一个任务切换到另一个任务时发生 IRQ,那么 IRQ 处理程序将看到不一致的状态(例如,“当前正在运行的任务”变量与当前的虚拟地址空间不匹配)可以/将会导致极难重现的细微错误(因为您必须准确把握问题发生的时机)并且极难找到和修复。

    请注意,支持多个 CPU 的操作系统不能依靠“禁用 IRQ”来防止重入问题(例如,在一个 CPU 上禁用 IRQ 不会阻止另一个 CPU 在其已经运行时调用 sched())。为了这; XV6(确实支持多个 CPU)使用锁(ptable.lock)。

    1. 为什么 ncli(pushcli 嵌套的深度)必须等于 1?

    从 CPU 的角度来看:

    • 一个任务导致ncli被设置为1
    • 发生任务切换
    • 另一个任务导致 ncli 减为零

    从任务的角度来看:

    • 任务导致ncli 设置为1
    • 会发生许多任务切换(而其他任务会获得 CPU 时间),直到任务再次获得 CPU 时间
    • 任务导致ncli 减为零

    这两种观点都需要兼容。例如,如果一项任务导致ncli 设置为2,那么(在任务切换后)将ncli 递减两次;那么“从该任务的角度来看”它会很好,但是“从 CPU 的角度来看”它会中断(不同的任务只会减少 ncli 一次,导致 IRQ 在不应该被禁用时被禁用)。

    换句话说,ncli 必须始终是相同的值。选择值 1 可能是因为它对大多数调用者来说“足够好”,并且使用更高的值会增加不必要的开销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      • 1970-01-01
      相关资源
      最近更新 更多