linux/drivers/base
Jiri Slaby b8f04bf4f3 base: make module_create_drivers_dir race-free
[ Upstream commit 7e1b1fc4da ]

Modules which register drivers via standard path (driver_register) in
parallel can cause a warning:
WARNING: CPU: 2 PID: 3492 at ../fs/sysfs/dir.c:31 sysfs_warn_dup+0x62/0x80
sysfs: cannot create duplicate filename '/module/saa7146/drivers'
Modules linked in: hexium_gemini(+) mxb(+) ...
...
Call Trace:
...
 [<ffffffff812e63a2>] sysfs_warn_dup+0x62/0x80
 [<ffffffff812e6487>] sysfs_create_dir_ns+0x77/0x90
 [<ffffffff8140f2c4>] kobject_add_internal+0xb4/0x340
 [<ffffffff8140f5b8>] kobject_add+0x68/0xb0
 [<ffffffff8140f631>] kobject_create_and_add+0x31/0x70
 [<ffffffff8157a703>] module_add_driver+0xc3/0xd0
 [<ffffffff8155e5d4>] bus_add_driver+0x154/0x280
 [<ffffffff815604c0>] driver_register+0x60/0xe0
 [<ffffffff8145bed0>] __pci_register_driver+0x60/0x70
 [<ffffffffa0273e14>] saa7146_register_extension+0x64/0x90 [saa7146]
 [<ffffffffa0033011>] hexium_init_module+0x11/0x1000 [hexium_gemini]
...

As can be (mostly) seen, driver_register causes this call sequence:
  -> bus_add_driver
    -> module_add_driver
      -> module_create_drivers_dir
The last one creates "drivers" directory in /sys/module/<...>. When
this is done in parallel, the directory is attempted to be created
twice at the same time.

This can be easily reproduced by loading mxb and hexium_gemini in
parallel:
while :; do
  modprobe mxb &
  modprobe hexium_gemini
  wait
  rmmod mxb hexium_gemini saa7146_vv saa7146
done

saa7146 calls pci_register_driver for both mxb and hexium_gemini,
which means /sys/module/saa7146/drivers is to be created for both of
them.

Fix this by a new mutex in module_create_drivers_dir which makes the
test-and-create "drivers" dir atomic.

I inverted the condition and removed 'return' to avoid multiple
unlocks or a goto.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Fixes: fe480a2675 (Modules: only add drivers/ direcory if needed)
Cc: v2.6.21+ <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
History 2016-07-12 08:46:52 -04:00
..
power PM / sleep: Handle failures in device_suspend_late() consistently 2016-06-06 19:11:10 -04:00
regmap regmap: spmi: Fix regmap_spmi_ext_read in multi-byte case 2016-05-17 14:31:25 -04:00
attribute_container.c attribute_container: fix coding style issues 2014-09-23 22:55:15 -07:00
base.h driver core: Move driver_data back to struct device 2014-05-27 12:37:18 -07:00
bus.c driver core: bus: Goto appropriate labels on failure in bus_add_device 2015-05-17 19:12:29 -04:00
class.c sysfs: make attr namespace interface less convoluted 2013-09-26 14:50:01 -07:00
component.c component: fix bug with legacy API 2014-07-04 18:05:05 +01:00
container.c ACPI / hotplug / driver core: Handle containers in a special way 2013-12-29 15:25:48 +01:00
core.c sysfs: driver core: Fix glue dir race condition by gdp_mutex 2014-11-07 08:17:43 -08:00
cpu.c x86: align x86 arch with generic CPU modalias handling 2014-02-18 12:45:38 -08:00
dd.c driver core: Remove kerneldoc from local function 2014-09-23 23:10:11 -07:00
devcoredump.c device coredump: add new device coredump class 2014-09-23 22:53:15 -07:00
devres.c devres: fix devres_get() 2015-10-27 22:14:48 -04:00
devtmpfs.c devtmpfs: Calling delete_path() only when necessary 2013-12-19 10:10:32 -08:00
dma-coherent.c drivers: dma-coherent: add initialization from device tree 2014-10-14 02:18:12 +02:00
dma-contiguous.c drivers: of: add return value to of_reserved_mem_device_init() 2014-10-29 16:33:14 -07:00
dma-mapping.c common: dma-mapping: introduce common remapping functions 2014-10-09 22:25:52 -04:00
driver.c driver core: add #include <linux/sysfs.h> to core files. 2013-08-27 10:24:15 -07:00
firmware.c firmware: change firmware_kset to firmware_kobj 2008-01-24 20:40:23 -08:00
firmware_class.c Fix firmware loader uevent buffer NULL pointer dereference 2015-08-04 14:43:38 -04:00
hypervisor.c drivers/base: Add export.h for EXPORT_SYMBOL/THIS_MODULE as required. 2011-10-31 19:31:38 -04:00
init.c ACPI / hotplug / driver core: Handle containers in a special way 2013-12-29 15:25:48 +01:00
isa.c dma-mapping: replace all DMA_24BIT_MASK macro with DMA_BIT_MASK(24) 2009-04-07 08:31:12 -07:00
Kconfig tiny: rename ENABLE_DEV_COREDUMP to ALLOW_DEV_COREDUMP 2014-11-07 11:07:35 -08:00
Makefile Driver core: Unified device properties interface for platform firmware 2015-06-28 13:39:20 -04:00
map.c [PATCH] kobj_map semaphore to mutex conversion 2006-03-20 13:42:58 -08:00
memory.c memory-hotplug: add sysfs valid_zones attribute 2014-10-09 22:25:52 -04:00
module.c base: make module_create_drivers_dir race-free 2016-07-12 08:46:52 -04:00
node.c mm: check if section present during memory block registering 2015-10-27 22:14:54 -04:00
pinctrl.c drivers: pinctrl sleep and idle states in the core 2013-06-16 11:56:52 +02:00
platform.c drivercore: Fix unregistration path of platform devices 2015-10-27 22:14:53 -04:00
property.c Driver core: Unified device properties interface for platform firmware 2015-06-28 13:39:20 -04:00
soc.c mode_t whack-a-mole: ->is_visible() returns umode_t... 2012-05-29 23:28:42 -04:00
syscore.c genirq: Simplify wakeup mechanism 2014-09-01 13:48:59 +02:00
topology.c topology: Fix compilation warning when not in SMP 2014-04-16 14:13:26 -07:00
transport_class.c drivers/base: transport_class explicitly requires EXPORT_SYMBOL 2011-10-31 19:31:15 -04:00