457c899653991 (Thomas Gleixner 2019-05-19 13:08:55 +0100 1) // SPDX-License-Identifier: GPL-2.0-only
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 2) /*
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 3) * fs/eventfd.c
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 4) *
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 5) * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 6) *
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 7) */
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 8)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 9) #include <linux/file.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 10) #include <linux/poll.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 11) #include <linux/init.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 12) #include <linux/fs.h>
174cd4b1e5fbd (Ingo Molnar 2017-02-02 19:15:33 +0100 13) #include <linux/sched/signal.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 14) #include <linux/kernel.h>
5a0e3ad6af866 (Tejun Heo 2010-03-24 17:04:11 +0900 15) #include <linux/slab.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 16) #include <linux/list.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 17) #include <linux/spinlock.h>
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 18) #include <linux/anon_inodes.h>
7747cdb2f8302 (Adrian Bunk 2008-02-06 01:36:49 -0800 19) #include <linux/syscalls.h>
630d9c47274aa (Paul Gortmaker 2011-11-16 23:57:37 -0500 20) #include <linux/export.h>
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 21) #include <linux/kref.h>
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 22) #include <linux/eventfd.h>
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 23) #include <linux/proc_fs.h>
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 24) #include <linux/seq_file.h>
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 25) #include <linux/idr.h>
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 26) #include <linux/uio.h>
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 27)
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 28) DEFINE_PER_CPU(int, eventfd_wake_count);
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 29)
ce528c4c20f94 (YueHaibing 2019-05-14 15:45:22 -0700 30) static DEFINE_IDA(eventfd_ida);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 31)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 32) struct eventfd_ctx {
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 33) struct kref kref;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 34) wait_queue_head_t wqh;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 35) /*
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 36) * Every time that a write(2) is performed on an eventfd, the
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 37) * value of the __u64 being written is added to "count" and a
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 38) * wakeup is performed on "wqh". A read(2) will return the "count"
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 39) * value to userspace, and will reset "count" to zero. The kernel
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 40) * side eventfd_signal() also, adds to the "count" counter and
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 41) * issue a wakeup.
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 42) */
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 43) __u64 count;
bcd0b235bf380 (Davide Libenzi 2009-03-31 15:24:18 -0700 44) unsigned int flags;
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 45) int id;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 46) };
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 47)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 48) /**
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 49) * eventfd_signal - Adds @n to the eventfd counter.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 50) * @ctx: [in] Pointer to the eventfd context.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 51) * @n: [in] Value of the counter to be added to the eventfd internal counter.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 52) * The value cannot be negative.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 53) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 54) * This function is supposed to be called by the kernel in paths that do not
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 55) * allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
a9a08845e9acb (Linus Torvalds 2018-02-11 14:34:03 -0800 56) * value, and we signal this as overflow condition by returning a EPOLLERR
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 57) * to poll(2).
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 58) *
20d5a865e1f1d (Masanari Iida 2015-09-22 12:04:17 +0900 59) * Returns the amount by which the counter was incremented. This will be less
ee62c6b2dc93c (Sha Zhengju 2012-05-31 16:26:41 -0700 60) * than @n if the counter has overflowed.
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 61) */
ee62c6b2dc93c (Sha Zhengju 2012-05-31 16:26:41 -0700 62) __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 63) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 64) unsigned long flags;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 65)
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 66) /*
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 67) * Deadlock or stack overflow issues can happen if we recurse here
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 68) * through waitqueue wakeup handlers. If the caller users potentially
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 69) * nested waitqueues with custom wakeup handlers, then it should
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 70) * check eventfd_signal_count() before calling this function. If
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 71) * it returns true, the eventfd_signal() call should be deferred to a
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 72) * safe context.
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 73) */
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 74) if (WARN_ON_ONCE(this_cpu_read(eventfd_wake_count)))
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 75) return 0;
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 76)
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 77) spin_lock_irqsave(&ctx->wqh.lock, flags);
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 78) this_cpu_inc(eventfd_wake_count);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 79) if (ULLONG_MAX - ctx->count < n)
ee62c6b2dc93c (Sha Zhengju 2012-05-31 16:26:41 -0700 80) n = ULLONG_MAX - ctx->count;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 81) ctx->count += n;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 82) if (waitqueue_active(&ctx->wqh))
a9a08845e9acb (Linus Torvalds 2018-02-11 14:34:03 -0800 83) wake_up_locked_poll(&ctx->wqh, EPOLLIN);
b5e683d5cab8c (Jens Axboe 2020-02-02 08:23:03 -0700 84) this_cpu_dec(eventfd_wake_count);
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 85) spin_unlock_irqrestore(&ctx->wqh.lock, flags);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 86)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 87) return n;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 88) }
5718607bb670c (Rusty Russell 2009-06-12 22:27:09 -0600 89) EXPORT_SYMBOL_GPL(eventfd_signal);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 90)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 91) static void eventfd_free_ctx(struct eventfd_ctx *ctx)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 92) {
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 93) if (ctx->id >= 0)
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 94) ida_simple_remove(&eventfd_ida, ctx->id);
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 95) kfree(ctx);
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 96) }
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 97)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 98) static void eventfd_free(struct kref *kref)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 99) {
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 100) struct eventfd_ctx *ctx = container_of(kref, struct eventfd_ctx, kref);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 101)
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 102) eventfd_free_ctx(ctx);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 103) }
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 104)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 105) /**
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 106) * eventfd_ctx_put - Releases a reference to the internal eventfd context.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 107) * @ctx: [in] Pointer to eventfd context.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 108) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 109) * The eventfd context reference must have been previously acquired either
105f2b7096075 (Eric Biggers 2018-01-06 09:45:44 -0800 110) * with eventfd_ctx_fdget() or eventfd_ctx_fileget().
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 111) */
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 112) void eventfd_ctx_put(struct eventfd_ctx *ctx)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 113) {
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 114) kref_put(&ctx->kref, eventfd_free);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 115) }
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 116) EXPORT_SYMBOL_GPL(eventfd_ctx_put);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 117)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 118) static int eventfd_release(struct inode *inode, struct file *file)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 119) {
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 120) struct eventfd_ctx *ctx = file->private_data;
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 121)
a9a08845e9acb (Linus Torvalds 2018-02-11 14:34:03 -0800 122) wake_up_poll(&ctx->wqh, EPOLLHUP);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 123) eventfd_ctx_put(ctx);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 124) return 0;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 125) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 126)
a11e1d432b51f (Linus Torvalds 2018-06-28 09:43:44 -0700 127) static __poll_t eventfd_poll(struct file *file, poll_table *wait)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 128) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 129) struct eventfd_ctx *ctx = file->private_data;
076ccb76e1a6c (Al Viro 2017-07-03 01:02:18 -0400 130) __poll_t events = 0;
e22553e2a25ed (Chris Mason 2015-02-17 13:46:07 -0800 131) u64 count;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 132)
a11e1d432b51f (Linus Torvalds 2018-06-28 09:43:44 -0700 133) poll_wait(file, &ctx->wqh, wait);
a11e1d432b51f (Linus Torvalds 2018-06-28 09:43:44 -0700 134)
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 135) /*
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 136) * All writes to ctx->count occur within ctx->wqh.lock. This read
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 137) * can be done outside ctx->wqh.lock because we know that poll_wait
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 138) * takes that lock (through add_wait_queue) if our caller will sleep.
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 139) *
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 140) * The read _can_ therefore seep into add_wait_queue's critical
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 141) * section, but cannot move above it! add_wait_queue's spin_lock acts
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 142) * as an acquire barrier and ensures that the read be ordered properly
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 143) * against the writes. The following CAN happen and is safe:
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 144) *
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 145) * poll write
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 146) * ----------------- ------------
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 147) * lock ctx->wqh.lock (in poll_wait)
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 148) * count = ctx->count
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 149) * __add_wait_queue
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 150) * unlock ctx->wqh.lock
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 151) * lock ctx->qwh.lock
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 152) * ctx->count += n
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 153) * if (waitqueue_active)
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 154) * wake_up_locked_poll
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 155) * unlock ctx->qwh.lock
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 156) * eventfd_poll returns 0
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 157) *
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 158) * but the following, which would miss a wakeup, cannot happen:
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 159) *
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 160) * poll write
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 161) * ----------------- ------------
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 162) * count = ctx->count (INVALID!)
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 163) * lock ctx->qwh.lock
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 164) * ctx->count += n
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 165) * **waitqueue_active is false**
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 166) * **no wake_up_locked_poll!**
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 167) * unlock ctx->qwh.lock
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 168) * lock ctx->wqh.lock (in poll_wait)
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 169) * __add_wait_queue
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 170) * unlock ctx->wqh.lock
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 171) * eventfd_poll returns 0
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 172) */
a484c3dd9426e (Paolo Bonzini 2016-03-22 14:27:14 -0700 173) count = READ_ONCE(ctx->count);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 174)
e22553e2a25ed (Chris Mason 2015-02-17 13:46:07 -0800 175) if (count > 0)
a11e1d432b51f (Linus Torvalds 2018-06-28 09:43:44 -0700 176) events |= EPOLLIN;
e22553e2a25ed (Chris Mason 2015-02-17 13:46:07 -0800 177) if (count == ULLONG_MAX)
a9a08845e9acb (Linus Torvalds 2018-02-11 14:34:03 -0800 178) events |= EPOLLERR;
e22553e2a25ed (Chris Mason 2015-02-17 13:46:07 -0800 179) if (ULLONG_MAX - 1 > count)
a11e1d432b51f (Linus Torvalds 2018-06-28 09:43:44 -0700 180) events |= EPOLLOUT;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 181)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 182) return events;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 183) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 184)
28f1326710555 (David Woodhouse 2020-10-27 13:55:21 +0000 185) void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt)
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 186) {
28f1326710555 (David Woodhouse 2020-10-27 13:55:21 +0000 187) lockdep_assert_held(&ctx->wqh.lock);
28f1326710555 (David Woodhouse 2020-10-27 13:55:21 +0000 188)
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 189) *cnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count;
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 190) ctx->count -= *cnt;
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 191) }
28f1326710555 (David Woodhouse 2020-10-27 13:55:21 +0000 192) EXPORT_SYMBOL_GPL(eventfd_ctx_do_read);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 193)
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 194) /**
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 195) * eventfd_ctx_remove_wait_queue - Read the current counter and removes wait queue.
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 196) * @ctx: [in] Pointer to eventfd context.
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 197) * @wait: [in] Wait queue to be removed.
361821854b71f (Randy Dunlap 2011-02-20 20:08:35 -0800 198) * @cnt: [out] Pointer to the 64-bit counter value.
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 199) *
361821854b71f (Randy Dunlap 2011-02-20 20:08:35 -0800 200) * Returns %0 if successful, or the following error codes:
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 201) *
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 202) * -EAGAIN : The operation would have blocked.
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 203) *
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 204) * This is used to atomically remove a wait queue entry from the eventfd wait
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 205) * queue head, and read/reset the counter value.
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 206) */
ac6424b981bce (Ingo Molnar 2017-06-20 12:06:13 +0200 207) int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait,
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 208) __u64 *cnt)
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 209) {
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 210) unsigned long flags;
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 211)
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 212) spin_lock_irqsave(&ctx->wqh.lock, flags);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 213) eventfd_ctx_do_read(ctx, cnt);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 214) __remove_wait_queue(&ctx->wqh, wait);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 215) if (*cnt != 0 && waitqueue_active(&ctx->wqh))
a9a08845e9acb (Linus Torvalds 2018-02-11 14:34:03 -0800 216) wake_up_locked_poll(&ctx->wqh, EPOLLOUT);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 217) spin_unlock_irqrestore(&ctx->wqh.lock, flags);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 218)
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 219) return *cnt != 0 ? 0 : -EAGAIN;
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 220) }
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 221) EXPORT_SYMBOL_GPL(eventfd_ctx_remove_wait_queue);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 222)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 223) static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 224) {
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 225) struct file *file = iocb->ki_filp;
b6364572d641c (Eric Biggers 2018-01-06 09:45:43 -0800 226) struct eventfd_ctx *ctx = file->private_data;
b6364572d641c (Eric Biggers 2018-01-06 09:45:43 -0800 227) __u64 ucnt = 0;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 228) DECLARE_WAITQUEUE(wait, current);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 229)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 230) if (iov_iter_count(to) < sizeof(ucnt))
b6364572d641c (Eric Biggers 2018-01-06 09:45:43 -0800 231) return -EINVAL;
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 232) spin_lock_irq(&ctx->wqh.lock);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 233) if (!ctx->count) {
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 234) if ((file->f_flags & O_NONBLOCK) ||
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 235) (iocb->ki_flags & IOCB_NOWAIT)) {
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 236) spin_unlock_irq(&ctx->wqh.lock);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 237) return -EAGAIN;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 238) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 239) __add_wait_queue(&ctx->wqh, &wait);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 240) for (;;) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 241) set_current_state(TASK_INTERRUPTIBLE);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 242) if (ctx->count)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 243) break;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 244) if (signal_pending(current)) {
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 245) __remove_wait_queue(&ctx->wqh, &wait);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 246) __set_current_state(TASK_RUNNING);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 247) spin_unlock_irq(&ctx->wqh.lock);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 248) return -ERESTARTSYS;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 249) }
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 250) spin_unlock_irq(&ctx->wqh.lock);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 251) schedule();
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 252) spin_lock_irq(&ctx->wqh.lock);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 253) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 254) __remove_wait_queue(&ctx->wqh, &wait);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 255) __set_current_state(TASK_RUNNING);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 256) }
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 257) eventfd_ctx_do_read(ctx, &ucnt);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 258) if (waitqueue_active(&ctx->wqh))
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 259) wake_up_locked_poll(&ctx->wqh, EPOLLOUT);
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 260) spin_unlock_irq(&ctx->wqh.lock);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 261) if (unlikely(copy_to_iter(&ucnt, sizeof(ucnt), to) != sizeof(ucnt)))
b6364572d641c (Eric Biggers 2018-01-06 09:45:43 -0800 262) return -EFAULT;
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 263)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 264) return sizeof(ucnt);
cb289d6244a37 (Davide Libenzi 2010-01-13 09:34:36 -0800 265) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 266)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 267) static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t count,
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 268) loff_t *ppos)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 269) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 270) struct eventfd_ctx *ctx = file->private_data;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 271) ssize_t res;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 272) __u64 ucnt;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 273) DECLARE_WAITQUEUE(wait, current);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 274)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 275) if (count < sizeof(ucnt))
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 276) return -EINVAL;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 277) if (copy_from_user(&ucnt, buf, sizeof(ucnt)))
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 278) return -EFAULT;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 279) if (ucnt == ULLONG_MAX)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 280) return -EINVAL;
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 281) spin_lock_irq(&ctx->wqh.lock);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 282) res = -EAGAIN;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 283) if (ULLONG_MAX - ctx->count > ucnt)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 284) res = sizeof(ucnt);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 285) else if (!(file->f_flags & O_NONBLOCK)) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 286) __add_wait_queue(&ctx->wqh, &wait);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 287) for (res = 0;;) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 288) set_current_state(TASK_INTERRUPTIBLE);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 289) if (ULLONG_MAX - ctx->count > ucnt) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 290) res = sizeof(ucnt);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 291) break;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 292) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 293) if (signal_pending(current)) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 294) res = -ERESTARTSYS;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 295) break;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 296) }
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 297) spin_unlock_irq(&ctx->wqh.lock);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 298) schedule();
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 299) spin_lock_irq(&ctx->wqh.lock);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 300) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 301) __remove_wait_queue(&ctx->wqh, &wait);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 302) __set_current_state(TASK_RUNNING);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 303) }
bcd0b235bf380 (Davide Libenzi 2009-03-31 15:24:18 -0700 304) if (likely(res > 0)) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 305) ctx->count += ucnt;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 306) if (waitqueue_active(&ctx->wqh))
a9a08845e9acb (Linus Torvalds 2018-02-11 14:34:03 -0800 307) wake_up_locked_poll(&ctx->wqh, EPOLLIN);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 308) }
d48eb23315952 (Davide Libenzi 2007-05-18 12:02:33 -0700 309) spin_unlock_irq(&ctx->wqh.lock);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 310)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 311) return res;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 312) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 313)
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 314) #ifdef CONFIG_PROC_FS
a3816ab0e8fe5 (Joe Perches 2014-09-29 16:08:25 -0700 315) static void eventfd_show_fdinfo(struct seq_file *m, struct file *f)
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 316) {
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 317) struct eventfd_ctx *ctx = f->private_data;
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 318)
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 319) spin_lock_irq(&ctx->wqh.lock);
a3816ab0e8fe5 (Joe Perches 2014-09-29 16:08:25 -0700 320) seq_printf(m, "eventfd-count: %16llx\n",
a3816ab0e8fe5 (Joe Perches 2014-09-29 16:08:25 -0700 321) (unsigned long long)ctx->count);
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 322) spin_unlock_irq(&ctx->wqh.lock);
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 323) seq_printf(m, "eventfd-id: %d\n", ctx->id);
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 324) }
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 325) #endif
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 326)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 327) static const struct file_operations eventfd_fops = {
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 328) #ifdef CONFIG_PROC_FS
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 329) .show_fdinfo = eventfd_show_fdinfo,
cbac5542d4812 (Cyrill Gorcunov 2012-12-17 16:04:57 -0800 330) #endif
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 331) .release = eventfd_release,
a11e1d432b51f (Linus Torvalds 2018-06-28 09:43:44 -0700 332) .poll = eventfd_poll,
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 333) .read_iter = eventfd_read,
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 334) .write = eventfd_write,
6038f373a3dc1 (Arnd Bergmann 2010-08-15 18:52:59 +0200 335) .llseek = noop_llseek,
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 336) };
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 337)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 338) /**
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 339) * eventfd_fget - Acquire a reference of an eventfd file descriptor.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 340) * @fd: [in] Eventfd file descriptor.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 341) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 342) * Returns a pointer to the eventfd file structure in case of success, or the
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 343) * following error pointer:
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 344) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 345) * -EBADF : Invalid @fd file descriptor.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 346) * -EINVAL : The @fd file descriptor is not an eventfd file.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 347) */
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 348) struct file *eventfd_fget(int fd)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 349) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 350) struct file *file;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 351)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 352) file = fget(fd);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 353) if (!file)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 354) return ERR_PTR(-EBADF);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 355) if (file->f_op != &eventfd_fops) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 356) fput(file);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 357) return ERR_PTR(-EINVAL);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 358) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 359)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 360) return file;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 361) }
5718607bb670c (Rusty Russell 2009-06-12 22:27:09 -0600 362) EXPORT_SYMBOL_GPL(eventfd_fget);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 363)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 364) /**
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 365) * eventfd_ctx_fdget - Acquires a reference to the internal eventfd context.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 366) * @fd: [in] Eventfd file descriptor.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 367) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 368) * Returns a pointer to the internal eventfd context, otherwise the error
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 369) * pointers returned by the following functions:
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 370) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 371) * eventfd_fget
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 372) */
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 373) struct eventfd_ctx *eventfd_ctx_fdget(int fd)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 374) {
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 375) struct eventfd_ctx *ctx;
36a7411724b1c (Al Viro 2013-12-23 16:51:33 -0500 376) struct fd f = fdget(fd);
36a7411724b1c (Al Viro 2013-12-23 16:51:33 -0500 377) if (!f.file)
36a7411724b1c (Al Viro 2013-12-23 16:51:33 -0500 378) return ERR_PTR(-EBADF);
36a7411724b1c (Al Viro 2013-12-23 16:51:33 -0500 379) ctx = eventfd_ctx_fileget(f.file);
36a7411724b1c (Al Viro 2013-12-23 16:51:33 -0500 380) fdput(f);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 381) return ctx;
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 382) }
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 383) EXPORT_SYMBOL_GPL(eventfd_ctx_fdget);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 384)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 385) /**
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 386) * eventfd_ctx_fileget - Acquires a reference to the internal eventfd context.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 387) * @file: [in] Eventfd file pointer.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 388) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 389) * Returns a pointer to the internal eventfd context, otherwise the error
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 390) * pointer:
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 391) *
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 392) * -EINVAL : The @fd file descriptor is not an eventfd file.
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 393) */
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 394) struct eventfd_ctx *eventfd_ctx_fileget(struct file *file)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 395) {
105f2b7096075 (Eric Biggers 2018-01-06 09:45:44 -0800 396) struct eventfd_ctx *ctx;
105f2b7096075 (Eric Biggers 2018-01-06 09:45:44 -0800 397)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 398) if (file->f_op != &eventfd_fops)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 399) return ERR_PTR(-EINVAL);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 400)
105f2b7096075 (Eric Biggers 2018-01-06 09:45:44 -0800 401) ctx = file->private_data;
105f2b7096075 (Eric Biggers 2018-01-06 09:45:44 -0800 402) kref_get(&ctx->kref);
105f2b7096075 (Eric Biggers 2018-01-06 09:45:44 -0800 403) return ctx;
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 404) }
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 405) EXPORT_SYMBOL_GPL(eventfd_ctx_fileget);
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 406)
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 407) static int do_eventfd(unsigned int count, int flags)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 408) {
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 409) struct eventfd_ctx *ctx;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 410) struct file *file;
7d815165c1a64 (Eric Biggers 2018-01-06 09:45:42 -0800 411) int fd;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 412)
e38b36f325153 (Ulrich Drepper 2008-07-23 21:29:42 -0700 413) /* Check the EFD_* constants for consistency. */
e38b36f325153 (Ulrich Drepper 2008-07-23 21:29:42 -0700 414) BUILD_BUG_ON(EFD_CLOEXEC != O_CLOEXEC);
e38b36f325153 (Ulrich Drepper 2008-07-23 21:29:42 -0700 415) BUILD_BUG_ON(EFD_NONBLOCK != O_NONBLOCK);
e38b36f325153 (Ulrich Drepper 2008-07-23 21:29:42 -0700 416)
bcd0b235bf380 (Davide Libenzi 2009-03-31 15:24:18 -0700 417) if (flags & ~EFD_FLAGS_SET)
7d815165c1a64 (Eric Biggers 2018-01-06 09:45:42 -0800 418) return -EINVAL;
b087498eb5605 (Ulrich Drepper 2008-07-23 21:29:25 -0700 419)
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 420) ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 421) if (!ctx)
7d815165c1a64 (Eric Biggers 2018-01-06 09:45:42 -0800 422) return -ENOMEM;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 423)
133890103b9de (Davide Libenzi 2009-06-30 11:41:11 -0700 424) kref_init(&ctx->kref);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 425) init_waitqueue_head(&ctx->wqh);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 426) ctx->count = count;
bcd0b235bf380 (Davide Libenzi 2009-03-31 15:24:18 -0700 427) ctx->flags = flags;
b556db17b0e7c (Masatake YAMATO 2019-05-14 15:45:19 -0700 428) ctx->id = ida_simple_get(&eventfd_ida, 0, 0, GFP_KERNEL);
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 429)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 430) flags &= EFD_SHARED_FCNTL_FLAGS;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 431) flags |= O_RDWR;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 432) fd = get_unused_fd_flags(flags);
7d815165c1a64 (Eric Biggers 2018-01-06 09:45:42 -0800 433) if (fd < 0)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 434) goto err;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 435)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 436) file = anon_inode_getfile("[eventfd]", &eventfd_fops, ctx, flags);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 437) if (IS_ERR(file)) {
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 438) put_unused_fd(fd);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 439) fd = PTR_ERR(file);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 440) goto err;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 441) }
562787a5c32cc (Davide Libenzi 2009-09-22 16:43:57 -0700 442)
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 443) file->f_mode |= FMODE_NOWAIT;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 444) fd_install(fd, file);
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 445) return fd;
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 446) err:
12aceb89b0bce (Jens Axboe 2020-05-01 13:11:09 -0600 447) eventfd_free_ctx(ctx);
2030a42cecd4d (Al Viro 2008-02-23 06:46:49 -0500 448) return fd;
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 449) }
e1ad7468c77dd (Davide Libenzi 2007-05-10 22:23:19 -0700 450)
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 451) SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags)
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 452) {
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 453) return do_eventfd(count, flags);
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 454) }
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 455)
d4e82042c4cfa (Heiko Carstens 2009-01-14 14:14:34 +0100 456) SYSCALL_DEFINE1(eventfd, unsigned int, count)
b087498eb5605 (Ulrich Drepper 2008-07-23 21:29:25 -0700 457) {
2fc96f8331ba7 (Dominik Brodowski 2018-03-11 11:34:37 +0100 458) return do_eventfd(count, 0);
b087498eb5605 (Ulrich Drepper 2008-07-23 21:29:25 -0700 459) }
bcd0b235bf380 (Davide Libenzi 2009-03-31 15:24:18 -0700 460)