• Lv Zheng's avatar
    ACPICA: Tables: Fix hidden logic related to acpi_tb_install_standard_table() · 7a37052a
    Lv Zheng authored
    There is a hidden logic for acpi_tb_install_standard_table() as it can be
    invoked from the boot stage and during runtime.
    
     1. When it is invoked from the OS boot stage, the ACPICA mutex may not have
        been initialized yet and so acpi_ut_acquire_mutex()/acpi_ut_release_mutex()
        are not invoked in these code paths:
    
       acpi_initialize_tables
         acpi_tb_parse_root_table
           acpi_tb_install_standard_table (4 invocations)
       acpi_install_table
           acpi_tb_install_standard_table
    
     2. When it is invoked during the runtime, ACPICA mutex is used as
        appropriate:
    
       acpi_ex_load_op
         acpi_tb_install_and_load_table
           acpi_tb_install_standard_table
       acpi_load_table
         acpi_tb_install_and_load_table
           acpi_tb_install_standard_table
    
    The mutex is now used in acpi_tb_install_and_load_table(), while it actually
    should be in acpi_tb_install_standard_table().
    
    This introduces another problem in acpi_tb_install_standard_table() where
    acpi_gbl_table_handler is invoked from and the lock contexts are thus not
    consistent for the table handlers. This triggers a regression when
    acpi_get_table()/acpi_put_table() start to hold table mutex during runtime.
    
    The regression is noticed by LKP as new errors reported by ACPICA mutex
    debugging facility.
    
    [    2.043693] ACPI Error: Mutex [ACPI_MTX_Tables] already acquired by this thread [497483776] (20160930/utmutex-254)
    [    2.054084] ACPI Error: Mutex [0x2] is not acquired, cannot release (20160930/utmutex-326)
    
    And it triggers a deadlock:
    
    [  247.066214] INFO: task swapper/0:1 blocked for more than 120 seconds.
    ...
    [  247.091271] Call Trace:
    ...
    [  247.121523]  down_timeout+0x47/0x50
    [  247.125065]  acpi_os_wait_semaphore+0x47/0x62
    [  247.129475]  acpi_ut_acquire_mutex+0x43/0x81
    [  247.133798]  acpi_get_table+0x2d/0x84
    [  247.137513]  acpi_table_attr_init+0xcd/0x100
    [  247.146590]  acpi_sysfs_table_handler+0x5d/0xb8
    [  247.151174]  acpi_bus_table_handler+0x23/0x2a
    [  247.155583]  acpi_tb_install_standard_table+0xe0/0x213
    [  247.164489]  acpi_tb_install_and_load_table+0x3a/0x82
    [  247.169592]  acpi_ex_load_op+0x194/0x201
    ...
    [  247.200108]  acpi_ns_evaluate+0x1bb/0x247
    [  247.204170]  acpi_evaluate_object+0x178/0x274
    [  247.213249]  acpi_processor_set_pdc+0x154/0x17b
    ...
    The table mutex is held in acpi_tb_install_and_load_table() and is re-visited by
    acpi_get_table().
    
    Noticing that the early mutex requirement actually belongs to the OSL layer
    and has already been handled in acpi_os_wait_semaphore()/acpi_os_signal_semaphore(),
    the regression canbe fixed by removing this hidden logic from the ACPICA core
    to the OS-specific code.
    
    Fixes: 174cc718 ("ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel")
    Reported-and-tested-by: default avatarTomi Sarvela <tomi.p.sarvela@intel.com>
    Reported-by: default avatarYe Xiaolong <xiaolong.ye@intel.com>
    Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    7a37052a
tbinstal.c 14.2 KB