现状

目前DragonOS的时间子系统,更新墙上时间其实是直接在时钟中断里面,调用update walltime,并且手动指定delta值来更新的。这导致了没法利用上时间子系统的校时相关的功能。并且,时间源并不一定是有时钟事件的。因此我最近在尝试把dragonos移植到云服务器的过程中,发现kvm-clock是没有时钟中断的,并且配置acpi pm timer的中断的教程/文档,我看了很久看不明白(后来是发现Linux的acpi_sci_ioapic_setup这个函数设置了acpi中断,但是目前dragonos里面实现它,难度还是有的)。

于是乎,就面临这样一个情况:时钟源没有时钟中断,因此必须在某种类型的时钟事件里面,读取时钟源,更新墙上时钟。

目前,DragonOS在riscv下面的做法就是这样的,在0号核心的调度时钟中断里面,更新墙上时钟:

https://code.dragonos.org.cn/xref/DragonOS/kernel/src/driver/clocksource/timer_riscv.rs?r=0102d69fdd231e472d7bb3d609a41ae56a3799ee#72

其实riscv里面的这个做法很暴力,因为他没有为tsc实现时间源这个trait。这是需要修改的地方。

Linux里面的做法

我翻了一下linux 6.6.21里面的做法,是在tick_handle_periodic里面,调用tick_periodic。

看tick_periodic的实现,是不是有点眼熟?他是指定了某个cpu来处理墙上时钟的更新。然后所有核心都会在这里更新进程的时间(update_process_times)。

然后,update_wall_time的实现就是调用这个函数 timekeeping_advance

https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/time/timekeeping.c?fi=update_wall_time#2150

在这里主动去读取当前时钟源,并且计算当前值跟之前的值之间的delta,然后更新。

思路

目前的思路是模仿Linux的做法,把墙上时钟更新的操作,改为“读取计数,接着计算偏移量,然后更新”。

这几天我打算按照上述思路修改dragonos的代码。

转载请注明来源:https://longjin666.cn/1869/

欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~

你也可能喜欢

发表评论