现状
目前DragonOS的时间子系统,更新墙上时间其实是直接在时钟中断里面,调用update walltime,并且手动指定delta值来更新的。这导致了没法利用上时间子系统的校时相关的功能。并且,时间源并不一定是有时钟事件的。因此我最近在尝试把dragonos移植到云服务器的过程中,发现kvm-clock是没有时钟中断的,并且配置acpi pm timer的中断的教程/文档,我看了很久看不明白(后来是发现Linux的acpi_sci_ioapic_setup这个函数设置了acpi中断,但是目前dragonos里面实现它,难度还是有的)。
于是乎,就面临这样一个情况:时钟源没有时钟中断,因此必须在某种类型的时钟事件里面,读取时钟源,更新墙上时钟。
目前,DragonOS在riscv下面的做法就是这样的,在0号核心的调度时钟中断里面,更新墙上时钟:
其实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的代码。