No description
  • C 98.2%
  • Assembly 1%
  • Makefile 0.3%
  • Shell 0.2%
  • Python 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Roman Penyaev 5d77631de1 epoll: atomically remove wait entry on wake up
commit 412895f03cbf9633298111cb4dfde13b7720e2c5 upstream.

This patch does two things:

 - fixes a lost wakeup introduced by commit 339ddb53d373 ("fs/epoll:
   remove unnecessary wakeups of nested epoll")

 - improves performance for events delivery.

The description of the problem is the following: if N (>1) threads are
waiting on ep->wq for new events and M (>1) events come, it is quite
likely that >1 wakeups hit the same wait queue entry, because there is
quite a big window between __add_wait_queue_exclusive() and the
following __remove_wait_queue() calls in ep_poll() function.

This can lead to lost wakeups, because thread, which was woken up, can
handle not all the events in ->rdllist.  (in better words the problem is
described here: https://lkml.org/lkml/2019/10/7/905)

The idea of the current patch is to use init_wait() instead of
init_waitqueue_entry().

Internally init_wait() sets autoremove_wake_function as a callback,
which removes the wait entry atomically (under the wq locks) from the
list, thus the next coming wakeup hits the next wait entry in the wait
queue, thus preventing lost wakeups.

Problem is very well reproduced by the epoll60 test case [1].

Wait entry removal on wakeup has also performance benefits, because
there is no need to take a ep->lock and remove wait entry from the queue
after the successful wakeup.  Here is the timing output of the epoll60
test case:

  With explicit wakeup from ep_scan_ready_list() (the state of the
  code prior 339ddb53d373):

    real    0m6.970s
    user    0m49.786s
    sys     0m0.113s

 After this patch:

   real    0m5.220s
   user    0m36.879s
   sys     0m0.019s

The other testcase is the stress-epoll [2], where one thread consumes
all the events and other threads produce many events:

  With explicit wakeup from ep_scan_ready_list() (the state of the
  code prior 339ddb53d373):

    threads  events/ms  run-time ms
          8       5427         1474
         16       6163         2596
         32       6824         4689
         64       7060         9064
        128       6991        18309

 After this patch:

    threads  events/ms  run-time ms
          8       5598         1429
         16       7073         2262
         32       7502         4265
         64       7640         8376
        128       7634        16767

 (number of "events/ms" represents event bandwidth, thus higher is
  better; number of "run-time ms" represents overall time spent
  doing the benchmark, thus lower is better)

[1] tools/testing/selftests/filesystems/epoll/epoll_wakeup_test.c
[2] https://github.com/rouming/test-tools/blob/master/stress-epoll.c

Signed-off-by: Roman Penyaev <rpenyaev@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Jason Baron <jbaron@akamai.com>
Cc: Khazhismel Kumykov <khazhy@google.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Heiher <r@hev.cc>
Cc: <stable@vger.kernel.org>
Link: http://lkml.kernel.org/r/20200430130326.1368509-2-rpenyaev@suse.de
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-05-14 07:58:26 +02:00
arch arm64: hugetlb: avoid potential NULL dereference 2020-05-14 07:58:26 +02:00
block blk-mq: Put driver tag in blk_mq_dispatch_rq_list() when no budget 2020-05-02 08:48:59 +02:00
certs
crypto crypto: rng - Fix a refcounting bug in crypto_rng_reset() 2020-04-17 10:50:16 +02:00
Documentation USB: hub: Revert commit bd0e6c9614 ("usb: hub: try old enumeration scheme first for high speed devices") 2020-04-29 16:33:14 +02:00
drivers drm: ingenic-drm: add MODULE_DEVICE_TABLE 2020-05-14 07:58:26 +02:00
fs epoll: atomically remove wait entry on wake up 2020-05-14 07:58:26 +02:00
include tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 2020-05-14 07:58:22 +02:00
init printk: queue wake_up_klogd irq_work only if per-CPU areas are ready 2020-05-02 08:48:42 +02:00
ipc ipc/mqueue.c: change __do_notify() to bypass check_kill_permission() 2020-05-14 07:58:26 +02:00
kernel tracing: Add a vmalloc_sync_mappings() for safe measure 2020-05-14 07:58:25 +02:00
lib lib: devres: add a helper function for ioremap_uc 2020-05-10 10:31:30 +02:00
LICENSES
mm mm/mremap: Add comment explaining the untagging behaviour of mremap() 2020-05-10 10:31:33 +02:00
net sctp: Fix bundling of SHUTDOWN with COOKIE-ACK 2020-05-14 07:58:24 +02:00
samples vmalloc: fix remap_vmalloc_range() bounds checks 2020-04-29 16:33:14 +02:00
scripts scripts/config: allow colons in option strings for sed 2020-05-10 10:31:27 +02:00
security selinux: properly handle multiple messages in selinux_netlink_send() 2020-05-06 08:15:17 +02:00
sound ALSA: hda: Match both PCI ID and SSID for driver blacklist 2020-05-10 10:31:31 +02:00
tools tools headers UAPI: Sync copy of arm64's asm/unistd.h with the kernel sources 2020-05-10 10:31:33 +02:00
usr
virt KVM: arm64: Fix 32bit PC wrap-around 2020-05-14 07:58:26 +02:00
.clang-format
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile Linux 5.4.40 2020-05-10 10:31:34 +02:00
README

Linux kernel
============

There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
Documentation/admin-guide/README.rst first.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``.  The formatted documentation can also be read online at:

    https://www.kernel.org/doc/html/latest/

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.