linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rafael@kernel.org>
To: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	dri-devel <dri-devel@lists.freedesktop.org>,
	intel-gfx <intel-gfx@lists.freedesktop.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	ramalingam.c@intel.com, aspriel@gmail.com,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	brgl@bgdev.pl, Heikki Krogerus <heikki.krogerus@linux.intel.com>,
	Vivek Gautam <vivek.gautam@codeaurora.org>,
	Joe Perches <joe@perches.com>,
	Daniel Vetter <daniel.vetter@intel.com>
Subject: Re: [PATCH] sysfs: Disable lockdep for driver bind/unbind files
Date: Wed, 19 Dec 2018 10:30:47 +0100	[thread overview]
Message-ID: <CAJZ5v0g6Nmmjp3a7vkS-C+caq1niq3Usa8NAm+gJ6R1O005TSw@mail.gmail.com> (raw)
In-Reply-To: <CAKMK7uF0dDeomEyDkeZGSqCE66f76ME2EkuExVPJv6Bu=tKQSg@mail.gmail.com>

On Wed, Dec 19, 2018 at 10:24 AM Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>
> On Wed, Dec 19, 2018 at 8:01 AM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > On Tue, Dec 18, 2018 at 09:14:43PM +0100, Daniel Vetter wrote:
> > > This is the much more correct fix for my earlier attempt at:
> > >
> > > https://lkml.org/lkml/2018/12/10/118
> > >
> > > Short recap:
> > >
> > > - There's not actually a locking issue, it's just lockdep being a bit
> > >   too eager to complain about a possible deadlock.
> > >
> > > - Contrary to what I claimed the real problem is recursion on
> > >   kn->count. Greg pointed me at sysfs_break_active_protection(), used
> > >   by the scsi subsystem to allow a sysfs file to unbind itself. That
> > >   would be a real deadlock, which isn't what's happening here. Also,
> > >   breaking the active protection means we'd need to manually handle
> > >   all the lifetime fun.
> > >
> > > - With Rafael we discussed the task_work approach, which kinda works,
> > >   but has two downsides: It's a functional change for a lockdep
> > >   annotation issue, and it won't work for the bind file (which needs
> > >   to get the errno from the driver load function back to userspace).
> > >
> > > - Greg also asked why this never showed up: To hit this you need to
> > >   unregister a 2nd driver from the unload code of your first driver. I
> > >   guess only gpus do that. The bug has always been there, but only
> > >   with a recent patch series did we add more locks so that lockdep
> > >   built a chain from unbinding the snd-hda driver to the
> > >   acpi_video_unregister call.
> > >
> > > Full lockdep splat:
> > >
> > > [12301.898799] ============================================
> > > [12301.898805] WARNING: possible recursive locking detected
> > > [12301.898811] 4.20.0-rc7+ #84 Not tainted
> > > [12301.898815] --------------------------------------------
> > > [12301.898821] bash/5297 is trying to acquire lock:
> > > [12301.898826] 00000000f61c6093 (kn->count#39){++++}, at: kernfs_remove_by_name_ns+0x3b/0x80
> > > [12301.898841] but task is already holding lock:
> > > [12301.898847] 000000005f634021 (kn->count#39){++++}, at: kernfs_fop_write+0xdc/0x190
> > > [12301.898856] other info that might help us debug this:
> > > [12301.898862]  Possible unsafe locking scenario:
> > > [12301.898867]        CPU0
> > > [12301.898870]        ----
> > > [12301.898874]   lock(kn->count#39);
> > > [12301.898879]   lock(kn->count#39);
> > > [12301.898883] *** DEADLOCK ***
> > > [12301.898891]  May be due to missing lock nesting notation
> > > [12301.898899] 5 locks held by bash/5297:
> > > [12301.898903]  #0: 00000000cd800e54 (sb_writers#4){.+.+}, at: vfs_write+0x17f/0x1b0
> > > [12301.898915]  #1: 000000000465e7c2 (&of->mutex){+.+.}, at: kernfs_fop_write+0xd3/0x190
> > > [12301.898925]  #2: 000000005f634021 (kn->count#39){++++}, at: kernfs_fop_write+0xdc/0x190
> > > [12301.898936]  #3: 00000000414ef7ac (&dev->mutex){....}, at: device_release_driver_internal+0x34/0x240
> > > [12301.898950]  #4: 000000003218fbdf (register_count_mutex){+.+.}, at: acpi_video_unregister+0xe/0x40
> > > [12301.898960] stack backtrace:
> > > [12301.898968] CPU: 1 PID: 5297 Comm: bash Not tainted 4.20.0-rc7+ #84
> > > [12301.898974] Hardware name: Hewlett-Packard HP EliteBook 8460p/161C, BIOS 68SCF Ver. F.01 03/11/2011
> > > [12301.898982] Call Trace:
> > > [12301.898989]  dump_stack+0x67/0x9b
> > > [12301.898997]  __lock_acquire+0x6ad/0x1410
> > > [12301.899003]  ? kernfs_remove_by_name_ns+0x3b/0x80
> > > [12301.899010]  ? find_held_lock+0x2d/0x90
> > > [12301.899017]  ? mutex_spin_on_owner+0xe4/0x150
> > > [12301.899023]  ? find_held_lock+0x2d/0x90
> > > [12301.899030]  ? lock_acquire+0x90/0x180
> > > [12301.899036]  lock_acquire+0x90/0x180
> > > [12301.899042]  ? kernfs_remove_by_name_ns+0x3b/0x80
> > > [12301.899049]  __kernfs_remove+0x296/0x310
> > > [12301.899055]  ? kernfs_remove_by_name_ns+0x3b/0x80
> > > [12301.899060]  ? kernfs_name_hash+0xd/0x80
> > > [12301.899066]  ? kernfs_find_ns+0x6c/0x100
> > > [12301.899073]  kernfs_remove_by_name_ns+0x3b/0x80
> > > [12301.899080]  bus_remove_driver+0x92/0xa0
> > > [12301.899085]  acpi_video_unregister+0x24/0x40
> > > [12301.899127]  i915_driver_unload+0x42/0x130 [i915]
> > > [12301.899160]  i915_pci_remove+0x19/0x30 [i915]
> > > [12301.899169]  pci_device_remove+0x36/0xb0
> > > [12301.899176]  device_release_driver_internal+0x185/0x240
> > > [12301.899183]  unbind_store+0xaf/0x180
> > > [12301.899189]  kernfs_fop_write+0x104/0x190
> > > [12301.899195]  __vfs_write+0x31/0x180
> > > [12301.899203]  ? rcu_read_lock_sched_held+0x6f/0x80
> > > [12301.899209]  ? rcu_sync_lockdep_assert+0x29/0x50
> > > [12301.899216]  ? __sb_start_write+0x13c/0x1a0
> > > [12301.899221]  ? vfs_write+0x17f/0x1b0
> > > [12301.899227]  vfs_write+0xb9/0x1b0
> > > [12301.899233]  ksys_write+0x50/0xc0
> > > [12301.899239]  do_syscall_64+0x4b/0x180
> > > [12301.899247]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> > > [12301.899253] RIP: 0033:0x7f452ac7f7a4
> > > [12301.899259] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 80 00 00 00 00 8b 05 aa f0 2c 00 48 63 ff 85 c0 75 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 f3 c3 66 90 55 53 48 89 d5 48 89 f3 48 83
> > > [12301.899273] RSP: 002b:00007ffceafa6918 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
> > > [12301.899282] RAX: ffffffffffffffda RBX: 000000000000000d RCX: 00007f452ac7f7a4
> > > [12301.899288] RDX: 000000000000000d RSI: 00005612a1abf7c0 RDI: 0000000000000001
> > > [12301.899295] RBP: 00005612a1abf7c0 R08: 000000000000000a R09: 00005612a1c46730
> > > [12301.899301] R10: 000000000000000a R11: 0000000000000246 R12: 000000000000000d
> > > [12301.899308] R13: 0000000000000001 R14: 00007f452af4a740 R15: 000000000000000d
> > >
> > > Locking around I've noticed that usb and i2c already handle similar
> > > recursion problems, where a sysfs file can unbind the same type of
> > > sysfs somewhere else in the hierarchy. Relevant commits are:
> > >
> > > commit 356c05d58af05d582e634b54b40050c73609617b
> > > Author: Alan Stern <stern@rowland.harvard.edu>
> > > Date:   Mon May 14 13:30:03 2012 -0400
> > >
> > >     sysfs: get rid of some lockdep false positives
> > >
> > > commit e9b526fe704812364bca07edd15eadeba163ebfb
> > > Author: Alexander Sverdlin <alexander.sverdlin@nsn.com>
> > > Date:   Fri May 17 14:56:35 2013 +0200
> > >
> > >     i2c: suppress lockdep warning on delete_device
> > >
> > > Implement the same trick for driver bind/unbind.
> > >
> > > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > > Cc: Ramalingam C <ramalingam.c@intel.com>
> > > Cc: Arend van Spriel <aspriel@gmail.com>
> > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > > Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> > > Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> > > Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > Cc: Vivek Gautam <vivek.gautam@codeaurora.org>
> > > Cc: Joe Perches <joe@perches.com>
> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > ---
> > >  drivers/base/bus.c     | 4 ++--
> > >  include/linux/device.h | 4 ++++
> > >  2 files changed, 6 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/base/bus.c b/drivers/base/bus.c
> > > index 8bfd27ec73d6..5d2411b848cd 100644
> > > --- a/drivers/base/bus.c
> > > +++ b/drivers/base/bus.c
> > > @@ -195,7 +195,7 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf,
> > >       bus_put(bus);
> > >       return err;
> > >  }
> > > -static DRIVER_ATTR_WO(unbind);
> > > +static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, S_IWUSR, NULL, unbind_store);
> > >
> > >  /*
> > >   * Manually attach a device to a driver.
> > > @@ -231,7 +231,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
> > >       bus_put(bus);
> > >       return err;
> > >  }
> > > -static DRIVER_ATTR_WO(bind);
> > > +static DRIVER_ATTR_IGNORE_LOCKDEP(bind, S_IWUSR, NULL, bind_store);
> > >
> > >  static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf)
> > >  {
> > > diff --git a/include/linux/device.h b/include/linux/device.h
> > > index 1b25c7a43f4c..d2cb1a6c5d95 100644
> > > --- a/include/linux/device.h
> > > +++ b/include/linux/device.h
> > > @@ -326,6 +326,10 @@ struct driver_attribute {
> > >       struct driver_attribute driver_attr_##_name = __ATTR_RO(_name)
> > >  #define DRIVER_ATTR_WO(_name) \
> > >       struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
> > > +#define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
> > > +     struct driver_attribute driver_attr_##_name =           \
> > > +             __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
> > > +
> >
> > I don't want to give driver writers the ability to shoot themselves in
> > the foot, can you just put this in the bus.c file itself so that no one
> > else will abuse this and "open code" the unbind/bind attributes instead
> > of using a #define for it?
>
> So part of the reasons I've put these here is that I think we can do a
> lot better. Instead of ignoring lockdep I think we can implement
> nested lockdep annotations. It's going to be a bit a pain to wire that
> through from sysfs->kernfs, but for all the (now 3) uses of
> _IGNORE_LOCKDEP it should work if the add/remove_files functions use
> mutex_lock_nested.

Agreed.

>I think then there's not really a problem with
> exposing this. Aside from it's already exposed, but only for devices,
> as DEVICE_ATTR_IGNORE_LOCKDEP.

Right.

  reply	other threads:[~2018-12-19  9:31 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-18 20:14 [PATCH] sysfs: Disable lockdep for driver bind/unbind files Daniel Vetter
2018-12-18 21:40 ` Rafael J. Wysocki
2018-12-19  7:01 ` Greg Kroah-Hartman
2018-12-19  9:24   ` Daniel Vetter
2018-12-19  9:30     ` Rafael J. Wysocki [this message]
2018-12-19  9:24   ` Rafael J. Wysocki
2018-12-19  9:44     ` Greg Kroah-Hartman
2018-12-19 12:39 ` Daniel Vetter
2018-12-19 12:49   ` Greg Kroah-Hartman
2018-12-19 13:18     ` Daniel Vetter
2018-12-19 13:26       ` Daniel Vetter
2018-12-19 15:00         ` Greg Kroah-Hartman
2018-12-19 14:21   ` Rafael J. Wysocki
2018-12-19 15:23     ` Daniel Vetter

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=CAJZ5v0g6Nmmjp3a7vkS-C+caq1niq3Usa8NAm+gJ6R1O005TSw@mail.gmail.com \
    --to=rafael@kernel.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=aspriel@gmail.com \
    --cc=brgl@bgdev.pl \
    --cc=daniel.vetter@ffwll.ch \
    --cc=daniel.vetter@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=geert+renesas@glider.be \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=joe@perches.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ramalingam.c@intel.com \
    --cc=vivek.gautam@codeaurora.org \
    /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).