The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	Borislav Petkov <petkovbb@googlemail.com>,
	David Airlie <airlied@linux.ie>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Greg KH <greg@kroah.com>, Al Viro <viro@ZenIV.linux.org.uk>
Subject: Re: drm_vm.c:drm_mmap: possible circular locking dependency detected (was: Re: Linux 2.6.33-rc2 - Merry Christmas ...)
Date: Thu, 31 Dec 2009 11:04:48 -0800 (PST)	[thread overview]
Message-ID: <alpine.LFD.2.00.0912311043330.11961@localhost.localdomain> (raw)
In-Reply-To: <m1fx6rtu31.fsf@fess.ebiederm.org>



On Thu, 31 Dec 2009, Eric W. Biederman wrote:
> >
> >  - hibernate ends up with the sequence: _cpu_down (cpu_hotplug.lock) ->  ..
> >    kref_put .. -> sysfs_addrm_start (sysfs_mutex)
> >
> >    Again, nothing suspicious or "bad", and this part of the dependency 
> >    chain has nothing to do with the DRM code itself.
> 
> kobject_del with a lock held scares me.

I would not object at _all_ if sysfs fixed the locking here instead of in 
filldir.

The problem is that releasing objects (with kref_put() and friends) is 
something that is _commonly_ done with various locks held.

Btw, that "cpu_down()" is by no means the only case. I would suggest you 
just google for

	sysfs_mutex lockdep

and you'll find a _lot_ of cases, most of them not involving drm at all, 
but ext4 and btrfs.

(Side note: almost all of them tend to _also_ have mmap_sem in the chain: 
that's usually the thing that "closes the deal").

> There is a possible deadlock (that lockdep is ignorant of) if you hold
> a lock over sysfs_deactivate() and if any sysfs file takes that lock.
> 
> I won't argue with a claim of inconvenient locking semantics here, and
> this is different to the problem you are seeing (except that fixing this
> problem would happen to fix the filldir issue).

I suspect that filldir is almost always implicated because mmap_sem is so 
hard to do just one way: both page faulting and mmap have it held, and so 
a lot of locks need to be gotten _after_ it, while filldir very often has 
the exact reverse requirement. 

So that's why filldir is kind of special (and the fundamental _reason_ it 
is special is exactly because pretty much all other VFS operations work 
with generic caches, and the actual filesystem only fills in the caches, 
it doesn't copy to user space directly while holding any locks - although 
ioctl's sometimes have the same issue as filldir for all the same 
reasons).

Anyway, I'm in _no_ way saying that you need to break it at filldir: the 
reason I pick on filldir is because I hate it, and think that it's a 
really annoying special case at the VFS level. But from a sysfs 
standpoint, I could well see that there are worse problems than that kind 
of annoying VFS problem.

So if you can break it at that kref_put layer (which leads to releasing a 
sysfs object etc), then that would be great. In fact, it would be better, 
since kref_put and friends are in many ways "more fundamental" than some 
filldir special case that we _could_ fix in other ways.

> The cheap fix here is mostly a matter of grabbing a reference to the
> sysfs_dirent and then revalidating that the reference is still useful
> after we reacquire the sysfs_mutex.  If not we already have the code for
> restarting from just an offset.  We just don't want to use it too much as
> that will give us O(n^2) times for sysfs readdir.

Well, the _trivial_ fix is to just move the mutex_lock/unlock _inside_ the 
loop instead of of outside. Something like the appended might just work, 
and is the really stupid approach.

Totally untested. And it will do a _lot_ more sysfs mutex accesses, since 
now it will lock/unlock around each entry we return.

A smarter thing to do would probably be to rewrite the 's_sibling' search 
to instead insert a fake entry in the list, so that we don't have to 
traverse the s_sibling list every time for each entry (which is O(n**2) in 
size of the directory, and just generally horribly evil and crap code).

		Linus

---
 fs/sysfs/dir.c |   34 +++++++++++++++++++---------------
 1 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index f05f230..2d0fd42 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -847,29 +847,33 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 		if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
 			filp->f_pos++;
 	}
