从零写OS(四十九):消灭 static 缓冲区

内核模块跑起来之后,发现 SMP 下偶发崩溃。追查下去,发现是一类隐藏很深的 bug:static 局部缓冲区。 static 局部变量在 SMP 下是定时炸弹 // ext2.c 里随处可见这样的代码 int ext2_read(uint32_t inum, ...) { static uint8_t blk[4096]; // 危险! // ... } static 局部变量存在 .bss 段里,整个内核只有一份。单核下没问题,但 SMP 下: CPU0 和 CPU1 同时读不同的文件 都调用 ext2_read,都在用同一个 blk[] 互相覆盖对方的数据 → 文件读出来是乱的 ext2.c 里有十几处这样的 static 缓冲区,vfs.c 里也有。全部改成 kmalloc: // 修改后 uint8_t *blk = (uint8_t *)kmalloc(block_size); if (!blk) return -1; // ... 使用 ... kfree(blk); 同时还有一个更隐蔽的问题:间接块的 LBA 缓存: // 修改前:有状态缓存,SMP 下竞争 static uint32_t ind1[1024]; static uint32_t ind1_bno = 0; // 上次读的 LBA,用来判断是否要重读 if (ind1_bno != inode.i_block[12]) { ind1_bno = inode.i_block[12]; read_block(ind1_bno, ind1); } 两个核心同时修改 ind1_bno,都以为自己读的数据有效——去掉缓存,每次都读: ...

June 4, 2026 · 1 min · 大飞
京ICP备14031575号-3