diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-04-06 05:45:01 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-07 04:48:55 -0400 |
commit | 3c446b3d3b38f991f97e9d2df0ad26a60a94dcff (patch) | |
tree | fc4a7bdf50f34eb1a7343afdcc980355ccce5e97 | |
parent | 9c03d88e328d5f28f13191622c2ea1349c36b799 (diff) |
perf_counter: SIGIO support
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>
-rw-r--r-- | include/linux/perf_counter.h | 2 | ||||
-rw-r--r-- | kernel/perf_counter.c | 20 |
2 files changed, 21 insertions, 1 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index f9d5cf0bfbdd..8d5d11b8d011 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h | |||
@@ -238,6 +238,7 @@ enum perf_event_type { | |||
238 | #include <linux/rcupdate.h> | 238 | #include <linux/rcupdate.h> |
239 | #include <linux/spinlock.h> | 239 | #include <linux/spinlock.h> |
240 | #include <linux/hrtimer.h> | 240 | #include <linux/hrtimer.h> |
241 | #include <linux/fs.h> | ||
241 | #include <asm/atomic.h> | 242 | #include <asm/atomic.h> |
242 | 243 | ||
243 | struct task_struct; | 244 | struct task_struct; |
@@ -398,6 +399,7 @@ struct perf_counter { | |||
398 | 399 | ||
399 | /* poll related */ | 400 | /* poll related */ |
400 | wait_queue_head_t waitq; | 401 | wait_queue_head_t waitq; |
402 | struct fasync_struct *fasync; | ||
401 | /* optional: for NMIs */ | 403 | /* optional: for NMIs */ |
402 | struct perf_wakeup_entry wakeup; | 404 | struct perf_wakeup_entry wakeup; |
403 | 405 | ||
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 727624db5078..c58cc64319e1 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -1526,6 +1526,22 @@ out: | |||
1526 | return ret; | 1526 | return ret; |
1527 | } | 1527 | } |
1528 | 1528 | ||
1529 | static int perf_fasync(int fd, struct file *filp, int on) | ||
1530 | { | ||
1531 | struct perf_counter *counter = filp->private_data; | ||
1532 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
1533 | int retval; | ||
1534 | |||
1535 | mutex_lock(&inode->i_mutex); | ||
1536 | retval = fasync_helper(fd, filp, on, &counter->fasync); | ||
1537 | mutex_unlock(&inode->i_mutex); | ||
1538 | |||
1539 | if (retval < 0) | ||
1540 | return retval; | ||
1541 | |||
1542 | return 0; | ||
1543 | } | ||
1544 | |||
1529 | static const struct file_operations perf_fops = { | 1545 | static const struct file_operations perf_fops = { |
1530 | .release = perf_release, | 1546 | .release = perf_release, |
1531 | .read = perf_read, | 1547 | .read = perf_read, |
@@ -1533,6 +1549,7 @@ static const struct file_operations perf_fops = { | |||
1533 | .unlocked_ioctl = perf_ioctl, | 1549 | .unlocked_ioctl = perf_ioctl, |
1534 | .compat_ioctl = perf_ioctl, | 1550 | .compat_ioctl = perf_ioctl, |
1535 | .mmap = perf_mmap, | 1551 | .mmap = perf_mmap, |
1552 | .fasync = perf_fasync, | ||
1536 | }; | 1553 | }; |
1537 | 1554 | ||
1538 | /* | 1555 | /* |
@@ -1549,7 +1566,7 @@ void perf_counter_wakeup(struct perf_counter *counter) | |||
1549 | rcu_read_lock(); | 1566 | rcu_read_lock(); |
1550 | data = rcu_dereference(counter->data); | 1567 | data = rcu_dereference(counter->data); |
1551 | if (data) { | 1568 | if (data) { |
1552 | (void)atomic_xchg(&data->wakeup, POLL_IN); | 1569 | atomic_set(&data->wakeup, POLL_IN); |
1553 | /* | 1570 | /* |
1554 | * Ensure all data writes are issued before updating the | 1571 | * Ensure all data writes are issued before updating the |
1555 | * user-space data head information. The matching rmb() | 1572 | * user-space data head information. The matching rmb() |
@@ -1561,6 +1578,7 @@ void perf_counter_wakeup(struct perf_counter *counter) | |||
1561 | rcu_read_unlock(); | 1578 | rcu_read_unlock(); |
1562 | 1579 | ||
1563 | wake_up_all(&counter->waitq); | 1580 | wake_up_all(&counter->waitq); |
1581 | kill_fasync(&counter->fasync, SIGIO, POLL_IN); | ||
1564 | } | 1582 | } |
1565 | 1583 | ||
1566 | /* | 1584 | /* |