| From 0e3dc1c8f7263356c1114ddd9571709d003b31b8 Mon Sep 17 00:00:00 2001 |
| From: Davidlohr Bueso <dave@stgolabs.net> |
| Date: Thu, 3 Jan 2019 15:27:09 -0800 |
| Subject: fs/epoll: drop ovflist branch prediction |
| |
| [ Upstream commit 76699a67f3041ff4c7af6d6ee9be2bfbf1ffb671 ] |
| |
| The ep->ovflist is a secondary ready-list to temporarily store events |
| that might occur when doing sproc without holding the ep->wq.lock. This |
| accounts for every time we check for ready events and also send events |
| back to userspace; both callbacks, particularly the latter because of |
| copy_to_user, can account for a non-trivial time. |
| |
| As such, the unlikely() check to see if the pointer is being used, seems |
| both misleading and sub-optimal. In fact, we go to an awful lot of |
| trouble to sync both lists, and populating the ovflist is far from an |
| uncommon scenario. |
| |
| For example, profiling a concurrent epoll_wait(2) benchmark, with |
| CONFIG_PROFILE_ANNOTATED_BRANCHES shows that for a two threads a 33% |
| incorrect rate was seen; and when incrementally increasing the number of |
| epoll instances (which is used, for example for multiple queuing load |
| balancing models), up to a 90% incorrect rate was seen. |
| |
| Similarly, by deleting the prediction, 3% throughput boost was seen |
| across incremental threads. |
| |
| Link: http://lkml.kernel.org/r/20181108051006.18751-4-dave@stgolabs.net |
| Signed-off-by: Davidlohr Bueso <dbueso@suse.de> |
| Reviewed-by: Andrew Morton <akpm@linux-foundation.org> |
| Cc: Al Viro <viro@zeniv.linux.org.uk> |
| Cc: Jason Baron <jbaron@akamai.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/eventpoll.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| diff --git a/fs/eventpoll.c b/fs/eventpoll.c |
| index 2fabd19cdeea..c291bf61afb9 100644 |
| --- a/fs/eventpoll.c |
| +++ b/fs/eventpoll.c |
| @@ -1167,7 +1167,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v |
| * semantics). All the events that happen during that period of time are |
| * chained in ep->ovflist and requeued later on. |
| */ |
| - if (unlikely(ep->ovflist != EP_UNACTIVE_PTR)) { |
| + if (ep->ovflist != EP_UNACTIVE_PTR) { |
| if (epi->next == EP_UNACTIVE_PTR) { |
| epi->next = ep->ovflist; |
| ep->ovflist = epi; |
| -- |
| 2.19.1 |
| |