diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/eventpoll.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index c806a0c4383c..64c55037c13b 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -394,27 +394,21 @@ static void ep_poll_safewake(wait_queue_head_t *wq) | |||
394 | } | 394 | } |
395 | 395 | ||
396 | /* | 396 | /* |
397 | * This function unregister poll callbacks from the associated file descriptor. | 397 | * This function unregisters poll callbacks from the associated file |
398 | * Since this must be called without holding "ep->lock" the atomic exchange trick | 398 | * descriptor. Must be called with "mtx" held (or "epmutex" if called from |
399 | * will protect us from multiple unregister. | 399 | * ep_free). |
400 | */ | 400 | */ |
401 | static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi) | 401 | static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi) |
402 | { | 402 | { |
403 | int nwait; | ||
404 | struct list_head *lsthead = &epi->pwqlist; | 403 | struct list_head *lsthead = &epi->pwqlist; |
405 | struct eppoll_entry *pwq; | 404 | struct eppoll_entry *pwq; |
406 | 405 | ||
407 | /* This is called without locks, so we need the atomic exchange */ | 406 | while (!list_empty(lsthead)) { |
408 | nwait = xchg(&epi->nwait, 0); | 407 | pwq = list_first_entry(lsthead, struct eppoll_entry, llink); |
409 | |||
410 | if (nwait) { | ||
411 | while (!list_empty(lsthead)) { | ||
412 | pwq = list_first_entry(lsthead, struct eppoll_entry, llink); | ||
413 | 408 | ||
414 | list_del_init(&pwq->llink); | 409 | list_del(&pwq->llink); |
415 | remove_wait_queue(pwq->whead, &pwq->wait); | 410 | remove_wait_queue(pwq->whead, &pwq->wait); |
416 | kmem_cache_free(pwq_cache, pwq); | 411 | kmem_cache_free(pwq_cache, pwq); |
417 | } | ||
418 | } | 412 | } |
419 | } | 413 | } |
420 | 414 | ||