linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: Mike Kravetz <mike.kravetz@oracle.com>
Cc: linux-mm@kvack.org
Subject: Re: find_swap_entry sparse cleanup
Date: Fri, 6 Apr 2018 19:28:49 -0700	[thread overview]
Message-ID: <20180407022849.GA24377@bombadil.infradead.org> (raw)
In-Reply-To: <ffad6db6-85b1-59b2-bc5e-5492d1c175ac@oracle.com>

On Fri, Apr 06, 2018 at 03:13:45PM -0700, Mike Kravetz wrote:
> As part of restructuring code for memfd, I want clean up all the
> sparse warnings in mm/shmem.c.  Most are straight forward, but I
> am not sure about find_swap_entry.  Specifically the code:
> 
> 	rcu_read_lock();
> 	radix_tree_for_each_slot(slot, root, &iter, 0) {
> 		if (*slot == item) {
> 			found = iter.index;
> 			break;
> 		}
> 		checked++;
> 		if ((checked % 4096) != 0)
> 			continue;
> 		slot = radix_tree_iter_resume(slot, &iter);
> 		cond_resched_rcu();
> 	}
> 	rcu_read_unlock();
> 
> The complaint is about that (*slot == item) comparison.
> 
> My first thought was to do the radix_tree_deref_slot(),
> radix_tree_exception(), radix_tree_deref_retry() thing.
> However, I was concerned that swap entries (which this routine
> is looking for) are stored as exception entries?  So, perhaps
> this should just use rcu_dereference_raw()?
> 
> Suggestions would be appreciated.
> 
> And, yes I do know that the XArray code would replace all this.

I'm happy to help clean this up in advance of the XArray code going in ...

This loop is actually buggy in two or three different ways.  Here's how
it should have looked:

@@ -1098,13 +1098,18 @@ static void shmem_evict_inode(struct inode *inode)
 static unsigned long find_swap_entry(struct radix_tree_root *root, void *item)
 {
        struct radix_tree_iter iter;
-       void **slot;
+       void __rcu **slot;
        unsigned long found = -1;
        unsigned int checked = 0;
 
        rcu_read_lock();
        radix_tree_for_each_slot(slot, root, &iter, 0) {
-               if (*slot == item) {
+               void *entry = radix_tree_deref_slot(slot);
+               if (radix_tree_deref_retry(entry)) {
+                       slot = radix_tree_iter_retry(&iter);
+                       continue;
+               }
+               if (entry == item) {
                        found = iter.index;
                        break;
                }

  reply	other threads:[~2018-04-07  2:28 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-06 22:13 find_swap_entry sparse cleanup Mike Kravetz
2018-04-07  2:28 ` Matthew Wilcox [this message]
2018-04-07  2:59   ` Mike Kravetz

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=20180407022849.GA24377@bombadil.infradead.org \
    --to=willy@infradead.org \
    --cc=linux-mm@kvack.org \
    --cc=mike.kravetz@oracle.com \
    /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).