Kernel 监视器/Mwait在内核空间中不工作

Kernel 监视器/Mwait在内核空间中不工作,kernel,Kernel,我想测试monitor/mwait是否在内核中工作。所以我创建了一个模块,其中启动了两个任务,task2将调用monitor/mwait进行睡眠。Task1修改待命地址以唤醒task2。但代码似乎不起作用。mwait的行为就像没有。我使用cpu_has函数检查监视器/mwait的可用性,我的处理器确实支持它 关于如何在内核空间中使用monitor/mwait,您能给我一些提示或一些示例代码吗 #include <linux/module.h> #include <asm/mwa

我想测试monitor/mwait是否在内核中工作。所以我创建了一个模块,其中启动了两个任务,task2将调用monitor/mwait进行睡眠。Task1修改待命地址以唤醒task2。但代码似乎不起作用。mwait的行为就像没有。我使用cpu_has函数检查监视器/mwait的可用性,我的处理器确实支持它

关于如何在内核空间中使用monitor/mwait,您能给我一些提示或一些示例代码吗

#include <linux/module.h>
#include <asm/mwait.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/desc.h>
#include <linux/kthread.h>

/* global varaible */
char msg[200];
struct task_struct *task1;
struct task_struct *task2;
unsigned int addr = 0;

/* print message to console */
int write_console (char *str)
{
         struct tty_struct *my_tty;
         if((my_tty=current->signal->tty) != NULL)
         {
                ((my_tty->driver->ops->write) (my_tty,str,strlen(str)));
                return 0;
         }
         else return -1;
}

int thread_func1(void *data)
{
    msleep(5000);
    addr = 1;
    while(!kthread_should_stop()){
        schedule();
    }
    return 0;
}

int thread_func2(void *data)
{
    while(addr == 0){
        clflush(&addr);
        __monitor(&addr, 0, 0);
        if(addr == 0){
            __mwait(0,0);
            printk(KERN_INFO "wake up\n");
        }
    }

    while(!kthread_should_stop()){
        schedule();
    }
    return 0;
}

int __init my_test_init(void){
    struct cpuinfo_x86 *c = &boot_cpu_data;
    write_console("enter module\r\n");
    if (cpu_has(c, X86_FEATURE_MWAIT)) {
        write_console("monitor/mwait supported\r\n");
    }
    task1 = kthread_create(&thread_func1, NULL, "thread_func1");
    task2 = kthread_create(&thread_func2, NULL, "thread_func2");
    if(task1){ wake_up_process(task1); }
    if(task2){ wake_up_process(task2); }

    return 0;
}

void __exit my_test_exit(void){
    kthread_stop(task1);
    kthread_stop(task2);
    write_console("leave \r\n");
}

module_init(my_test_init);
module_exit(my_test_exit);
MODULE_LICENSE("GPL");
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*全局变量*/
char-msg[200];
结构任务_结构*task1;
结构任务_struct*task2;
无符号整数addr=0;
/*将消息打印到控制台*/
int write_控制台(char*str)
{
struct tty_struct*my\u tty;
如果((my_tty=当前->信号->tty)!=NULL)
{
((my_tty->driver->ops->write)(my_tty,str,strlen(str));
返回0;
}
否则返回-1;
}
int thread_func1(void*数据)
{
msleep(5000);
addr=1;
而(!kthread_should_stop()){
附表();
}
返回0;
}
int thread_func2(void*数据)
{
while(addr==0){
clflush&addr;
__监视器(&addr,0,0);
if(addr==0){
__mwait(0,0);
printk(内核信息“唤醒”\n);
}
}
而(!kthread_should_stop()){
附表();
}
返回0;
}
int\uu init my\u test\u init(无效){
结构cpuinfo_x86*c=&boot_cpu_数据;
写入控制台(“输入模块”\r\n);
如果(cpu有(c,X86功能){
写入控制台(“支持监视器/mwait\r\n”);
}
task1=kthread_create(&thread_func1,NULL,“thread_func1”);
task2=kthread_create(&thread_func2,NULL,“thread_func2”);
if(task1){唤醒进程(task1)}
if(task2){唤醒进程(task2)}
返回0;
}
无效\uuu退出我的测试\u退出(无效){
kthread_stop(任务1);
kthread_stop(任务2);
写入控制台(“离开”);
}
模块初始化(我的测试初始化);
模块退出(我的测试退出);
模块许可证(“GPL”);