linux/drivers/acpi
Carlos Garnacho 12c78ca2ab ACPI / battery: Add sysfs representation after checking _BST
Thus move sysfs_add_battery() after acpi_battery_get_state(), which doesn't
require the power_supply. Prevents possible hanged tasks if
acpi_battery_get_state() fails consistently (and takes a long time in doing
so) when called inside acpi_battery_add().

In this situation the battery module first calls sysfs_add_battery(),
which creates a power_supply, which spawns an async
power_supply_deferred_register_work() task, which shall try to hold the
parent battery device mutex (being already held) so this register work
is set up after device initialization. If initialization takes long enough
the thread will be eventually run and try to hold the mutex before
acpi_battery_add() had the chance to finish.

Eventually the 5 retries in acpi_battery_update_retry() fail, the error
state is propagated, and results in sysfs_remove_battery() being called
within the error handling paths of acpi_battery_add(), and the power_supply
tear down too.

This triggers a cancel_delayed_work_sync() of the deferred_register_work
task, which ends up in schedule(). The end result is that the deferred
task is blocked trying to acquire the parent device mutex, which is not
released because the thread doing initialization (and failure handling)
went to sleep awaiting for the deferred task to be cancelled.

The hanged tasks look like this:

INFO: task kworker/u8:0:6 blocked for more than 120 seconds.
 ...
Call Trace:
 [<ffffffff815daec5>] schedule+0x35/0x80
 [<ffffffff815dda3c>] schedule_timeout+0x1ec/0x250
 [<ffffffff810a0572>] ? check_preempt_curr+0x52/0x90
 [<ffffffff810a05c9>] ? ttwu_do_wakeup+0x19/0xe0
 [<ffffffff815db915>] wait_for_common+0xc5/0x190
 [<ffffffff810a1500>] ? wake_up_q+0x70/0x70
 [<ffffffff815db9fd>] wait_for_completion+0x1d/0x20
 [<ffffffff8108ffb1>] flush_work+0x111/0x1c0
 [<ffffffff8108dfe0>] ? flush_workqueue_prep_pwqs+0x1a0/0x1a0
 [<ffffffff810909af>] __cancel_work_timer+0x9f/0x1d0
 [<ffffffff81090b13>] cancel_delayed_work_sync+0x13/0x20
 [<ffffffff8147ac67>] power_supply_unregister+0x37/0xc0
 [<ffffffffa058b03d>] sysfs_remove_battery+0x3d/0x52 [battery]
 [<ffffffffa058bf3a>] acpi_battery_add+0x112/0x181 [battery]
 [<ffffffff81366db6>] acpi_device_probe+0x54/0x19b
 [<ffffffff81427e9c>] driver_probe_device+0x22c/0x440
 [<ffffffff81428181>] __driver_attach+0xd1/0xf0
 [<ffffffff814280b0>] ? driver_probe_device+0x440/0x440
 [<ffffffff8142591c>] bus_for_each_dev+0x6c/0xc0
 [<ffffffff8142758e>] driver_attach+0x1e/0x20
 [<ffffffff81426fc3>] bus_add_driver+0x1c3/0x280
 [<ffffffff81428b00>] driver_register+0x60/0xe0
 [<ffffffff81366c80>] acpi_bus_register_driver+0x3b/0x43
 [<ffffffffa0591040>] acpi_battery_init_async+0x1c/0x1e [battery]
 [<ffffffff81099268>] async_run_entry_fn+0x48/0x150
 [<ffffffff81090d09>] process_one_work+0x1e9/0x440
 [<ffffffff81090fab>] worker_thread+0x4b/0x4f0
 [<ffffffff81090f60>] ? process_one_work+0x440/0x440
 [<ffffffff81096b58>] kthread+0xd8/0xf0
 [<ffffffff815de97f>] ret_from_fork+0x1f/0x40
 [<ffffffff81096a80>] ? kthread_worker_fn+0x180/0x180

INFO: task kworker/u8:4:282 blocked for more than 120 seconds.
 ...
Call Trace:
 [<ffffffff810ad745>] ? put_prev_entity+0x35/0x8b0
 [<ffffffff815daec5>] schedule+0x35/0x80
 [<ffffffff815db14e>] schedule_preempt_disabled+0xe/0x10
 [<ffffffff815dc533>] __mutex_lock_slowpath+0xb3/0x120
 [<ffffffff815dc5bf>] mutex_lock+0x1f/0x30
 [<ffffffff8147a59b>] power_supply_deferred_register_work+0x2b/0x50
 [<ffffffff81090d09>] process_one_work+0x1e9/0x440
 [<ffffffff81090fab>] worker_thread+0x4b/0x4f0
 [<ffffffff81090f60>] ? process_one_work+0x440/0x440
 [<ffffffff81090f60>] ? process_one_work+0x440/0x440
 [<ffffffff81096b58>] kthread+0xd8/0xf0
 [<ffffffff815de97f>] ret_from_fork+0x1f/0x40
 [<ffffffff81096a80>] ? kthread_worker_fn+0x180/0x180

