Commit 3ad6f93e authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e6c8adca
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
{
	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) {
		/* An event has been signaled, call function */
+2 −2
Original line number Diff line number Diff line
@@ -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);

	if (!((unsigned long)key & poll->mask))
	if (!(key_to_poll(key) & poll->mask))
		return 0;

	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);
	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 (poll->wqh)
			remove_wait_queue(poll->wqh, &poll->wait);
+5 −4
Original line number Diff line number Diff line
@@ -1117,6 +1117,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
	unsigned long flags;
	struct epitem *epi = ep_item_from_wait(wait);
	struct eventpoll *ep = epi->ep;
	__poll_t pollflags = key_to_poll(key);
	int ewake = 0;

	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
	 * 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;

	/*
@@ -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 ((epi->event.events & EPOLLEXCLUSIVE) &&
					!((unsigned long)key & POLLFREE)) {
			switch ((unsigned long)key & EPOLLINOUT_BITS) {
					!(pollflags & POLLFREE)) {
			switch (pollflags & EPOLLINOUT_BITS) {
			case POLLIN:
				if (epi->event.events & POLLIN)
					ewake = 1;
@@ -1205,7 +1206,7 @@ out_unlock:
	if (!(epi->event.events & EPOLLEXCLUSIVE))
		ewake = 1;

	if ((unsigned long)key & POLLFREE) {
	if (pollflags & POLLFREE) {
		/*
		 * If we race with ep_remove_wait_queue() it can miss
		 * ->whead = NULL and do another remove_wait_queue() after
+1 −1
Original line number Diff line number Diff line
@@ -212,7 +212,7 @@ static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key
	struct poll_table_entry *entry;

	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 __pollwake(wait, mode, sync, key);
}
+6 −4
Original line number Diff line number Diff line
@@ -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.
 */
#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)							\
	__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)						\
	__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)					\
	__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)					\
	__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)						\
({										\
Loading