【问题标题】:How to get current CPU usage with Linux Kernel Module?如何使用 Linux 内核模块获取当前 CPU 使用率?
【发布时间】:2021-01-14 13:31:39
【问题描述】:

我想使用 Linux 内核模块获取当前 CPU 和内存使用情况。感谢this documentation,内存非常简单,但是从cpuinfo.c 获取CPU 使用率是一个相当大的挑战。我搜索了很多文档,但没有任何有用的东西。

到目前为止我的代码

/**
 * @file    modulo.c
 * @author  Some College Student
 * @date    2020 Sep
 * @version 0.1
 * @brief   Memory and CPU usage
 *
*/


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
#include <linux/cpufreq.h>

void __attribute__((weak)) arch_report_meminfo(struct seq_file *m){}

static int my_proc_show(struct seq_file *m, void *v){
    struct sysinfo i;
    struct cpufreq_policy *cp;
    unsigned long uc_temp, tc_temp, um_temp, tm_temp;

    si_meminfo(&i); //gets memory info
    um_temp = i.totalram - i.freeram; //used memory
    tm_temp = i.totalram; //total memory

    //cp = cpufreq_cpu_get(0); //returning 0
    //uc_temp = cp->cur - cp->min; //usec cpu freq
    //tc_temp = cp->max - cp->min; //total cpu freq
    uc_temp = 0;
    tc_temp = 0;

    seq_printf(m, "{\n\t\"um_temp\":%lu,\n\t\"tm_temp\":%lu,\n\t\"uc_temp\":%lu,\n\t\"tc_temp\":%lu\n}\n", um_temp, tm_temp, uc_temp, tc_temp); //writing in JSON format in /proc/modulo file

    arch_report_meminfo(m);

    return 0;
}

static int my_proc_open(struct inode *inode, struct file *file){
    return single_open(file, my_proc_show, NULL);
}

static ssize_t my_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *f_pos){
    return 0;
}

static struct file_operations my_fops={
    .owner = THIS_MODULE,
    .open = my_proc_open,
    .release = single_release,
    .read = seq_read,
    .llseek = seq_lseek,
    .write = my_proc_write
};

static int __init modulo_init(void){
    struct proc_dir_entry *entry;
    entry = proc_create("modulo", 0777, NULL, &my_fops);
    if(!entry) {
        return -1;    
    } else {
        printk(KERN_INFO "Start\n");
    }
    return 0;
}

static void __exit modulo_exit(void){
    remove_proc_entry("modulo",NULL);
    printk(KERN_INFO "End\n");
}

module_init(modulo_init);
module_exit(modulo_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Memory and CPU usage");
MODULE_AUTHOR("Some College Student");

我很好地从这段记忆中恢复过来,但我的两个 cpu 频率都为 0。提前感谢您的帮助。

【问题讨论】:

    标签: c linux linux-kernel ubuntu-20.04


    【解决方案1】:

    您应该能够使用cpufreq_get() 函数获取给定 CPU 的当前频率。该函数直接返回CPU频率,不用担心手动从当前cpufreq_policy中提取不同的函数。

    或者,您可以通过cpufreq_quick_get() 获取最后已知的 CPU 频率。

    下面是一个针对所有在线 CPU 使用 cpufreq_get() 的工作示例:

    // SPDX-License-Identifier: GPL-3.0
    #include <linux/kernel.h>  // printk(), pr_*()
    #include <linux/module.h>  // THIS_MODULE, MODULE_VERSION, ...
    #include <linux/init.h>    // module_{init,exit}()
    #include <linux/smp.h>     // get_cpu(), put_cpu()
    #include <linux/cpufreq.h> // cpufreq_get()
    #include <linux/cpumask.h> // cpumask_{first,next}(), cpu_online_mask
    
    #ifdef pr_fmt
    #undef pr_fmt
    #endif
    #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
    
    static int __init modinit(void)
    {
            unsigned cpu = cpumask_first(cpu_online_mask);
    
            while (cpu < nr_cpu_ids) {
                    pr_info("CPU: %u, freq: %u kHz\n", cpu, cpufreq_get(cpu));
                    cpu = cpumask_next(cpu, cpu_online_mask);
            }
    
            return 0;
    }
    
    static void __exit modexit(void)
    {
            // Empty function only to be able to unload the module.
            return;
    }
    
    module_init(modinit);
    module_exit(modexit);
    MODULE_VERSION("0.1");
    MODULE_DESCRIPTION("Get CPU frequency for currently online CPUs.");
    MODULE_AUTHOR("Marco Bonelli");
    MODULE_LICENSE("GPL");
    

    我的机器上的结果:

    [ 2168.420286] cpufreq: CPU: 0, freq: 1333000 kHz
    [ 2168.420321] cpufreq: CPU: 1, freq: 1200000 kHz
    [ 2168.420358] cpufreq: CPU: 2, freq: 1333000 kHz
    [ 2168.420364] cpufreq: CPU: 3, freq: 1600000 kHz
    [ 2168.420372] cpufreq: CPU: 4, freq: 1333000 kHz
    [ 2168.420402] cpufreq: CPU: 5, freq: 2400000 kHz
    [ 2168.420442] cpufreq: CPU: 6, freq: 1200000 kHz
    [ 2168.420444] cpufreq: CPU: 7, freq: 1200000 kHz
    

    【讨论】:

    • 仍然返回零,唯一不同的是我在虚拟机中。
    • @Askaredox 嗯,这可能是您的虚拟机的限制?我们在谈论什么虚拟机和架构?还有哪个内核版本?
    • 这是一个 AWS EC2 实例,Ubuntu Server 20.04 和 linux 内核 "5.4.0-1025-aws"
    猜你喜欢
    • 1970-01-01
    • 2021-06-10
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2023-03-30
    • 2011-03-02
    相关资源
    最近更新 更多