linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: Al Viro <viro@zeniv.linux.org.uk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	Marc Zyngier <maz@kernel.org>
Subject: Re: [RFC][PATCHSET] epoll cleanups
Date: Sun, 4 Oct 2020 13:13:29 +0100	[thread overview]
Message-ID: <20201004121329.GG20115@casper.infradead.org> (raw)
In-Reply-To: <20201004023608.GM3421308@ZenIV.linux.org.uk>

On Sun, Oct 04, 2020 at 03:36:08AM +0100, Al Viro wrote:
> 	Finally, there's the mess with reverse path check.  When we insert
> a new file into a epoll, we need to check that there won't be excessively long
> (or excessively many) wakeup chains.  If the target is not an epoll, we need
> to check that for the target alone, but if it's another epoll we need the same
> check done to everything reachable from that epoll.  The way it's currently
> done is Not Nice(tm): we collect the set of files to check and, once we have
> verified the absence of loops, created a new epitem and inserted it into
> the epoll data structures, we run reverse_path_check_proc() for every file
> in the set.  The set is maintained as a (global) cyclic list threaded through
> some struct file.  Everything is serialized on epmutex, so the list can be
> global.  Unfortunately, each struct file ends up with list_head embedded into
> it, all for the sake of operation that is rare *and* involves a small fraction
> of all struct file instances on the system.
> 	Worse, files can end up disappearing while we are collecting the set;
> explicit EPOLL_CTL_DEL does not grab epmutex, and final fput() won't touch
> epmutex if all epitem refering to that file have already been removed.  This
> had been worked around this cycle (by grabbing temporary references to struct
> file added to the set), but that's not a good solution.
> 	What we need is to separate the head of epitem list (->f_ep_links)
> from struct file; all we need in struct file is a reference to that head.
> We could thread the list representing the set of files through those objects
> (getting rid of 3 pointers in each struct file) and have epitem removal
> free those objects if there's no epitems left *and* they are not included
> into the set.  Reference from struct file would be cleared as soon as there's
> no epitems left.  Dissolving the set would free those that have no epitems
> left and thus would've been freed by ep_remove() if they hadn't been in the
> set.
> 	With some massage it can be done; we end up with
> * 3 pointers gone from each struct file
> * one pointer added to struct eventpoll
> * two-pointer object kept for each non-epoll file that is currently watched by
> some epoll.

Have you considered just storing a pointer to each struct file in an
epoll set in an XArray?  Linked lists suck for modern CPUs, and there'd
be no need to store any additional data in each struct file.  Using
xa_alloc() to store the pointer and throw away the index the pointer
got stored at would leave you with something approximating a singly
linked list, except it's an array.  Which does zero memory allocations
for a single entry and will then allocate a single node for your first
64 entries.


  parent reply	other threads:[~2020-10-04 12:13 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-04  2:36 [RFC][PATCHSET] epoll cleanups Al Viro
2020-10-04  2:39 ` [RFC PATCH 01/27] epoll: switch epitem->pwqlist to single-linked list Al Viro
2020-10-04  2:39   ` [RFC PATCH 02/27] epoll: get rid of epitem->nwait Al Viro
2020-10-04  2:39   ` [RFC PATCH 03/27] untangling ep_call_nested(): get rid of useless arguments Al Viro
2020-10-04  2:39   ` [RFC PATCH 04/27] untangling ep_call_nested(): it's all serialized on epmutex Al Viro
2020-10-04  2:39   ` [RFC PATCH 05/27] untangling ep_call_nested(): take pushing cookie into a helper Al Viro
2020-10-04  2:39   ` [RFC PATCH 06/27] untangling ep_call_nested(): move push/pop of cookie into the callbacks Al Viro
2020-10-04  2:39   ` [RFC PATCH 07/27] untangling ep_call_nested(): and there was much rejoicing Al Viro
2020-10-04  2:39   ` [RFC PATCH 08/27] reverse_path_check_proc(): sane arguments Al Viro
2020-10-04  2:39   ` [RFC PATCH 09/27] reverse_path_check_proc(): don't bother with cookies Al Viro
2020-10-04  2:39   ` [RFC PATCH 10/27] clean reverse_path_check_proc() a bit Al Viro
2020-10-04  2:39   ` [RFC PATCH 11/27] ep_loop_check_proc(): lift pushing the cookie into callers Al Viro
2020-10-04  2:39   ` [RFC PATCH 12/27] get rid of ep_push_nested() Al Viro
2020-10-04  2:39   ` [RFC PATCH 13/27] ep_loop_check_proc(): saner calling conventions Al Viro
2020-10-04  2:39   ` [RFC PATCH 14/27] ep_scan_ready_list(): prepare to splitup Al Viro
2020-10-04  2:39   ` [RFC PATCH 15/27] lift the calls of ep_read_events_proc() into the callers Al Viro
2020-10-04  2:39   ` [RFC PATCH 16/27] lift the calls of ep_send_events_proc() " Al Viro
2020-10-04  2:39   ` [RFC PATCH 17/27] ep_send_events_proc(): fold into the caller Al Viro
2020-10-04  2:39   ` [RFC PATCH 18/27] lift locking/unlocking ep->mtx out of ep_{start,done}_scan() Al Viro
2020-10-04  2:39   ` [RFC PATCH 19/27] ep_insert(): don't open-code ep_remove() on failure exits Al Viro
2020-10-04  2:39   ` [RFC PATCH 20/27] ep_insert(): we only need tep->mtx around the insertion itself Al Viro
2020-10-04 12:56     ` [ep_insert()] 9ee1cc5666: WARNING:possible_recursive_locking_detected kernel test robot
2020-10-04 14:17       ` Al Viro
2020-10-04 14:27         ` Al Viro
2020-10-04  2:39   ` [RFC PATCH 21/27] take the common part of ep_eventpoll_poll() and ep_item_poll() into helper Al Viro
2020-10-04  2:39   ` [RFC PATCH 22/27] fold ep_read_events_proc() into the only caller Al Viro
2020-10-04  2:39   ` [RFC PATCH 23/27] ep_insert(): move creation of wakeup source past the fl_ep_links insertion Al Viro
2020-10-04  2:39   ` [RFC PATCH 24/27] convert ->f_ep_links/->fllink to hlist Al Viro
2020-10-04  2:39   ` [RFC PATCH 25/27] lift rcu_read_lock() into reverse_path_check() Al Viro
2020-10-04  2:39   ` [RFC PATCH 26/27] epoll: massage the check list insertion Al Viro
2020-10-04  2:39   ` [RFC PATCH 27/27] epoll: take epitem list out of struct file Al Viro
2020-10-05 20:37     ` Qian Cai
2020-10-05 20:49       ` Al Viro
2020-10-04  2:49 ` [RFC][PATCHSET] epoll cleanups Al Viro
2020-10-04 12:13 ` Matthew Wilcox [this message]
2020-10-04 14:15   ` Al Viro
2020-10-04 18:08 ` Linus Torvalds
2020-10-04 20:05   ` Al Viro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201004121329.GG20115@casper.infradead.org \
    --to=willy@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).