用户USER_HZ与内核HZ的值

定义

内核文件include/asm-generic/param.h定义了两者的值:

# undef HZ
# define HZ     CONFIG_HZ   /* Internal kernel timer frequency */
# define USER_HZ    100     /* some user interfaces are */
# define CLOCKS_PER_SEC (USER_HZ)       /* in "ticks" like times() */

其中CONFIG_HZ为通过make menuconfig配置的HZ值,一般为1000,即每秒钟jiffies增加1000个计数。实际值可参见代码中include/generated/autoconf.h文件。USER_HZ固定为100,用户层调用times系统调用,返回的是按照USER_HZ计算的jiffies值。

u64 jiffies_64_to_clock_t(u64 x)
{
	...
    x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ));
    return x;
}

SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
{
	...
    return (long) jiffies_64_to_clock_t(get_jiffies_64());
}

用户层与内核之间相关交互

两者定义的差别导致用户层与内核交互时,需要进行转换。除了以上的64位转换函数jiffies_64_to_clock_t。内核还提供了另外两个互换函数:

kernel/time.c

clock_t jiffies_to_clock_t(unsigned long x)
{
    return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ);
}

unsigned long clock_t_to_jiffies(unsigned long x)
{
    return x * (HZ / USER_HZ);
}

Linux网桥的ioctl为例

代码位于文件net/bridge/br_ioctl.c中,示例为设置和获取bridge表项的最大超时时间:

static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
    unsigned char mac[ETH_ALEN];
    struct net_bridge *br = netdev_priv(dev);
    unsigned long args[4];

    if (copy_from_user(args, rq->ifr_data, sizeof(args)))
        return -EFAULT;

    switch (args[0]) {
	
    case BRCTL_GET_BRIDGE_INFO:
    {
        struct __bridge_info b;
        b.max_age = jiffies_to_clock_t(br->max_age); //转化为USER_HZ表示的clock
		return 0;
	}
    case BRCTL_SET_BRIDGE_MAX_AGE:
	{
		unsigned long t = clock_t_to_jiffies(args[1]); //转化为HZ表示的jiffies
		br->bridge_max_age = t;
		return 0;
	}
}

获取运行系统HZ值

网络中邻居表的locktime参数,默认设置的是一个HZ,通过proc文件可读取:

cat /proc/sys/net/ipv4/neigh/ens160/locktime
100

内核版本

linux-3.10.0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值