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>
This commit is contained in:
parent
e6c8adca20
commit
3ad6f93e98
|
@ -46,7 +46,7 @@ static void virqfd_deactivate(struct virqfd *virqfd)
|
||||||
static int virqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
|
static int virqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
|
||||||
{
|
{
|
||||||
struct virqfd *virqfd = container_of(wait, struct virqfd, wait);
|
struct virqfd *virqfd = container_of(wait, struct virqfd, wait);
|
||||||
unsigned long flags = (unsigned long)key;
|
__poll_t flags = key_to_poll(key);
|
||||||
|
|
||||||
if (flags & POLLIN) {
|
if (flags & POLLIN) {
|
||||||
/* An event has been signaled, call function */
|
/* An event has been signaled, call function */
|
||||||
|
|
|
@ -170,7 +170,7 @@ static int vhost_poll_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync,
|
||||||
{
|
{
|
||||||
struct vhost_poll *poll = container_of(wait, struct vhost_poll, wait);
|
struct vhost_poll *poll = container_of(wait, struct vhost_poll, wait);
|
||||||
|
|
||||||
if (!((unsigned long)key & poll->mask))
|
if (!(key_to_poll(key) & poll->mask))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vhost_poll_queue(poll);
|
vhost_poll_queue(poll);
|
||||||
|
@ -211,7 +211,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
|
||||||
|
|
||||||
mask = file->f_op->poll(file, &poll->table);
|
mask = file->f_op->poll(file, &poll->table);
|
||||||
if (mask)
|
if (mask)
|
||||||
vhost_poll_wakeup(&poll->wait, 0, 0, (void *)(uintptr_t)mask);
|
vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
|
||||||
if (mask & POLLERR) {
|
if (mask & POLLERR) {
|
||||||
if (poll->wqh)
|
if (poll->wqh)
|
||||||
remove_wait_queue(poll->wqh, &poll->wait);
|
remove_wait_queue(poll->wqh, &poll->wait);
|
||||||
|
|
|
@ -1117,6 +1117,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct epitem *epi = ep_item_from_wait(wait);
|
struct epitem *epi = ep_item_from_wait(wait);
|
||||||
struct eventpoll *ep = epi->ep;
|
struct eventpoll *ep = epi->ep;
|
||||||
|
__poll_t pollflags = key_to_poll(key);
|
||||||
int ewake = 0;
|
int ewake = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&ep->lock, flags);
|
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
|
||||||
* callback. We need to be able to handle both cases here, hence the
|
* callback. We need to be able to handle both cases here, hence the
|
||||||
* test for "key" != NULL before the event match test.
|
* test for "key" != NULL before the event match test.
|
||||||
*/
|
*/
|
||||||
if (key && !((unsigned long) key & epi->event.events))
|
if (pollflags && !(pollflags & epi->event.events))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1175,8 +1176,8 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
|
||||||
*/
|
*/
|
||||||
if (waitqueue_active(&ep->wq)) {
|
if (waitqueue_active(&ep->wq)) {
|
||||||
if ((epi->event.events & EPOLLEXCLUSIVE) &&
|
if ((epi->event.events & EPOLLEXCLUSIVE) &&
|
||||||
!((unsigned long)key & POLLFREE)) {
|
!(pollflags & POLLFREE)) {
|
||||||
switch ((unsigned long)key & EPOLLINOUT_BITS) {
|
switch (pollflags & EPOLLINOUT_BITS) {
|
||||||
case POLLIN:
|
case POLLIN:
|
||||||
if (epi->event.events & POLLIN)
|
if (epi->event.events & POLLIN)
|
||||||
ewake = 1;
|
ewake = 1;
|
||||||
|
@ -1205,7 +1206,7 @@ out_unlock:
|
||||||
if (!(epi->event.events & EPOLLEXCLUSIVE))
|
if (!(epi->event.events & EPOLLEXCLUSIVE))
|
||||||
ewake = 1;
|
ewake = 1;
|
||||||
|
|
||||||
if ((unsigned long)key & POLLFREE) {
|
if (pollflags & POLLFREE) {
|
||||||
/*
|
/*
|
||||||
* If we race with ep_remove_wait_queue() it can miss
|
* If we race with ep_remove_wait_queue() it can miss
|
||||||
* ->whead = NULL and do another remove_wait_queue() after
|
* ->whead = NULL and do another remove_wait_queue() after
|
||||||
|
|
|
@ -212,7 +212,7 @@ static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key
|
||||||
struct poll_table_entry *entry;
|
struct poll_table_entry *entry;
|
||||||
|
|
||||||
entry = container_of(wait, struct poll_table_entry, wait);
|
entry = container_of(wait, struct poll_table_entry, wait);
|
||||||
if (key && !((unsigned long)key & entry->key))
|
if (key && !(key_to_poll(key) & entry->key))
|
||||||
return 0;
|
return 0;
|
||||||
return __pollwake(wait, mode, sync, key);
|
return __pollwake(wait, mode, sync, key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,14 +206,16 @@ void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode, int nr);
|
||||||
/*
|
/*
|
||||||
* Wakeup macros to be used to report events to the targets.
|
* Wakeup macros to be used to report events to the targets.
|
||||||
*/
|
*/
|
||||||
|
#define poll_to_key(m) ((void *)(__force uintptr_t)(__poll_t)(m))
|
||||||
|
#define key_to_poll(m) ((__force __poll_t)(uintptr_t)(void *)(m))
|
||||||
#define wake_up_poll(x, m) \
|
#define wake_up_poll(x, m) \
|
||||||
__wake_up(x, TASK_NORMAL, 1, (void *) (m))
|
__wake_up(x, TASK_NORMAL, 1, poll_to_key(m))
|
||||||
#define wake_up_locked_poll(x, m) \
|
#define wake_up_locked_poll(x, m) \
|
||||||
__wake_up_locked_key((x), TASK_NORMAL, (void *) (m))
|
__wake_up_locked_key((x), TASK_NORMAL, poll_to_key(m))
|
||||||
#define wake_up_interruptible_poll(x, m) \
|
#define wake_up_interruptible_poll(x, m) \
|
||||||
__wake_up(x, TASK_INTERRUPTIBLE, 1, (void *) (m))
|
__wake_up(x, TASK_INTERRUPTIBLE, 1, poll_to_key(m))
|
||||||
#define wake_up_interruptible_sync_poll(x, m) \
|
#define wake_up_interruptible_sync_poll(x, m) \
|
||||||
__wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, (void *) (m))
|
__wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, poll_to_key(m))
|
||||||
|
|
||||||
#define ___wait_cond_timeout(condition) \
|
#define ___wait_cond_timeout(condition) \
|
||||||
({ \
|
({ \
|
||||||
|
|
|
@ -3777,7 +3777,7 @@ static int memcg_event_wake(wait_queue_entry_t *wait, unsigned mode,
|
||||||
struct mem_cgroup_event *event =
|
struct mem_cgroup_event *event =
|
||||||
container_of(wait, struct mem_cgroup_event, wait);
|
container_of(wait, struct mem_cgroup_event, wait);
|
||||||
struct mem_cgroup *memcg = event->memcg;
|
struct mem_cgroup *memcg = event->memcg;
|
||||||
unsigned long flags = (unsigned long)key;
|
__poll_t flags = key_to_poll(key);
|
||||||
|
|
||||||
if (flags & POLLHUP) {
|
if (flags & POLLHUP) {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -72,12 +72,10 @@ static inline int connection_based(struct sock *sk)
|
||||||
static int receiver_wake_function(wait_queue_entry_t *wait, unsigned int mode, int sync,
|
static int receiver_wake_function(wait_queue_entry_t *wait, unsigned int mode, int sync,
|
||||||
void *key)
|
void *key)
|
||||||
{
|
{
|
||||||
unsigned long bits = (unsigned long)key;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid a wakeup if event not interesting for us
|
* Avoid a wakeup if event not interesting for us
|
||||||
*/
|
*/
|
||||||
if (bits && !(bits & (POLLIN | POLLERR)))
|
if (key && !(key_to_poll(key) & (POLLIN | POLLERR)))
|
||||||
return 0;
|
return 0;
|
||||||
return autoremove_wake_function(wait, mode, sync, key);
|
return autoremove_wake_function(wait, mode, sync, key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,7 +367,7 @@ static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int
|
||||||
/* relaying can only happen while the wq still exists */
|
/* relaying can only happen while the wq still exists */
|
||||||
u_sleep = sk_sleep(&u->sk);
|
u_sleep = sk_sleep(&u->sk);
|
||||||
if (u_sleep)
|
if (u_sleep)
|
||||||
wake_up_interruptible_poll(u_sleep, key);
|
wake_up_interruptible_poll(u_sleep, key_to_poll(key));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
|
||||||
{
|
{
|
||||||
struct kvm_kernel_irqfd *irqfd =
|
struct kvm_kernel_irqfd *irqfd =
|
||||||
container_of(wait, struct kvm_kernel_irqfd, wait);
|
container_of(wait, struct kvm_kernel_irqfd, wait);
|
||||||
unsigned long flags = (unsigned long)key;
|
__poll_t flags = key_to_poll(key);
|
||||||
struct kvm_kernel_irq_routing_entry irq;
|
struct kvm_kernel_irq_routing_entry irq;
|
||||||
struct kvm *kvm = irqfd->kvm;
|
struct kvm *kvm = irqfd->kvm;
|
||||||
unsigned seq;
|
unsigned seq;
|
||||||
|
|
Loading…
Reference in New Issue