Commit 3c446b3d authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

perf_counter: SIGIO support



Provide support for fcntl() I/O availability signals.

Signed-off-by: default avatarPeter 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: default avatarIngo Molnar <mingo@elte.hu>
parent 9c03d88e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;

+19 −1
Original line number Diff line number Diff line
@@ -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);
}

/*