Skip to content

Commit

Permalink
xen/mce: add .poll method for mcelog device driver
Browse files Browse the repository at this point in the history
If a driver leaves its poll method NULL, the device is assumed to
be both readable and writable without blocking.

This patch add .poll method to xen mcelog device driver, so that
when mcelog use system calls like ppoll or select, it would be
blocked when no data available, and avoid spinning at CPU.

Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  • Loading branch information
Liu, Jinsong authored and Konrad Rzeszutek Wilk committed Jul 19, 2012
1 parent 1b2a055 commit a867e5d
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions drivers/xen/mcelog.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/capability.h>
#include <linux/poll.h>
#include <linux/sched.h>

#include <xen/interface/xen.h>
#include <xen/events.h>
Expand All @@ -67,6 +69,8 @@ static DEFINE_SPINLOCK(xen_mce_chrdev_state_lock);
static int xen_mce_chrdev_open_count; /* #times opened */
static int xen_mce_chrdev_open_exclu; /* already open exclusive? */

static DECLARE_WAIT_QUEUE_HEAD(xen_mce_chrdev_wait);

static int xen_mce_chrdev_open(struct inode *inode, struct file *file)
{
spin_lock(&xen_mce_chrdev_state_lock);
Expand Down Expand Up @@ -135,6 +139,16 @@ static ssize_t xen_mce_chrdev_read(struct file *filp, char __user *ubuf,
return err ? err : buf - ubuf;
}

static unsigned int xen_mce_chrdev_poll(struct file *file, poll_table *wait)
{
poll_wait(file, &xen_mce_chrdev_wait, wait);

if (xen_mcelog.next)
return POLLIN | POLLRDNORM;

return 0;
}

static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd,
unsigned long arg)
{
Expand Down Expand Up @@ -166,6 +180,7 @@ static const struct file_operations xen_mce_chrdev_ops = {
.open = xen_mce_chrdev_open,
.release = xen_mce_chrdev_release,
.read = xen_mce_chrdev_read,
.poll = xen_mce_chrdev_poll,
.unlocked_ioctl = xen_mce_chrdev_ioctl,
.llseek = no_llseek,
};
Expand Down Expand Up @@ -329,6 +344,9 @@ static void xen_mce_work_fn(struct work_struct *work)
pr_err(XEN_MCELOG
"Failed to handle nonurgent mc_info queue.\n");

/* wake processes polling /dev/mcelog */
wake_up_interruptible(&xen_mce_chrdev_wait);

mutex_unlock(&mcelog_lock);
}
static DECLARE_WORK(xen_mce_work, xen_mce_work_fn);
Expand Down

0 comments on commit a867e5d

Please sign in to comment.