diff options
author | Gleb Natapov <glebn@voltaire.com> | 2005-07-27 17:40:00 -0400 |
---|---|---|
committer | Roland Dreier <roland@eddore.topspincom.com> | 2005-07-27 17:40:00 -0400 |
commit | abdf119b4dad015803819c3d046d20cfbd393e87 (patch) | |
tree | 9d0372a7f4a71886696a5d7b6f7583790e1c8d22 /drivers/infiniband | |
parent | 42b1806d5cfc93bf8c3d7fa6e9e79e4ec860c678 (diff) |
[IB/uverbs]: Add O_ASYNC support
Add support for O_ASYNC notifications on userspace verbs
completion and asynchronous event file descriptors.
Signed-off-by: Gleb Natapov <glebn@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 14 |
2 files changed, 14 insertions, 1 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 57347f1e82c1..7696022f9a4e 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -61,6 +61,7 @@ struct ib_uverbs_event_file { | |||
61 | int fd; | 61 | int fd; |
62 | int is_async; | 62 | int is_async; |
63 | wait_queue_head_t poll_wait; | 63 | wait_queue_head_t poll_wait; |
64 | struct fasync_struct *async_queue; | ||
64 | struct list_head event_list; | 65 | struct list_head event_list; |
65 | }; | 66 | }; |
66 | 67 | ||
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index fbbe03d8c901..eb99e693dec2 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -257,11 +257,19 @@ static void ib_uverbs_event_release(struct ib_uverbs_event_file *file) | |||
257 | spin_unlock_irq(&file->lock); | 257 | spin_unlock_irq(&file->lock); |
258 | } | 258 | } |
259 | 259 | ||
260 | static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) | ||
261 | { | ||
262 | struct ib_uverbs_event_file *file = filp->private_data; | ||
263 | |||
264 | return fasync_helper(fd, filp, on, &file->async_queue); | ||
265 | } | ||
266 | |||
260 | static int ib_uverbs_event_close(struct inode *inode, struct file *filp) | 267 | static int ib_uverbs_event_close(struct inode *inode, struct file *filp) |
261 | { | 268 | { |
262 | struct ib_uverbs_event_file *file = filp->private_data; | 269 | struct ib_uverbs_event_file *file = filp->private_data; |
263 | 270 | ||
264 | ib_uverbs_event_release(file); | 271 | ib_uverbs_event_release(file); |
272 | ib_uverbs_event_fasync(-1, filp, 0); | ||
265 | kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); | 273 | kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); |
266 | 274 | ||
267 | return 0; | 275 | return 0; |
@@ -276,7 +284,8 @@ static struct file_operations uverbs_event_fops = { | |||
276 | */ | 284 | */ |
277 | .read = ib_uverbs_event_read, | 285 | .read = ib_uverbs_event_read, |
278 | .poll = ib_uverbs_event_poll, | 286 | .poll = ib_uverbs_event_poll, |
279 | .release = ib_uverbs_event_close | 287 | .release = ib_uverbs_event_close, |
288 | .fasync = ib_uverbs_event_fasync | ||
280 | }; | 289 | }; |
281 | 290 | ||
282 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) | 291 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) |
@@ -296,6 +305,7 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) | |||
296 | spin_unlock_irqrestore(&file->comp_file[0].lock, flags); | 305 | spin_unlock_irqrestore(&file->comp_file[0].lock, flags); |
297 | 306 | ||
298 | wake_up_interruptible(&file->comp_file[0].poll_wait); | 307 | wake_up_interruptible(&file->comp_file[0].poll_wait); |
308 | kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN); | ||
299 | } | 309 | } |
300 | 310 | ||
301 | static void ib_uverbs_async_handler(struct ib_uverbs_file *file, | 311 | static void ib_uverbs_async_handler(struct ib_uverbs_file *file, |
@@ -316,6 +326,7 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, | |||
316 | spin_unlock_irqrestore(&file->async_file.lock, flags); | 326 | spin_unlock_irqrestore(&file->async_file.lock, flags); |
317 | 327 | ||
318 | wake_up_interruptible(&file->async_file.poll_wait); | 328 | wake_up_interruptible(&file->async_file.poll_wait); |
329 | kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN); | ||
319 | } | 330 | } |
320 | 331 | ||
321 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) | 332 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) |
@@ -350,6 +361,7 @@ static int ib_uverbs_event_init(struct ib_uverbs_event_file *file, | |||
350 | INIT_LIST_HEAD(&file->event_list); | 361 | INIT_LIST_HEAD(&file->event_list); |
351 | init_waitqueue_head(&file->poll_wait); | 362 | init_waitqueue_head(&file->poll_wait); |
352 | file->uverbs_file = uverbs_file; | 363 | file->uverbs_file = uverbs_file; |
364 | file->async_queue = NULL; | ||
353 | 365 | ||
354 | file->fd = get_unused_fd(); | 366 | file->fd = get_unused_fd(); |
355 | if (file->fd < 0) | 367 | if (file->fd < 0) |