summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-07-03 20:14:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-11-27 16:19:54 -0500
commit3ad6f93e98d6df25d0667d847d3ab9cbdccb3eae (patch)
tree8b52d66806f02c815198e962758ac4199d9ee6e0
parente6c8adca20ba459dd88057ca74232bf9f1045075 (diff)
annotate poll-related wait keys
__poll_t is also used as wait key in some waitqueues. Verify that wait_..._poll() gets __poll_t as key and provide a helper for wakeup functions to get back to that __poll_t value. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/vfio/virqfd.c2
-rw-r--r--drivers/vhost/vhost.c4
-rw-r--r--fs/eventpoll.c9
-rw-r--r--fs/select.c2
-rw-r--r--include/linux/wait.h10
-rw-r--r--mm/memcontrol.c2
-rw-r--r--net/core/datagram.c4
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--virt/kvm/eventfd.c2
9 files changed, 19 insertions, 18 deletions
diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c
index d18b10ff119e..8cc4b48ff127 100644
--- a/drivers/vfio/virqfd.c
+++ b/drivers/vfio/virqfd.c
@@ -46,7 +46,7 @@ static void virqfd_deactivate(struct virqfd *virqfd)
46static int virqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key) 46static int virqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
47{ 47{
48 struct virqfd *virqfd = container_of(wait, struct virqfd, wait); 48 struct virqfd *virqfd = container_of(wait, struct virqfd, wait);
49 unsigned long flags = (unsigned long)key; 49 __poll_t flags = key_to_poll(key);
50 50
51 if (flags & POLLIN) { 51 if (flags & POLLIN) {
52 /* An event has been signaled, call function */ 52 /* An event has been signaled, call function */
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c18e70bd0466..7aad77be0b46 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -170,7 +170,7 @@ static int vhost_poll_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync,
170{ 170{
171 struct vhost_poll *poll = container_of(wait, struct vhost_poll, wait); 171 struct vhost_poll *poll = container_of(wait, struct vhost_poll, wait);
172 172
173 if (!((unsigned long)key & poll->mask)) 173 if (!(key_to_poll(key) & poll->mask))
174 return 0; 174 return 0;
175 175
176 vhost_poll_queue(poll); 176 vhost_poll_queue(poll);
@@ -211,7 +211,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
211 211
212 mask = file->f_op->poll(file, &poll->table); 212 mask = file->f_op->poll(file, &poll->table);
213 if (mask) 213 if (mask)
214 vhost_poll_wakeup(&poll->wait, 0, 0, (void *)(uintptr_t)mask); 214 vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
215 if (mask & POLLERR) { 215 if (mask & POLLERR) {
216 if (poll->wqh) 216 if (poll->wqh)
217 remove_wait_queue(poll->wqh, &poll->wait); 217 remove_wait_queue(poll->wqh, &poll->wait);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index afd548ebc328..21e6fee00e8b 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1117,6 +1117,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
1117 unsigned long flags; 1117 unsigned long flags;
1118 struct epitem *epi = ep_item_from_wait(wait); 1118 struct epitem *epi = ep_item_from_wait(wait);
1119 struct eventpoll *ep = epi->ep; 1119 struct eventpoll *ep = epi->ep;
1120 __poll_t pollflags = key_to_poll(key);
1120 int ewake = 0; 1121 int ewake = 0;
1121 1122
1122 spin_lock_irqsave(&ep->lock, flags); 1123 spin_lock_irqsave(&ep->lock, flags);
@@ -1138,7 +1139,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
1138 * callback. We need to be able to handle both cases here, hence the 1139 * callback. We need to be able to handle both cases here, hence the
1139 * test for "key" != NULL before the event match test. 1140 * test for "key" != NULL before the event match test.
1140 */ 1141 */
1141 if (key && !((unsigned long) key & epi->event.events)) 1142 if (pollflags && !(pollflags & epi->event.events))
1142 goto out_unlock; 1143 goto out_unlock;
1143 1144
1144 /* 1145 /*
@@ -1175,8 +1176,8 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
1175 */ 1176 */
1176 if (waitqueue_active(&ep->wq)) { 1177 if (waitqueue_active(&ep->wq)) {
1177 if ((epi->event.events & EPOLLEXCLUSIVE) && 1178 if ((epi->event.events & EPOLLEXCLUSIVE) &&
1178 !((unsigned long)key & POLLFREE)) { 1179 !(pollflags & POLLFREE)) {
1179 switch ((unsigned long)key & EPOLLINOUT_BITS) { 1180 switch (pollflags & EPOLLINOUT_BITS) {
1180 case POLLIN: 1181 case POLLIN:
1181 if (epi->event.events & POLLIN) 1182 if (epi->event.events & POLLIN)
1182 ewake = 1; 1183 ewake = 1;
@@ -1205,7 +1206,7 @@ out_unlock:
1205 if (!(epi->event.events & EPOLLEXCLUSIVE)) 1206 if (!(epi->event.events & EPOLLEXCLUSIVE))
1206 ewake = 1; 1207 ewake = 1;
1207 1208
1208 if ((unsigned long)key & POLLFREE) { 1209 if (pollflags & POLLFREE) {
1209 /* 1210 /*
1210 * If we race with ep_remove_wait_queue() it can miss 1211 * If we race with ep_remove_wait_queue() it can miss
1211 * ->whead = NULL and do another remove_wait_queue() after 1212 * ->whead = NULL and do another remove_wait_queue() after
diff --git a/fs/select.c b/fs/select.c
index b2bf84be5056..ffc16fd3673e 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -212,7 +212,7 @@ static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key
212 struct poll_table_entry *entry; 212 struct poll_table_entry *entry;
213 213
214 entry = container_of(wait, struct poll_table_entry, wait); 214 entry = container_of(wait, struct poll_table_entry, wait);
215 if (key && !((unsigned long)key & entry->key)) 215 if (key && !(key_to_poll(key) & entry->key))
216 return 0; 216 return 0;
217 return __pollwake(wait, mode, sync, key); 217 return __pollwake(wait, mode, sync, key);
218} 218}
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 158715445ffb..55a611486bac 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -206,14 +206,16 @@ void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode, int nr);
206/* 206/*
207 * Wakeup macros to be used to report events to the targets. 207 * Wakeup macros to be used to report events to the targets.
208 */ 208 */
209#define poll_to_key(m) ((void *)(__force uintptr_t)(__poll_t)(m))
210#define key_to_poll(m) ((__force __poll_t)(uintptr_t)(void *)(m))
209#define wake_up_poll(x, m) \ 211#define wake_up_poll(x, m) \
210 __wake_up(x, TASK_NORMAL, 1, (void *) (m)) 212 __wake_up(x, TASK_NORMAL, 1, poll_to_key(m))
211#define wake_up_locked_poll(x, m) \ 213#define wake_up_locked_poll(x, m) \
212 __wake_up_locked_key((x), TASK_NORMAL, (void *) (m)) 214 __wake_up_locked_key((x), TASK_NORMAL, poll_to_key(m))
213#define wake_up_interruptible_poll(x, m) \ 215#define wake_up_interruptible_poll(x, m) \
214 __wake_up(x, TASK_INTERRUPTIBLE, 1, (void *) (m)) 216 __wake_up(x, TASK_INTERRUPTIBLE, 1, poll_to_key(m))
215#define wake_up_interruptible_sync_poll(x, m) \ 217#define wake_up_interruptible_sync_poll(x, m) \
216 __wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, (void *) (m)) 218 __wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, poll_to_key(m))
217 219
218#define ___wait_cond_timeout(condition) \ 220#define ___wait_cond_timeout(condition) \
219({ \ 221({ \
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 50e6906314f8..006aa27f4fb4 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3777,7 +3777,7 @@ static int memcg_event_wake(wait_queue_entry_t *wait, unsigned mode,
3777 struct mem_cgroup_event *event = 3777 struct mem_cgroup_event *event =
3778 container_of(wait, struct mem_cgroup_event, wait); 3778 container_of(wait, struct mem_cgroup_event, wait);
3779 struct mem_cgroup *memcg = event->memcg; 3779 struct mem_cgroup *memcg = event->memcg;
3780 unsigned long flags = (unsigned long)key; 3780 __poll_t flags = key_to_poll(key);
3781 3781
3782 if (flags & POLLHUP) { 3782 if (flags & POLLHUP) {
3783 /* 3783 /*
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 522873ed120b..000da13c01f2 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -72,12 +72,10 @@ static inline int connection_based(struct sock *sk)
72static int receiver_wake_function(wait_queue_entry_t *wait, unsigned int mode, int sync, 72static int receiver_wake_function(wait_queue_entry_t *wait, unsigned int mode, int sync,
73 void *key) 73 void *key)
74{ 74{
75 unsigned long bits = (unsigned long)key;
76
77 /* 75 /*
78 * Avoid a wakeup if event not interesting for us 76 * Avoid a wakeup if event not interesting for us
79 */ 77 */
80 if (bits && !(bits & (POLLIN | POLLERR))) 78 if (key && !(key_to_poll(key) & (POLLIN | POLLERR)))
81 return 0; 79 return 0;
82 return autoremove_wake_function(wait, mode, sync, key); 80 return autoremove_wake_function(wait, mode, sync, key);
83} 81}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index a9ee634f3c42..72957961ac22 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -367,7 +367,7 @@ static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int
367 /* relaying can only happen while the wq still exists */ 367 /* relaying can only happen while the wq still exists */
368 u_sleep = sk_sleep(&u->sk); 368 u_sleep = sk_sleep(&u->sk);
369 if (u_sleep) 369 if (u_sleep)
370 wake_up_interruptible_poll(u_sleep, key); 370 wake_up_interruptible_poll(u_sleep, key_to_poll(key));
371 371
372 return 0; 372 return 0;
373} 373}
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index a1f68ed999d8..a334399fafec 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -188,7 +188,7 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
188{ 188{
189 struct kvm_kernel_irqfd *irqfd = 189 struct kvm_kernel_irqfd *irqfd =
190 container_of(wait, struct kvm_kernel_irqfd, wait); 190 container_of(wait, struct kvm_kernel_irqfd, wait);
191 unsigned long flags = (unsigned long)key; 191 __poll_t flags = key_to_poll(key);
192 struct kvm_kernel_irq_routing_entry irq; 192 struct kvm_kernel_irq_routing_entry irq;
193 struct kvm *kvm = irqfd->kvm; 193 struct kvm *kvm = irqfd->kvm;
194 unsigned seq; 194 unsigned seq;