Re: NMI handling rework for x86

From: Corey Minyard (cminyard@mvista.com)
Date: Fri Nov 15 2002 - 14:35:16 EST


John Levon wrote:

>>I have also created a kernel module that loops requesting and releasing
>>the NMI, and counting the number of NMIs that actually get hit by the
>>handler that is installed.. This is on a dual 2.8GHZ Pentium 4 machine
>>with hyperthreading (so 4 processors, sort of). I have six processes
>>doing the request/release and some other processes eating CPU on each
>>processor. This has been running for almost three hours, about
>>10,000,000 NMIs have occurred (around 1000/sec). Around 4700 NMIs have
>>been caught by the handler, meaning that it was a close race between the
>>removal and the NMI occurring. So it looks good.
>>
>>
>
>Can you send me the test module so I don't have to bother writing one
>myself ?
>
>I'll try to test this weekend
>
Certainly. It's attached.

Thanks,

-Corey


#include <linux/config.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/nmi.h>
#include <linux/notifier.h>
#include <asm/atomic.h>

static atomic_t nmi_count = ATOMIC_INIT(0);
static atomic_t request_count = ATOMIC_INIT(0);

static int
do_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
{
        atomic_inc(&nmi_count);
        return NOTIFY_DONE;
}

static ssize_t do_read(struct file *file,
                       char *buf,
                       size_t count,
                       loff_t *ppos)
{
        int rv;
        long last_jiffies = jiffies;
        struct nmi_handler nmi_handler =
        {
                .link = LIST_HEAD_INIT(nmi_handler.link),
                .dev_name = "nmi_test",
                .dev_id = NULL,
                .handler = do_nmi,
                .priority = 0, /* Call us last. */
        };

        printk("NMI test: start test\n");

        for (;;) {
                if (signal_pending(current))
                        return -ERESTARTSYS;
                
                rv = request_nmi(&nmi_handler);
                if (rv) {
                        printk(KERN_WARNING
                               "NMI test: Can't register nmi handler\n");
                        return rv;
                }

// set_current_state(TASK_INTERRUPTIBLE);
// schedule_timeout(1);

                release_nmi(&nmi_handler);

                atomic_inc(&request_count);
                if ((jiffies - last_jiffies) >= HZ) {
                        last_jiffies = jiffies;
                        printk("NMIs = %d, requests=%d\n",
                               atomic_read(&nmi_count),
                               atomic_read(&request_count));
                }
        }
        return 0;
}

static int do_open(struct inode *ino, struct file *filep)
{
        return 0;
}

static int do_close(struct inode *ino, struct file *filep)
{
        printk("NMI test: in close\n");
        return 0;
}

static struct file_operations nmi_test_fops = {
        .owner = THIS_MODULE,
        .read = do_read,
        .write = NULL,
        .ioctl = NULL,
        .open = do_open,
        .release = do_close,
};

static struct miscdevice nmi_test_miscdev = {
        130,
        "nmi_test",
        &nmi_test_fops
};

static int __init nmi_test_init(void)
{
        int rv;

        rv = misc_register(&nmi_test_miscdev);
        if (rv < 0) {
                printk("NMI test: Unable to register misc device\n");
                return rv;
        }

        printk(KERN_INFO "NMI test by "
               "Corey Minyard (minyard@mvista.com)\n");

        return 0;
}

static void __exit nmi_test_exit(void)
{
        /* Make sure no one can call us any more. */
        misc_deregister(&nmi_test_miscdev);
}
module_exit(nmi_test_exit);
module_init(nmi_test_init);
MODULE_LICENSE("GPL");

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Nov 15 2002 - 22:00:39 EST