aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorLiu, Jinsong <jinsong.liu@intel.com>2012-06-14 21:03:39 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-07-19 15:51:41 -0400
commita867e5d6b362fc2982f19c5223f1946292643e57 (patch)
tree4dc03701387d766b5f2b44c3d3efa0e8e350f1b4 /drivers/xen
parent1b2a05516e42149a5e9f0f5aeba2c7fa9574b3f4 (diff)
xen/mce: add .poll method for mcelog device driver
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>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/mcelog.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c
index 804aa3c181c2..8feee08bcb43 100644
--- a/drivers/xen/mcelog.c
+++ b/drivers/xen/mcelog.c
@@ -41,6 +41,8 @@
41#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
42#include <linux/uaccess.h> 42#include <linux/uaccess.h>
43#include <linux/capability.h> 43#include <linux/capability.h>
44#include <linux/poll.h>
45#include <linux/sched.h>
44 46
45#include <xen/interface/xen.h> 47#include <xen/interface/xen.h>
46#include <xen/events.h> 48#include <xen/events.h>
@@ -67,6 +69,8 @@ static DEFINE_SPINLOCK(xen_mce_chrdev_state_lock);
67static int xen_mce_chrdev_open_count; /* #times opened */ 69static int xen_mce_chrdev_open_count; /* #times opened */
68static int xen_mce_chrdev_open_exclu; /* already open exclusive? */ 70static int xen_mce_chrdev_open_exclu; /* already open exclusive? */
69 71
72static DECLARE_WAIT_QUEUE_HEAD(xen_mce_chrdev_wait);
73
70static int xen_mce_chrdev_open(struct inode *inode, struct file *file) 74static int xen_mce_chrdev_open(struct inode *inode, struct file *file)
71{ 75{
72 spin_lock(&xen_mce_chrdev_state_lock); 76 spin_lock(&xen_mce_chrdev_state_lock);
@@ -135,6 +139,16 @@ out:
135 return err ? err : buf - ubuf; 139 return err ? err : buf - ubuf;
136} 140}
137 141
142static unsigned int xen_mce_chrdev_poll(struct file *file, poll_table *wait)
143{
144 poll_wait(file, &xen_mce_chrdev_wait, wait);
145
146 if (xen_mcelog.next)
147 return POLLIN | POLLRDNORM;
148
149 return 0;
150}
151
138static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd, 152static long xen_mce_chrdev_ioctl(struct file *f, unsigned int cmd,
139 unsigned long arg) 153 unsigned long arg)
140{ 154{
@@ -166,6 +180,7 @@ static const struct file_operations xen_mce_chrdev_ops = {
166 .open = xen_mce_chrdev_open, 180 .open = xen_mce_chrdev_open,
167 .release = xen_mce_chrdev_release, 181 .release = xen_mce_chrdev_release,
168 .read = xen_mce_chrdev_read, 182 .read = xen_mce_chrdev_read,
183 .poll = xen_mce_chrdev_poll,
169 .unlocked_ioctl = xen_mce_chrdev_ioctl, 184 .unlocked_ioctl = xen_mce_chrdev_ioctl,
170 .llseek = no_llseek, 185 .llseek = no_llseek,
171}; 186};
@@ -329,6 +344,9 @@ static void xen_mce_work_fn(struct work_struct *work)
329 pr_err(XEN_MCELOG 344 pr_err(XEN_MCELOG
330 "Failed to handle nonurgent mc_info queue.\n"); 345 "Failed to handle nonurgent mc_info queue.\n");
331 346
347 /* wake processes polling /dev/mcelog */
348 wake_up_interruptible(&xen_mce_chrdev_wait);
349
332 mutex_unlock(&mcelog_lock); 350 mutex_unlock(&mcelog_lock);
333} 351}
334static DECLARE_WORK(xen_mce_work, xen_mce_work_fn); 352static DECLARE_WORK(xen_mce_work, xen_mce_work_fn);