All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Thelen <gthelen@google.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Dave Chinner <david@fromorbit.com>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	Greg Thelen <gthelen@google.com>
Subject: [PATCH] vfs: dcache: cond_resched in shrink_dentry_list
Date: Mon, 25 Mar 2013 10:22:31 -0700	[thread overview]
Message-ID: <1364232151-23242-1-git-send-email-gthelen@google.com> (raw)

Call cond_resched() from shrink_dentry_list() to preserve
shrink_dcache_parent() interactivity.

void shrink_dcache_parent(struct dentry * parent)
{
	while ((found = select_parent(parent, &dispose)) != 0)
		shrink_dentry_list(&dispose);
}

select_parent() populates the dispose list with dentries which
shrink_dentry_list() then deletes.  select_parent() carefully uses
need_resched() to avoid doing too much work at once.  But neither
shrink_dcache_parent() nor its called functions call cond_resched().
So once need_resched() is set select_parent() will return single
dentry dispose list which is then deleted by shrink_dentry_list().
This is inefficient when there are a lot of dentry to process.  This
can cause softlockup and hurts interactivity on non preemptable
kernels.

This change adds a call to cond_resched() in shrink_dentry_list().
The primary benefit of this is that need_resched() is quickly cleared
so that future calls to select_parent() are able to efficiently return
a big batch of dentry.  A theoretically secondary benefit of this
change is that shrink_dentry_list() is willing to give up the
processor when working on a huge number of dentry.

These additional cond_resched() do not seem to impact performance, at
least for the workload below.

Here is a program which can cause soft lockup on a if other system
activity sets need_resched().

	int main()
	{
	        struct rlimit rlim;
	        int i;
	        int f[100000];
	        char buf[20];
	        struct timeval t1, t2;
	        double diff;

	        /* cleanup past run */
	        system("rm -rf x");

	        /* boost nfile rlimit */
	        rlim.rlim_cur = 200000;
	        rlim.rlim_max = 200000;
	        if (setrlimit(RLIMIT_NOFILE, &rlim))
	                err(1, "setrlimit");

	        /* make directory for files */
	        if (mkdir("x", 0700))
	                err(1, "mkdir");

	        if (gettimeofday(&t1, NULL))
	                err(1, "gettimeofday");

	        /* populate directory with open files */
	        for (i = 0; i < 100000; i++) {
	                snprintf(buf, sizeof(buf), "x/%d", i);
	                f[i] = open(buf, O_CREAT);
	                if (f[i] == -1)
	                        err(1, "open");
	        }

	        /* close some of the files */
	        for (i = 0; i < 85000; i++)
	                close(f[i]);

	        /* unlink all files, even open ones */
	        system("rm -rf x");

	        if (gettimeofday(&t2, NULL))
	                err(1, "gettimeofday");

	        diff = (((double)t2.tv_sec * 1000000 + t2.tv_usec) -
	                ((double)t1.tv_sec * 1000000 + t1.tv_usec));

	        printf("done: %g elapsed\n", diff/1e6);
	        return 0;
	}

Signed-off-by: Greg Thelen <gthelen@google.com>
---
 fs/dcache.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/dcache.c b/fs/dcache.c
index fbfae008..105e973 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -818,6 +818,8 @@ static void shrink_dentry_list(struct list_head *list)
 
 		try_prune_one_dentry(dentry);
 
+		cond_resched();
+
 		rcu_read_lock();
 	}
 	rcu_read_unlock();
-- 
1.8.1.3

             reply	other threads:[~2013-03-25 17:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-25 17:22 Greg Thelen [this message]
2013-03-25 23:56 ` [PATCH] vfs: dcache: cond_resched in shrink_dentry_list Dave Chinner
2013-03-26  0:39   ` Greg Thelen
2013-03-26  2:40     ` Dave Chinner
2013-03-26  4:36       ` Greg Thelen
2013-04-10  0:37         ` Greg Thelen
2013-04-10  0:37           ` Greg Thelen
2013-04-10 23:44           ` Andrew Morton
2013-04-10 23:44             ` Andrew Morton
2013-04-11  0:15             ` Greg Thelen
2013-04-11  0:15               ` Greg Thelen

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=1364232151-23242-1-git-send-email-gthelen@google.com \
    --to=gthelen@google.com \
    --cc=david@fromorbit.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.