Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs/epoll: deal with wait_queue only once

There is no reason why we rearm the waitiqueue upon every fetch_events
retry (for when events are found yet send_events() fails). If nothing
else, this saves four lock operations per retry, and furthermore reduces
the scope of the lock even further.

[akpm@linux-foundation.org: restore code to original position, fix and reflow comment]
Link: http://lkml.kernel.org/r/20181114182532.27981-2-dave@stgolabs.net
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Davidlohr Bueso and committed by
Linus Torvalds
86c05179 35cff1a6

+18 -11
+18 -11
fs/eventpoll.c
··· 1749 1749 { 1750 1750 int res = 0, eavail, timed_out = 0; 1751 1751 u64 slack = 0; 1752 + bool waiter = false; 1752 1753 wait_queue_entry_t wait; 1753 1754 ktime_t expires, *to = NULL; 1754 1755 ··· 1795 1794 ep_reset_busy_poll_napi_id(ep); 1796 1795 1797 1796 /* 1798 - * We don't have any available event to return to the caller. 1799 - * We need to sleep here, and we will be wake up by 1800 - * ep_poll_callback() when events will become available. 1797 + * We don't have any available event to return to the caller. We need 1798 + * to sleep here, and we will be woken by ep_poll_callback() when events 1799 + * become available. 1801 1800 */ 1802 - init_waitqueue_entry(&wait, current); 1803 - spin_lock_irq(&ep->wq.lock); 1804 - __add_wait_queue_exclusive(&ep->wq, &wait); 1805 - spin_unlock_irq(&ep->wq.lock); 1801 + if (!waiter) { 1802 + waiter = true; 1803 + init_waitqueue_entry(&wait, current); 1804 + 1805 + spin_lock_irq(&ep->wq.lock); 1806 + __add_wait_queue_exclusive(&ep->wq, &wait); 1807 + spin_unlock_irq(&ep->wq.lock); 1808 + } 1806 1809 1807 1810 for (;;) { 1808 1811 /* ··· 1842 1837 1843 1838 __set_current_state(TASK_RUNNING); 1844 1839 1845 - spin_lock_irq(&ep->wq.lock); 1846 - __remove_wait_queue(&ep->wq, &wait); 1847 - spin_unlock_irq(&ep->wq.lock); 1848 - 1849 1840 send_events: 1850 1841 /* 1851 1842 * Try to transfer events to user space. In case we get 0 events and ··· 1851 1850 if (!res && eavail && 1852 1851 !(res = ep_send_events(ep, events, maxevents)) && !timed_out) 1853 1852 goto fetch_events; 1853 + 1854 + if (waiter) { 1855 + spin_lock_irq(&ep->wq.lock); 1856 + __remove_wait_queue(&ep->wq, &wait); 1857 + spin_unlock_irq(&ep->wq.lock); 1858 + } 1854 1859 1855 1860 return res; 1856 1861 }