Making sysfs_add_battery() the last operation here means that the
power_supply won't be created yet when the acpi_add_battery() failure
handling happens, the deferred task won't even spawn, and
sysfs_remove_battery will just skip over the NULL battery->bat.

Signed-off-by: Carlos Garnacho <carlosg@gnome.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2016-08-31 00:35:16 +02:00
..
acpica Revert "ACPICA: Namespace: Fix deadlock triggered by MLC support in dynamic table loading" 2016-07-11 16:18:18 +02:00
apei pstore subsystem updates for v4.8 2016-07-26 18:48:23 -07:00
dptf ACPI / DPTF: move int340x_thermal.c to the DPTF folder 2016-07-21 13:42:46 +02:00
nfit libnvdimm, nd_blk: mask off reserved status bits 2016-08-08 09:26:13 -07:00
pmic ACPI / PMIC: remove modular references from non-modular code 2016-07-16 03:03:14 +02:00
ac.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
acpi_amba.c ACPI / amba: Remove CLK_IS_ROOT 2016-04-27 23:42:57 +02:00
acpi_apd.c ACPI / APD: Remove CLK_IS_ROOT 2016-04-27 23:42:57 +02:00
acpi_cmos_rtc.c char/genrtc: x86: remove remnants of asm/rtc.h 2016-06-04 00:20:07 +02:00
acpi_configfs.c ACPI: Rename configfs.c to acpi_configfs.c to prevent link error 2016-07-11 15:13:36 +02:00
acpi_dbg.c ACPI / debugger: Fix regression introduced by IS_ERR_VALUE() removal 2016-07-05 23:02:34 +02:00
acpi_extlog.c ACPI and power management updates for 3.17-rc1 2014-08-06 20:34:19 -07:00
acpi_ipmi.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
acpi_lpat.c ACPI / lpat: make it explicitly non-modular 2016-07-16 03:08:10 +02:00
acpi_lpss.c x86/acpi/lss: Use Intel family name macros for the acpi_lpss driver 2016-06-08 13:03:26 +02:00
acpi_memhotplug.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
acpi_pad.c ACPI / PAD: power_saving_thread() is not freezable 2015-10-26 04:42:54 +01:00
acpi_platform.c Power management and ACPI material for v4.6-rc1, part 1 2016-03-16 14:10:53 -07:00
acpi_pnp.c ACPI / PNP: constify device IDs 2016-01-04 22:10:30 +01:00
acpi_processor.c ACPI / processor: Avoid reserving IO regions too early 2016-06-02 01:57:50 +02:00
acpi_video.c ACPI / video: skip evaluating _DOD when it does not exist 2016-06-22 02:00:04 +02:00
battery.c ACPI / battery: Add sysfs representation after checking _BST 2016-08-31 00:35:16 +02:00
battery.h ACPI / battery: move some ACPI_BATTERY_* definitions to header 2014-03-19 01:57:46 +01:00
bgrt.c drivers/acpi: make bgrt driver explicitly non-modular 2016-03-09 23:46:07 +01:00
blacklist.c ACPI / osi: Collect _OSI handling into one single file 2016-05-05 00:13:53 +02:00
bus.c Merge branches 'acpi-processor', 'acpi-cppc', 'acpi-apei' and 'acpi-sleep' 2016-07-25 13:42:25 +02:00
button.c ACPI / button: remove pointer to old lid_sysfs on unbind 2016-08-03 01:27:20 +02:00
cm_sbs.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
container.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
cppc_acpi.c ACPI / CPPC: Prevent cpc_desc_ptr points to the invalid data 2016-06-25 02:53:31 +02:00
custom_method.c ACPI: Clean up inclusions of ACPI header files 2013-12-07 01:03:14 +01:00
debugfs.c ACPI: fix acpi_debugfs_init prototype 2015-08-07 02:55:18 +02:00
device_pm.c ACPI / PM: Export acpi_device_fix_up_power() 2016-05-20 15:54:01 +02:00
device_sysfs.c ACPI / device_sysfs: Clean up checkpatch errors 2016-05-04 23:47:32 +02:00
dock.c ACPI / dock: make dock explicitly non-modular 2016-07-16 03:08:08 +02:00
ec_sys.c ACPI / EC: Deny write access unless requested by module param 2016-03-09 23:26:15 +01:00
ec.c Merge branches 'acpi-ec' and 'acpi-button' 2016-08-05 16:04:49 +02:00
event.c netlink: make nlmsg_end() and genlmsg_end() void 2015-01-18 01:03:45 -05:00
evged.c ACPI / GED: make evged.c explicitly non-modular 2016-05-09 22:59:25 +02:00
fan.c ACPI / fan: Make struct dev_pm_ops const 2016-03-09 23:23:21 +01:00
glue.c Merge branch 'acpi-pci' 2015-11-07 01:30:10 +01:00
gsi.c ACPI: Rename acpi_gsi_get_irq_type to acpi_dev_get_irq_type and export symbol 2016-01-01 03:20:25 +01:00
hed.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
internal.h ACPI: add support for ACPI reconfiguration notifiers 2016-07-08 21:52:35 +02:00
ioapic.c x86/irq, ACPI: Implement ACPI driver to support IOAPIC hotplug 2015-02-05 15:09:26 +01:00
Kconfig PCI changes for the v4.8 merge window: 2016-08-02 17:12:29 -04:00
Makefile PCI changes for the v4.8 merge window: 2016-08-02 17:12:29 -04:00
numa.c ACPI / NUMA: Enable ACPI based NUMA on ARM64 2016-06-22 01:36:59 +02:00
nvs.c ACPI: Clean up acpi_os_map/unmap_memory() to eliminate __iomem. 2014-05-27 18:13:08 +02:00
osi.c ACPI / osi: Collect _OSI handling into one single file 2016-05-05 00:13:53 +02:00
osl.c treewide: replace obsolete _refok by __ref 2016-08-02 17:31:41 -04:00
pci_irq.c x86/ACPI/PCI: Recognize that Interrupt Line 255 means "not connected" 2016-03-09 01:23:35 +01:00
pci_link.c ACPI,PCI,IRQ: separate ISA penalty calculation 2016-07-02 01:38:34 +02:00
pci_mcfg.c PCI/ACPI: Add generic MCFG table handling 2016-06-10 18:27:59 -05:00
pci_root.c PCI/ACPI: Support I/O resources when parsing host bridge resources 2016-06-10 16:00:48 -05:00
pci_slot.c ACPI / PCI: make pci_slot explicitly non-modular 2016-07-16 03:05:29 +02:00
power.c Merge branch 'acpi-pm' 2015-09-01 03:38:43 +02:00
proc.c ACPI: change acpi_sleep_proc_init() to return void 2015-09-15 03:03:15 +02:00
processor_core.c ACPI / processor: Add acpi_map_madt_entry() 2016-05-30 14:27:09 +02:00
processor_driver.c Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-07-29 13:55:30 -07:00
processor_idle.c ACPI / processor_idle: Add support for Low Power Idle(LPI) states 2016-07-21 23:25:58 +02:00
processor_pdc.c ACPI / processor: Introduce invalid_logical_cpuid() 2015-05-13 23:28:14 +02:00
processor_perflib.c Merge branch 'pm-cpufreq' 2015-09-01 15:52:35 +02:00
processor_thermal.c ACPI: Remove FSF mailing addresses 2015-07-08 02:27:32 +02:00
processor_throttling.c ACPI / processor: Avoid reserving IO regions too early 2016-06-02 01:57:50 +02:00
property.c ACPI / property: fix data node parsing in acpi_get_next_subnode() 2016-03-17 03:06:38 +01:00
reboot.c Revert "ACPI: ignore FADT reset-reg-sup flag" 2012-04-20 11:19:35 -07:00
resource.c PCI: ACPI: IA64: fix IO port generic range check 2016-03-22 23:07:49 +01:00
sbs.c ACPI / SBS: fix inconsistent indenting inside if statement 2016-01-04 22:14:27 +01:00
sbshc.c Revert "ACPI / SBS: Add 5 us delay to fix SBS hangs on MacBook" 2015-11-16 23:26:45 +01:00
sbshc.h
scan.c xen: features and fixes for 4.8-rc0 2016-07-27 11:35:37 -07:00
sleep.c ACPI: Execute _PTS before system reboot 2016-06-29 23:44:02 +02:00
sleep.h ACPICA: Drop Linux-specific waking vector functions 2016-01-04 22:05:20 +01:00
sysfs.c ACPI: add support for ACPI reconfiguration notifiers 2016-07-08 21:52:35 +02:00
tables.c ACPI / tables: move arch-specific symbol to asm/acpi.h 2016-06-22 01:16:14 +02:00
thermal.c ACPI / thermal: Remove create_workqueue() 2016-06-22 02:12:56 +02:00
utils.c nfit: make DIMM DSMs optional 2016-07-19 12:32:39 -07:00
video_detect.c ACPI / video: Thinkpad X201 Tablet needs video_detect_force_video 2016-06-22 01:59:03 +02:00
wakeup.c ACPI: Clean up inclusions of ACPI header files 2013-12-07 01:03:14 +01:00