epoll: remove unnecessary xchg

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Wednesday, April 1, 2009 - 11:01 am

Gitweb:     http://git.kernel.org/linus/d1bc90dd5d037079f96b3327f943eb6ae8ef7491
Commit:     d1bc90dd5d037079f96b3327f943eb6ae8ef7491
Parent:     d0305882825784e74f68a56eee6c3a812a99f235
Author:     Tony Battersby <tonyb@cybernetics.com>
AuthorDate: Tue Mar 31 15:24:15 2009 -0700
Committer:  Linus Torvalds <torvalds@linux-foundation.org>
CommitDate: Wed Apr 1 08:59:19 2009 -0700

    epoll: remove unnecessary xchg
    
    xchg in ep_unregister_pollwait() is unnecessary because it is protected by
    either epmutex or ep->mtx (the same protection as ep_remove()).
    
    If xchg was necessary, it would be insufficient to protect against
    problems: if multiple concurrent calls to ep_unregister_pollwait() were
    possible then a second caller that returns without doing anything because
    nwait == 0 could return before the waitqueues are removed by the first
    caller, which looks like it could lead to problematic races with
    ep_poll_callback().
    
    So remove xchg and add comments about the locking.
    
    Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
    Acked-by: Davide Libenzi <davidel@xmailserver.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 fs/eventpoll.c |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index c806a0c..64c5503 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -394,27 +394,21 @@ static void ep_poll_safewake(wait_queue_head_t *wq)
 }
 
 /*
- * This function unregister poll callbacks from the associated file descriptor.
- * Since this must be called without holding "ep->lock" the atomic exchange trick
- * will protect us from multiple unregister.
+ * This function unregisters poll callbacks from the associated file
+ * descriptor.  Must be called with "mtx" held (or "epmutex" if called from
+ * ep_free).
  */
 static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
 {
-	int nwait;
 	struct list_head *lsthead = &epi->pwqlist;
 	struct eppoll_entry *pwq;
 
-	/* This is called without locks, so we need the atomic exchange */
-	nwait = xchg(&epi->nwait, 0);
-
-	if (nwait) {
-		while (!list_empty(lsthead)) {
-			pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
+	while (!list_empty(lsthead)) {
+		pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
 
-			list_del_init(&pwq->llink);
-			remove_wait_queue(pwq->whead, &pwq->wait);
-			kmem_cache_free(pwq_cache, pwq);
-		}
+		list_del(&pwq->llink);
+		remove_wait_queue(pwq->whead, &pwq->wait);
+		kmem_cache_free(pwq_cache, pwq);
 	}
 }
 
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
epoll: remove unnecessary xchg, Linux Kernel Mailing ..., (Wed Apr 1, 11:01 am)