You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux 0.11内核hd_out后磁盘准备数据时的运行机制问询

Linux 0.11磁盘IO流程疑问:等待磁盘就绪时内核行为分析

我正在研究Linux 0.11内核源码,重点分析磁盘数据读取至内存的流程,目前正对hd.c中的hd_out函数及关联的do_hd_request函数进行解析。相关代码片段如下:

#define CURRENT (blk_dev[MAJOR_NR].current_request)

// hd.c
void do_hd_request(void) {
    ...
    unsigned int dev = MINOR(CURRENT->dev);
    unsigned int block = CURRENT->sector;
    ...
    nsect = CURRENT->nr_sectors;
    ...
    if (CURRENT->cmd == WRITE) {
        hd_out(dev, nsect, sec, head, cyl, WIN_WRITE, &write_intr);
        // Poll status register to check if ready to write
        for (i = 0; i < 3000 && !(r = inb_p(HD_STATUS) & DRQ_STAT); i++);
        if (!r) {
            bad_rw_intr();
            goto repeat;
        }
        port_write(HD_DATA, CURRENT->buffer, 256);
    } else if (CURRENT->cmd == READ) {
        hd_out(dev, nsect, sec, head, cyl, WIN_READ, &read_intr);
    } else
        panic("unknown hd-command");
}

static void hd_out(unsigned int drive, unsigned int nsect, unsigned int sect,
                   unsigned int head, unsigned int cyl, unsigned int cmd,
                   void (*intr_addr)(void)) {
    ...
    do_hd = intr_addr;
    outb_p(hd_info[drive].ctl, HD_CMD);
    port = HD_DATA;
    outb_p(hd_info[drive].wpcom >> 2, ++port);
    outb_p(nsect, ++port);
    outb_p(sect, ++port);
    outb_p(cyl, ++port);
    outb_p(cyl >> 8, ++port);
    outb_p(0xA0 | (drive << 4) | head, ++port);
    outb(cmd, ++port);
}

据我理解,hd_out会向磁盘下发命令并绑定对应的中断处理函数(如read_intr或write_intr),随后磁盘开始准备数据。我的核心问题是:磁盘准备数据期间,Linux 0.11内核会执行什么操作?

我原本认为内核会切换至其他进程(如通过定时器中断),但调试时发现hd_out执行后直接进入磁盘中断处理函数(如hd_interrupt),仿佛磁盘立即就绪,这与预期的进程切换行为不符。我有以下疑问:

  1. 等待磁盘准备数据时,内核是否会进行进程切换?
  2. 若不进行进程切换,内核如何避免浪费CPU周期?

问题解答

1. 等待磁盘准备数据时的进程切换行为

Linux 0.11在磁盘准备数据阶段不会主动触发进程切换,但存在两种不同场景的差异:

  • 写操作场景:代码中写操作后会执行一段有限次数的轮询逻辑,这段轮询完全阻塞在当前上下文,期间不会切换进程。
  • 读操作场景:调用hd_out下发读命令后,do_hd_request函数会直接返回。如果当前是用户进程发起的IO,内核会回到系统调用处理流程,最终通过schedule()触发进程切换;如果是内核线程发起的IO,则会继续执行其他内核逻辑,直到下一次定时器中断触发调度。

你调试时看到hd_out后直接进入hd_interrupt,大概率是因为虚拟机环境下磁盘IO被模拟为即时完成,物理磁盘的机械寻道、数据准备延迟被大幅缩短,导致磁盘中断几乎立刻触发,看起来像是没有切换进程就进入了中断处理。

2. 避免CPU周期浪费的机制

Linux 0.11针对磁盘IO等待的CPU浪费问题,主要通过以下方式处理:

  • 中断驱动IO:读操作完全依赖中断触发,下发命令后内核不会原地等待,而是回到调度流程让其他进程执行,直到磁盘准备好数据后发送中断,再唤醒等待的进程处理数据。
  • 有限轮询+失败回退:写操作的轮询设置了3000次的上限,若超时则调用bad_rw_intr()标记请求失败并重新处理,不会无限占用CPU;这个次数是基于早期磁盘的响应速度设置的,属于平衡延迟和CPU占用的折中方案。
  • 定时器调度:即使内核在某些场景下处于空闲等待,默认10ms一次的定时器中断会定期触发schedule(),切换到就绪队列中的其他进程,避免CPU空转。

内容的提问来源于stack exchange,提问作者0x1B05

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:39:55