All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: Johan Hovold <jhovold@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Li Zhong <zhong@linux.vnet.ibm.com>,
	rafael.j.wysocki@intel.com
Subject: Re: [PATCH] USB: serial: fix sysfs-attribute removal deadlock
Date: Wed, 23 Apr 2014 10:19:08 -0400	[thread overview]
Message-ID: <20140423141908.GA4781@htj.dyndns.org> (raw)
In-Reply-To: <1398245539-1618-1-git-send-email-jhovold@gmail.com>

cc'ing Li Zhong who's working on a simliar issue in the following
thread and quoting whole body.

  http://thread.gmane.org/gmane.linux.kernel/1680706

Li, this is another variation of the same problem.  Maybe this can be
covered by your work too?

Thanks.

On Wed, Apr 23, 2014 at 11:32:19AM +0200, Johan Hovold wrote:
> Fix driver new_id sysfs-attribute removal deadlock by making sure to
> not hold any locks that the attribute operations grab when removing the
> attribute.
> 
> Specifically, usb_serial_deregister holds the table mutex when
> deregistering the driver, which includes removing the new_id attribute.
> This can lead to a deadlock as writing to new_id increments the
> attribute's active count before trying to grab the same mutex in
> usb_serial_probe.
> 
> The deadlock can easily be triggered by inserting a sleep in
> usb_serial_deregister and writing the id of an unbound device to new_id
> during module unload.
> 
> As the table mutex (in this case) is used to prevent subdriver unload
> during probe, it should be sufficient to only hold the lock while
> manipulating the usb-serial driver list during deregister. A racing
> probe will then either fail to find a matching subdriver or fail to get
> the corresponding module reference.
> 
> Since v3.15-rc1 this also triggers the following lockdep warning:
> 
> ======================================================
> [ INFO: possible circular locking dependency detected ]
> 3.15.0-rc2 #123 Tainted: G        W
> -------------------------------------------------------
> modprobe/190 is trying to acquire lock:
>  (s_active#4){++++.+}, at: [<c0167aa0>] kernfs_remove_by_name_ns+0x4c/0x94
> 
> but task is already holding lock:
>  (table_lock){+.+.+.}, at: [<bf004d84>] usb_serial_deregister+0x3c/0x78 [usbserial]
> 
> which lock already depends on the new lock.
> 
> the existing dependency chain (in reverse order) is:
> 
> -> #1 (table_lock){+.+.+.}:
>        [<c0075f84>] __lock_acquire+0x1694/0x1ce4
>        [<c0076de8>] lock_acquire+0xb4/0x154
>        [<c03af3cc>] _raw_spin_lock+0x4c/0x5c
>        [<c02bbc24>] usb_store_new_id+0x14c/0x1ac
>        [<bf007eb4>] new_id_store+0x68/0x70 [usbserial]
>        [<c025f568>] drv_attr_store+0x30/0x3c
>        [<c01690e0>] sysfs_kf_write+0x5c/0x60
>        [<c01682c0>] kernfs_fop_write+0xd4/0x194
>        [<c010881c>] vfs_write+0xbc/0x198
>        [<c0108e4c>] SyS_write+0x4c/0xa0
>        [<c000f880>] ret_fast_syscall+0x0/0x48
> 
> -> #0 (s_active#4){++++.+}:
>        [<c03a7a28>] print_circular_bug+0x68/0x2f8
>        [<c0076218>] __lock_acquire+0x1928/0x1ce4
>        [<c0076de8>] lock_acquire+0xb4/0x154
>        [<c0166b70>] __kernfs_remove+0x254/0x310
>        [<c0167aa0>] kernfs_remove_by_name_ns+0x4c/0x94
>        [<c0169fb8>] remove_files.isra.1+0x48/0x84
>        [<c016a2fc>] sysfs_remove_group+0x58/0xac
>        [<c016a414>] sysfs_remove_groups+0x34/0x44
>        [<c02623b8>] driver_remove_groups+0x1c/0x20
>        [<c0260e9c>] bus_remove_driver+0x3c/0xe4
>        [<c026235c>] driver_unregister+0x38/0x58
>        [<bf007fb4>] usb_serial_bus_deregister+0x84/0x88 [usbserial]
>        [<bf004db4>] usb_serial_deregister+0x6c/0x78 [usbserial]
>        [<bf005330>] usb_serial_deregister_drivers+0x2c/0x4c [usbserial]
>        [<bf016618>] usb_serial_module_exit+0x14/0x1c [sierra]
>        [<c009d6cc>] SyS_delete_module+0x184/0x210
>        [<c000f880>] ret_fast_syscall+0x0/0x48
> 
> other info that might help us debug this:
> 
>  Possible unsafe locking scenario:
> 
>        CPU0                    CPU1
>        ----                    ----
>   lock(table_lock);
>                                lock(s_active#4);
>                                lock(table_lock);
>   lock(s_active#4);
> 
>  *** DEADLOCK ***
> 
> 1 lock held by modprobe/190:
>  #0:  (table_lock){+.+.+.}, at: [<bf004d84>] usb_serial_deregister+0x3c/0x78 [usbserial]
> 
> stack backtrace:
> CPU: 0 PID: 190 Comm: modprobe Tainted: G        W     3.15.0-rc2 #123
> [<c0015e10>] (unwind_backtrace) from [<c0013728>] (show_stack+0x20/0x24)
> [<c0013728>] (show_stack) from [<c03a9a54>] (dump_stack+0x24/0x28)
> [<c03a9a54>] (dump_stack) from [<c03a7cac>] (print_circular_bug+0x2ec/0x2f8)
> [<c03a7cac>] (print_circular_bug) from [<c0076218>] (__lock_acquire+0x1928/0x1ce4)
> [<c0076218>] (__lock_acquire) from [<c0076de8>] (lock_acquire+0xb4/0x154)
> [<c0076de8>] (lock_acquire) from [<c0166b70>] (__kernfs_remove+0x254/0x310)
> [<c0166b70>] (__kernfs_remove) from [<c0167aa0>] (kernfs_remove_by_name_ns+0x4c/0x94)
> [<c0167aa0>] (kernfs_remove_by_name_ns) from [<c0169fb8>] (remove_files.isra.1+0x48/0x84)
> [<c0169fb8>] (remove_files.isra.1) from [<c016a2fc>] (sysfs_remove_group+0x58/0xac)
> [<c016a2fc>] (sysfs_remove_group) from [<c016a414>] (sysfs_remove_groups+0x34/0x44)
> [<c016a414>] (sysfs_remove_groups) from [<c02623b8>] (driver_remove_groups+0x1c/0x20)
> [<c02623b8>] (driver_remove_groups) from [<c0260e9c>] (bus_remove_driver+0x3c/0xe4)
> [<c0260e9c>] (bus_remove_driver) from [<c026235c>] (driver_unregister+0x38/0x58)
> [<c026235c>] (driver_unregister) from [<bf007fb4>] (usb_serial_bus_deregister+0x84/0x88 [usbserial])
> [<bf007fb4>] (usb_serial_bus_deregister [usbserial]) from [<bf004db4>] (usb_serial_deregister+0x6c/0x78 [usbserial])
> [<bf004db4>] (usb_serial_deregister [usbserial]) from [<bf005330>] (usb_serial_deregister_drivers+0x2c/0x4c [usbserial])
> [<bf005330>] (usb_serial_deregister_drivers [usbserial]) from [<bf016618>] (usb_serial_module_exit+0x14/0x1c [sierra])
> [<bf016618>] (usb_serial_module_exit [sierra]) from [<c009d6cc>] (SyS_delete_module+0x184/0x210)
> [<c009d6cc>] (SyS_delete_module) from [<c000f880>] (ret_fast_syscall+0x0/0x48)
> 
> Signed-off-by: Johan Hovold <jhovold@gmail.com>
> ---
> 
> I got this new lockdep warning with 3.15-rc, but this dates back to at
> least 0daeed381c6a ("USB-BKL: Remove BKL use for usb serial driver
> probing").
> 
> As far as I can tell, moving driver deregistration out of the table lock
> should be fine. Another option would be to get a module reference in
> new_id store, although that would still trigger the lockdep warning.
> 
> Thanks,
> Johan
> 
> 
>  drivers/usb/serial/usb-serial.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
> index 81fc0dfcfdcf..6d40d56378d7 100644
> --- a/drivers/usb/serial/usb-serial.c
> +++ b/drivers/usb/serial/usb-serial.c
> @@ -1347,10 +1347,12 @@ static int usb_serial_register(struct usb_serial_driver *driver)
>  static void usb_serial_deregister(struct usb_serial_driver *device)
>  {
>  	pr_info("USB Serial deregistering driver %s\n", device->description);
> +
>  	mutex_lock(&table_lock);
>  	list_del(&device->driver_list);
> -	usb_serial_bus_deregister(device);
>  	mutex_unlock(&table_lock);
> +
> +	usb_serial_bus_deregister(device);
>  }
>  
>  /**
> -- 
> 1.8.3.2
> 

-- 
tejun

  reply	other threads:[~2014-04-23 14:19 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-23  9:32 [PATCH] USB: serial: fix sysfs-attribute removal deadlock Johan Hovold
2014-04-23 14:19 ` Tejun Heo [this message]
2014-04-24  8:29   ` Li Zhong
2014-04-24 14:35     ` Tejun Heo
2014-04-24 14:52       ` Johan Hovold
2014-04-25  2:16         ` Li Zhong
2014-04-25 10:15           ` Johan Hovold
2014-04-28  0:39             ` Li Zhong
2014-05-02 15:20               ` Tejun Heo
2014-04-25 13:59           ` Alan Stern
2014-04-28  1:58             ` Li Zhong
2014-04-25  2:15       ` Li Zhong
2014-04-25 13:54         ` Alan Stern
2014-04-25 15:13           ` Johan Hovold
2014-04-28  1:55           ` Li Zhong

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=20140423141908.GA4781@htj.dyndns.org \
    --to=tj@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jhovold@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=stern@rowland.harvard.edu \
    --cc=zhong@linux.vnet.ibm.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 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.