Linux 内核 v5 中 current_kernel_time 的等价物是什么?

Pta*_*666 3 c linux-kernel

我尝试在内核版本为 5.0.0-38-generic 的 Linux Ubuntu 19.04 机器上从 Pleora eBUS SDK 编译一些内核模块,但出现编译错误:

error: implicit declaration of function ‘current_kernel_time’; did you mean ‘core_kernel_text’? [-Werror=implicit-function-declaration]
  lTime = current_kernel_time();
Run Code Online (Sandbox Code Playgroud)

和另一个(相同的问题) function do_gettimeofday

我注意到了这一点,current_kernel_time并且current_kernel_time64在内核 v4.15 中仍然可用(例如,我的另一台机器使用 Ubuntu 18.04),最后一次出现在linux v4.19.97 中。在我的内核版本的time.h标头中,有一个函数get_timespec64似乎在做类似的事情,但是它接受 2 个参数,对我来说似乎不正确(因为在我看到的来源中,有一个copy_from_user被调用的)传递一些未初始化const struct __kernel_timespec __user *uts为第二个参数。有人可以给我一些提示如何current_kernel_time在我的较新内核版本中替换对 的调用吗?

需要修改的示例代码:

OS_UINT64 OS_TimeGetUS( OS_VOID )
{
    struct timespec64 lTime;
    lTime = current_kernel_time();
    return ( lTime.tv_sec * 1000000 + OS_DIV64( lTime.tv_nsec, 1000 ) );
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 7

current_kernel_time()函数被弃用并移至timekeeping32.hv4.15 ( commit ),然后在 v4.20 ( commit ) 中完全删除。v4.18 ( commit )中引入了较新的计时功能。

新导出的函数是(source):

extern void ktime_get_raw_ts64(struct timespec64 *ts);
extern void ktime_get_ts64(struct timespec64 *ts);
extern void ktime_get_real_ts64(struct timespec64 *tv);
extern void ktime_get_coarse_ts64(struct timespec64 *ts);
extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
Run Code Online (Sandbox Code Playgroud)

另请参阅相关的内核文档页面,其中指出:

不推荐使用的时间接口

[...]

struct timespec current_kernel_time(void)
struct timespec64 current_kernel_time64(void)
struct timespec get_monotonic_coarse(void)
struct timespec64 get_monotonic_coarse64(void)
Run Code Online (Sandbox Code Playgroud)

这些由ktime_get_coarse_real_ts64()和代替ktime_get_coarse_ts64()。然而,许多需要粗粒度时间的代码可以使用简单的“jiffies”来代替,而现在一些驱动程序实际上可能需要更高分辨率的访问器。


您可以将代码重写为:

OS_UINT64 OS_TimeGetUS( OS_VOID )
{
    struct timespec64 lTime;
    ktime_get_coarse_real_ts64(&lTime);
    return (lTime.tv_sec * 1000000 + OS_DIV64( lTime.tv_nsec, 1000 ) );
}
Run Code Online (Sandbox Code Playgroud)

但是我看到您以微秒为单位返回时间。在这种情况下,您可能希望直接使用ktime_t ktime_get(void)或等效的u64 ktime_get_ns(void). 您提供的代码片段可以重写为:

OS_UINT64 OS_TimeGetUS( OS_VOID )
{
    return OS_DIV64(ktime_get_ns(), 1000);
}
Run Code Online (Sandbox Code Playgroud)