-	if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) {
-		mutex_lock(&sysfs_mutex);
+	while ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) {
+		const char * name;
+		int len, err;
 
+		mutex_lock(&sysfs_mutex);
 		/* Skip the dentries we have already reported */
 		pos = parent_sd->s_dir.children;
 		while (pos && (filp->f_pos > pos->s_ino))
 			pos = pos->s_sibling;
 
-		for ( ; pos; pos = pos->s_sibling) {
-			const char * name;
-			int len;
+		/* This is ok even with 'pos == NULL' */
+		sysfs_get_active(pos);
+		mutex_unlock(&sysfs_mutex);
+		if (!pos) {
+			filp->f_pos = INT_MAX;
+			break;
+		}
 
-			name = pos->s_name;
-			len = strlen(name);
-			filp->f_pos = ino = pos->s_ino;
+		name = pos->s_name;
+		len = strlen(name);
+		filp->f_pos = ino = pos->s_ino;
 
-			if (filldir(dirent, name, len, filp->f_pos, ino,
-					 dt_type(pos)) < 0)
-				break;
-		}
-		if (!pos)
-			filp->f_pos = INT_MAX;
-		mutex_unlock(&sysfs_mutex);
+		err = filldir(dirent, name, len, filp->f_pos, ino, dt_type(pos));
+		sysfs_put_active(pos);
+
+		if (err < 0)
+			break;
 	}
 	return 0;
 }

  reply	other threads:[~2009-12-31 19:05 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-24 22:00 Linux 2.6.33-rc2 - Merry Christmas Linus Torvalds
2009-12-25 10:27 ` -tip: origin tree boot crash Ingo Molnar
2009-12-25 19:49   ` Dmitry Torokhov
2009-12-26 20:19     ` Len Brown
2009-12-26 20:17   ` Len Brown
2009-12-27  4:20     ` Len Brown
2009-12-28  9:44       ` Ingo Molnar
2009-12-28 12:01         ` Ingo Molnar
2009-12-28 15:02           ` Paul Rolland
2009-12-28 16:15             ` Paul Rolland
2009-12-28 16:53             ` Paul Rolland
2009-12-28 20:17               ` Dmitry Torokhov
2009-12-30  6:14               ` Len Brown
2009-12-30  7:13                 ` Paul Rolland
2009-12-30  6:19               ` [PATCH] wmi: check find_guid() return value to prevent oops Len Brown
2009-12-30  6:21               ` [PATCH] dell-wmi: sys_init_module: 'dell_wmi'->init suspiciously returned 21, it should follow 0/-E convention Len Brown
2009-12-25 13:10 ` Linux 2.6.33-rc2 - Blank screen for Intel KMS Miguel Calleja
2009-12-29  9:50   ` Miguel Calleja
2009-12-29 14:01     ` Rafael J. Wysocki
2009-12-25 20:00 ` Linux 2.6.33-rc2 - Merry Christmas Borislav Petkov
2009-12-25 21:50   ` Borislav Petkov
2009-12-26  6:00     ` Jesse Barnes
2009-12-26  8:02       ` Borislav Petkov
2009-12-26  9:36 ` EHCI resume sysfs duplicates (was: Re: Linux 2.6.33-rc2 - Merry Christmas ...) Borislav Petkov
2009-12-26  9:45 ` drm_vm.c:drm_mmap: possible circular locking dependency detected " Borislav Petkov
2009-12-28  0:40   ` KOSAKI Motohiro
2009-12-30 21:10     ` Linus Torvalds
2009-12-30 21:34       ` Eric W. Biederman
2009-12-30 22:03         ` Linus Torvalds
2009-12-31  8:40           ` Eric W. Biederman
2009-12-31 19:04             ` Linus Torvalds [this message]
2010-01-01 13:58               ` [PATCH] sysfs: Cache the last sysfs_dirent to improve readdir scalability Eric W. Biederman
2010-01-01 15:33                 ` Borislav Petkov
2010-01-01 18:56                 ` Linus Torvalds
2010-01-01 22:43                   ` [PATCH] sysfs: Cache the last sysfs_dirent to improve readdir scalability v2 Eric W. Biederman
2010-01-01 23:10                     ` Linus Torvalds
2010-01-02  5:59                       ` Greg KH
2010-01-02 15:40                       ` Borislav Petkov
2010-01-01 15:16               ` drm_vm.c:drm_mmap: possible circular locking dependency detected (was: Re: Linux 2.6.33-rc2 - Merry Christmas ...) Eric W. Biederman
2010-01-02  2:59                 ` drm_vm.c:drm_mmap: possible circular locking dependency detected Tejun Heo
2010-01-02 21:37                   ` [PATCH] sysfs: Add lockdep annotations for the sysfs active reference Eric W. Biederman
2010-01-03  0:02                     ` Tejun Heo
2010-01-17 16:26                     ` Ming Lei
2010-01-17 17:18                       ` Eric W. Biederman
2010-01-17 18:03                         ` Dominik Brodowski
2010-01-02 21:49                   ` drm_vm.c:drm_mmap: possible circular locking dependency detected Eric W. Biederman
2010-01-03  0:32                     ` Tejun Heo
2010-01-03  2:06                       ` Eric W. Biederman
2010-01-03  5:01                         ` Tejun Heo
2010-01-03  5:38                           ` Eric W. Biederman
2010-01-03  6:05                             ` Tejun Heo
2010-01-03  7:47                       ` Dmitry Torokhov
2010-01-03 10:57                         ` Eric W. Biederman
2010-01-03 11:14                           ` Eric W. Biederman
2010-01-04 19:16                             ` Dmitry Torokhov
2010-01-04 18:57                           ` Dmitry Torokhov
2010-01-04 19:43                             ` Eric W. Biederman
2010-01-04 21:12                               ` Dmitry Torokhov
2010-01-04 23:09                               ` Tejun Heo
2009-12-31  8:40           ` drm_vm.c:drm_mmap: possible circular locking dependency detected (was: Re: Linux 2.6.33-rc2 - Merry Christmas ...) Eric W. Biederman

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=alpine.LFD.2.00.0912311043330.11961@localhost.localdomain \
    --to=torvalds@linux-foundation.org \
    --cc=airlied@linux.ie \
    --cc=ebiederm@xmission.com \
    --cc=greg@kroah.com \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=petkovbb@googlemail.com \
    --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