Ver Fonte

修复clock_gettime返回类型错误,修复小时间间隔duration返回0问题 (#664)

* 修复clock_gettime返回类型错误,修正wtm初始化逻辑

* 修复duration在小时间间隔下为0的问题

* 临时修复时间流逝速度异常,在test-mount中加入运行时间检测
Donkey Kane há 1 ano atrás
pai
commit
911132c4b8

+ 3 - 3
kernel/src/time/syscall.rs

@@ -8,7 +8,7 @@ use crate::{
     time::{sleep::nanosleep, TimeSpec},
 };
 
-use super::timekeeping::do_gettimeofday;
+use super::timekeeping::{do_gettimeofday, getnstimeofday};
 
 pub type PosixTimeT = c_longlong;
 pub type PosixSusecondsT = c_int;
@@ -142,9 +142,9 @@ impl Syscall {
         let mut tp_buf =
             UserBufferWriter::new::<TimeSpec>(tp, core::mem::size_of::<TimeSpec>(), true)?;
 
-        let posix_time = do_gettimeofday();
+        let timespec = getnstimeofday();
 
-        tp_buf.copy_one_to_user(&posix_time, 0)?;
+        tp_buf.copy_one_to_user(&timespec, 0)?;
 
         return Ok(0);
     }

+ 14 - 17
kernel/src/time/timekeeping.rs

@@ -140,9 +140,10 @@ impl Timekeeper {
         let clock = timekeeper.clock.clone().unwrap();
         drop(timekeeper);
         let clock_now = clock.read();
-        let clcok_data = clock.clocksource_data();
-        let clock_delta = clock_now.div(clcok_data.watchdog_last).data() & clcok_data.mask.bits();
-        return clocksource_cyc2ns(CycleNum(clock_delta), clcok_data.mult, clcok_data.shift);
+        let clock_data = clock.clocksource_data();
+        let clock_delta = clock_now.div(clock_data.watchdog_last).data() & clock_data.mask.bits();
+        // clock_shift的值错误导致时间流逝速度异常,+5为临时修改以确保系统正常运作,目前追踪到的设置在DragonOS-dev/blob/fix_time/kernel/src/time/jiffies.rs#L18,但是修改无效
+        return clocksource_cyc2ns(CycleNum(clock_delta), clock_data.mult, clock_data.shift + 5);
     }
 }
 pub fn timekeeper() -> &'static Timekeeper {
@@ -163,7 +164,7 @@ pub fn timekeeper_init() {
 pub fn getnstimeofday() -> TimeSpec {
     // kdebug!("enter getnstimeofday");
 
-    // let mut nsecs: u64 = 0;0
+    let nsecs;
     let mut _xtime = TimeSpec {
         tv_nsec: 0,
         tv_sec: 0,
@@ -174,15 +175,15 @@ pub fn getnstimeofday() -> TimeSpec {
             Some(tk) => {
                 _xtime = tk.xtime;
                 drop(tk);
-                // nsecs = timekeeper().tk_get_ns();
+                nsecs = timekeeper().tk_get_ns();
                 // TODO 不同架构可能需要加上不同的偏移量
                 break;
             }
         }
     }
-    // xtime.tv_nsec += nsecs as i64;
-    let sec = __ADDED_SEC.load(Ordering::SeqCst);
-    _xtime.tv_sec += sec;
+    _xtime.tv_nsec += nsecs as i64;
+    // let sec = __ADDED_SEC.load(Ordering::SeqCst);
+    // _xtime.tv_sec += sec;
     while _xtime.tv_nsec >= NSEC_PER_SEC.into() {
         _xtime.tv_nsec -= NSEC_PER_SEC as i64;
         _xtime.tv_sec += 1;
@@ -224,15 +225,11 @@ pub fn timekeeping_init() {
     let mut timekeeper = timekeeper().0.write_irqsave();
     timekeeper.xtime.tv_nsec = ktime_get_real_ns();
 
-    // 初始化wall time到monotonic的时间
-    let mut nsec = -timekeeper.xtime.tv_nsec;
-    let mut sec = -timekeeper.xtime.tv_sec;
-    // FIXME: 这里有个奇怪的奇怪的bug
-    let num = nsec % NSEC_PER_SEC as i64;
-    nsec += num * NSEC_PER_SEC as i64;
-    sec -= num;
-    timekeeper.wall_to_monotonic.tv_nsec = nsec;
-    timekeeper.wall_to_monotonic.tv_sec = sec;
+    //参考https://elixir.bootlin.com/linux/v4.4/source/kernel/time/timekeeping.c#L1251 对wtm进行初始化
+    (
+        timekeeper.wall_to_monotonic.tv_nsec,
+        timekeeper.wall_to_monotonic.tv_sec,
+    ) = (-timekeeper.xtime.tv_nsec, -timekeeper.xtime.tv_sec);
 
     __ADDED_USEC.store(0, Ordering::SeqCst);
     __ADDED_SEC.store(0, Ordering::SeqCst);

+ 4 - 1
user/apps/test-mount/src/main.rs

@@ -1,7 +1,8 @@
 use core::ffi::{c_char, c_void};
 use libc::{mount, MS_BIND};
-
+use std::time;
 fn main() {
+    let clock = time::Instant::now();
     let source = b"\0".as_ptr() as *const c_char;
     let target = b"/mnt/tmp\0".as_ptr() as *const c_char;
     let fstype = b"ramfs\0".as_ptr() as *const c_char;
@@ -14,4 +15,6 @@ fn main() {
     } else {
         println!("Mount failed");
     }
+    let dur = clock.elapsed();
+    println!("mount costing time: {} ns", dur.as_nanos());
 }