Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755206AbaDWOTS (ORCPT ); Wed, 23 Apr 2014 10:19:18 -0400 Received: from mail-qc0-f173.google.com ([209.85.216.173]:44030 "EHLO mail-qc0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753628AbaDWOTM (ORCPT ); Wed, 23 Apr 2014 10:19:12 -0400 Date: Wed, 23 Apr 2014 10:19:08 -0400 From: Tejun Heo To: Johan Hovold Cc: Greg Kroah-Hartman , Alan Stern , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Li Zhong , rafael.j.wysocki@intel.com Subject: Re: [PATCH] USB: serial: fix sysfs-attribute removal deadlock Message-ID: <20140423141908.GA4781@htj.dyndns.org> References: <1398245539-1618-1-git-send-email-jhovold@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1398245539-1618-1-git-send-email-jhovold@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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: [] kernfs_remove_by_name_ns+0x4c/0x94 > > but task is already holding lock: > (table_lock){+.+.+.}, at: [] 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){+.+.+.}: > [] __lock_acquire+0x1694/0x1ce4 > [] lock_acquire+0xb4/0x154 > [] _raw_spin_lock+0x4c/0x5c > [] usb_store_new_id+0x14c/0x1ac > [] new_id_store+0x68/0x70 [usbserial] > [] drv_attr_store+0x30/0x3c > [] sysfs_kf_write+0x5c/0x60 > [] kernfs_fop_write+0xd4/0x194 > [] vfs_write+0xbc/0x198 > [] SyS_write+0x4c/0xa0 > [] ret_fast_syscall+0x0/0x48 > > -> #0 (s_active#4){++++.+}: > [] print_circular_bug+0x68/0x2f8 > [] __lock_acquire+0x1928/0x1ce4 > [] lock_acquire+0xb4/0x154 > [] __kernfs_remove+0x254/0x310 > [] kernfs_remove_by_name_ns+0x4c/0x94 > [] remove_files.isra.1+0x48/0x84 > [] sysfs_remove_group+0x58/0xac > [] sysfs_remove_groups+0x34/0x44 > [] driver_remove_groups+0x1c/0x20 > [] bus_remove_driver+0x3c/0xe4 > [] driver_unregister+0x38/0x58 > [] usb_serial_bus_deregister+0x84/0x88 [usbserial] > [] usb_serial_deregister+0x6c/0x78 [usbserial] > [] usb_serial_deregister_drivers+0x2c/0x4c [usbserial] > [] usb_serial_module_exit+0x14/0x1c [sierra] > [] SyS_delete_module+0x184/0x210 > [] 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: [] usb_serial_deregister+0x3c/0x78 [usbserial] > > stack backtrace: > CPU: 0 PID: 190 Comm: modprobe Tainted: G W 3.15.0-rc2 #123 > [] (unwind_backtrace) from [] (show_stack+0x20/0x24) > [] (show_stack) from [] (dump_stack+0x24/0x28) > [] (dump_stack) from [] (print_circular_bug+0x2ec/0x2f8) > [] (print_circular_bug) from [] (__lock_acquire+0x1928/0x1ce4) > [] (__lock_acquire) from [] (lock_acquire+0xb4/0x154) > [] (lock_acquire) from [] (__kernfs_remove+0x254/0x310) > [] (__kernfs_remove) from [] (kernfs_remove_by_name_ns+0x4c/0x94) > [] (kernfs_remove_by_name_ns) from [] (remove_files.isra.1+0x48/0x84) > [] (remove_files.isra.1) from [] (sysfs_remove_group+0x58/0xac) > [] (sysfs_remove_group) from [] (sysfs_remove_groups+0x34/0x44) > [] (sysfs_remove_groups) from [] (driver_remove_groups+0x1c/0x20) > [] (driver_remove_groups) from [] (bus_remove_driver+0x3c/0xe4) > [] (bus_remove_driver) from [] (driver_unregister+0x38/0x58) > [] (driver_unregister) from [] (usb_serial_bus_deregister+0x84/0x88 [usbserial]) > [] (usb_serial_bus_deregister [usbserial]) from [] (usb_serial_deregister+0x6c/0x78 [usbserial]) > [] (usb_serial_deregister [usbserial]) from [] (usb_serial_deregister_drivers+0x2c/0x4c [usbserial]) > [] (usb_serial_deregister_drivers [usbserial]) from [] (usb_serial_module_exit+0x14/0x1c [sierra]) > [] (usb_serial_module_exit [sierra]) from [] (SyS_delete_module+0x184/0x210) > [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x48) > > Signed-off-by: Johan Hovold > --- > > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/