]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
perf_counter: SIGIO support
authorPeter Zijlstra <a.p.zijlstra@chello.nl>
Mon, 6 Apr 2009 09:45:01 +0000 (11:45 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 7 Apr 2009 08:48:55 +0000 (10:48 +0200)
Provide support for fcntl() I/O availability signals.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
LKML-Reference: <20090406094517.579788800@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
include/linux/perf_counter.h
kernel/perf_counter.c

index f9d5cf0bfbdd007529e07125b95ee8fd9ea65b8b..8d5d11b8d011561936b249bd7d2ab3a31bddab9f 100644 (file)
@@ -238,6 +238,7 @@ enum perf_event_type {
 #include <linux/rcupdate.h>
 #include <linux/spinlock.h>
 #include <linux/hrtimer.h>
+#include <linux/fs.h>
 #include <asm/atomic.h>
 
 struct task_struct;
@@ -398,6 +399,7 @@ struct perf_counter {
 
        /* poll related */
        wait_queue_head_t               waitq;
+       struct fasync_struct            *fasync;
        /* optional: for NMIs */
        struct perf_wakeup_entry        wakeup;
 
index 727624db5078bef5fcdcaa3c97e63768f8e29c86..c58cc64319e162b67f5cec73ba12f77684faf37b 100644 (file)
@@ -1526,6 +1526,22 @@ out:
        return ret;
 }
 
+static int perf_fasync(int fd, struct file *filp, int on)
+{
+       struct perf_counter *counter = filp->private_data;
+       struct inode *inode = filp->f_path.dentry->d_inode;
+       int retval;
+
+       mutex_lock(&inode->i_mutex);
+       retval = fasync_helper(fd, filp, on, &counter->fasync);
+       mutex_unlock(&inode->i_mutex);
+
+       if (retval < 0)
+               return retval;
+
+       return 0;
+}
+
 static const struct file_operations perf_fops = {
        .release                = perf_release,
        .read                   = perf_read,
@@ -1533,6 +1549,7 @@ static const struct file_operations perf_fops = {
        .unlocked_ioctl         = perf_ioctl,
        .compat_ioctl           = perf_ioctl,
        .mmap                   = perf_mmap,
+       .fasync                 = perf_fasync,
 };
 
 /*
@@ -1549,7 +1566,7 @@ void perf_counter_wakeup(struct perf_counter *counter)
        rcu_read_lock();
        data = rcu_dereference(counter->data);
        if (data) {
-               (void)atomic_xchg(&data->wakeup, POLL_IN);
+               atomic_set(&data->wakeup, POLL_IN);
                /*
                 * Ensure all data writes are issued before updating the
                 * user-space data head information. The matching rmb()
@@ -1561,6 +1578,7 @@ void perf_counter_wakeup(struct perf_counter *counter)
        rcu_read_unlock();
 
        wake_up_all(&counter->waitq);
+       kill_fasync(&counter->fasync, SIGIO, POLL_IN);
 }
 
 /*