From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758744AbaD3Kgf (ORCPT ); Wed, 30 Apr 2014 06:36:35 -0400 Received: from mail-lb0-f182.google.com ([209.85.217.182]:53248 "EHLO mail-lb0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758727AbaD3Kgb (ORCPT ); Wed, 30 Apr 2014 06:36:31 -0400 From: Ricardo Ribalda Delgado To: linux-spi@vger.kernel.org, broonie@kernel.org, linux-kernel@vger.kernel.org Cc: Ricardo Ribalda Delgado Subject: [PATCH] spi: Fix hung task timeout when initialization fails Date: Wed, 30 Apr 2014 12:36:11 +0200 Message-Id: <1398854171-5187-1-git-send-email-ricardo.ribalda@gmail.com> X-Mailer: git-send-email 1.9.2 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Since "786235eeba0e1e85e5cbbb9f97d1087ad03dfa21 kthread: make kthread_create() killable" kthread_run can be killed by the user, ie, by killing modprobe. When this happens spi_destroy_queue() fails to cleanout the resources ending up in a hung process that outputs a error message and avoids the computer to be halted. This bug is particulary critical on machines that relay on the spi subsystem to hold a file system (MTD over SPI). [ 95.900328] spi_master spi32765: failed to create message pump task [ 95.900358] spi_master spi32765: problem initializing queue [ 95.912333] qtec_pcie b0030000.pcie_bridge: Axi-pcie bridge supervisor [ 240.463698] INFO: task udevd:129 blocked for more than 120 seconds. [ 240.463724] Not tainted 3.13.0-qtec-standard+ #191 [ 240.463733] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 240.463743] udevd D ffff880087815ac0 0 129 118 0x00000006 [ 240.463762] ffff880086593590 0000000000000002 ffff880087815ac0 ffff880086593fd8 [ 240.463778] 0000000000012c00 0000000000012c00 ffff880087815ac0 ffff880086593520 [ 240.463792] ffffffff813debe7 ffffffff810be6df ffffffff81da539c 0000000000000000 [ 240.463807] Call Trace: [ 240.463836] [] ? vt_console_print+0x57/0x3e0 [ 240.463852] [] ? print_prefix+0x6f/0xb0 [ 240.463867] [] ? wake_up_klogd+0x3c/0x50 [ 240.463880] [] ? console_unlock+0x20b/0x3f0 [ 240.463897] [] schedule+0x29/0x70 [ 240.463910] [] schedule_timeout+0x189/0x240 [ 240.463925] [] ? dev_vprintk_emit+0x50/0x60 [ 240.463939] [] wait_for_common+0xe7/0x190 [ 240.463954] [] ? wake_up_process+0x40/0x40 [ 240.463968] [] wait_for_completion+0x1d/0x20 [ 240.463981] [] flush_kthread_worker+0x6c/0x80 [ 240.463995] [] ? wait_for_completion_killable+0x1d/0x40 [ 240.464007] [] ? kthread_create_on_node+0xd2/0x190 [ 240.464020] [] ? kthread_freezable_should_stop+0x80/0x80 [ 240.464036] [] spi_destroy_queue+0x27/0x60 [ 240.464050] [] spi_register_master+0x5d6/0x900 [ 240.464072] [] spi_bitbang_start+0x83/0x110 [spi_bitbang] [ 240.464089] [] xilinx_spi_probe+0x230/0x3aa [spi_xilinx] [ 240.464104] [] platform_drv_probe+0x45/0xb0 [ 240.464120] [] ? driver_sysfs_add+0x82/0xb0 [ 240.464134] [] driver_probe_device+0x125/0x3b0 [ 240.464149] [] ? driver_probe_device+0x3b0/0x3b0 [ 240.464163] [] __device_attach+0x3b/0x40 [ 240.464177] [] bus_for_each_drv+0x63/0xa0 [ 240.464191] [] device_attach+0x88/0xa0 [ 240.464205] [] bus_probe_device+0x98/0xc0 [ 240.464218] [] device_add+0x495/0x600 [ 240.464233] [] of_device_add+0x2f/0x40 [ 240.464246] [] of_platform_device_create_pdata+0x6b/0xb0 [ 240.464259] [] of_platform_bus_create+0xf3/0x200 [ 240.464272] [] ? __of_match_node+0x48/0xe0 [ 240.464286] [] of_platform_bus_create+0x14e/0x200 [ 240.464298] [] ? __of_find_property+0x3c/0x80 [ 240.464312] [] of_platform_populate+0x47/0x90 [ 240.464334] [] qt5023_of_populate+0x562/0x980 [qt5023] [ 240.464357] [] qt5023_of_probe+0x1d3/0x300 [qt5023] [ 240.464472] [] qt5023_pci_probe+0xd3/0x1c0 [qt5023] [ 240.464491] [] pci_device_probe+0x84/0xe0 [ 240.464507] [] driver_probe_device+0x125/0x3b0 [ 240.464522] [] __driver_attach+0x93/0xa0 [ 240.464536] [] ? __device_attach+0x40/0x40 [ 240.464550] [] bus_for_each_dev+0x63/0xa0 [ 240.464585] [] driver_attach+0x1e/0x20 [ 240.464640] [] bus_add_driver+0x180/0x250 [ 240.464687] [] ? 0xffffffffa000ffff [ 240.464738] [] driver_register+0x64/0xf0 [ 240.464789] [] ? 0xffffffffa000ffff [ 240.464845] [] __pci_register_driver+0x4b/0x50 [ 240.464899] [] qt5023_init+0x31/0x33 [qt5023] [ 240.464943] [] do_one_initcall+0xd2/0x180 [ 240.464960] [] ? __blocking_notifier_call_chain+0x58/0x70 [ 240.464976] [] load_module+0x1ad6/0x23a0 [ 240.464992] [] ? store_uevent+0x40/0x40 [ 240.465010] [] ? copy_module_from_fd.isra.50+0x12a/0x190 [ 240.465024] [] SyS_finit_module+0x86/0xb0 [ 240.465041] [] tracesys+0xd0/0xd5 [ 360.540806] INFO: task udevd:129 blocked for more than 120 seconds. [ 360.540832] Not tainted 3.13.0-qtec-standard+ #191 [ 360.540841] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 360.540851] udevd D ffff880087815ac0 0 129 118 0x00000006 [ 360.540871] ffff880086593590 0000000000000002 ffff880087815ac0 ffff880086593fd8 [ 360.540886] 0000000000012c00 0000000000012c00 ffff880087815ac0 ffff880086593520 [ 360.540900] ffffffff813debe7 ffffffff810be6df ffffffff81da539c 0000000000000000 [ 360.540915] Call Trace: [ 360.540943] [] ? vt_console_print+0x57/0x3e0 [ 360.540959] [] ? print_prefix+0x6f/0xb0 [ 360.540974] [] ? wake_up_klogd+0x3c/0x50 [ 360.540988] [] ? console_unlock+0x20b/0x3f0 [ 360.541004] [] schedule+0x29/0x70 [ 360.541017] [] schedule_timeout+0x189/0x240 [ 360.541032] [] ? dev_vprintk_emit+0x50/0x60 [ 360.541046] [] wait_for_common+0xe7/0x190 [ 360.541061] [] ? wake_up_process+0x40/0x40 [ 360.541075] [] wait_for_completion+0x1d/0x20 [ 360.541089] [] flush_kthread_worker+0x6c/0x80 [ 360.541102] [] ? wait_for_completion_killable+0x1d/0x40 [ 360.541115] [] ? kthread_create_on_node+0xd2/0x190 [ 360.541127] [] ? kthread_freezable_should_stop+0x80/0x80 [ 360.541144] [] spi_destroy_queue+0x27/0x60 [ 360.541157] [] spi_register_master+0x5d6/0x900 [ 360.541179] [] spi_bitbang_start+0x83/0x110 [spi_bitbang] [ 360.541196] [] xilinx_spi_probe+0x230/0x3aa [spi_xilinx] [ 360.541211] [] platform_drv_probe+0x45/0xb0 [ 360.541226] [] ? driver_sysfs_add+0x82/0xb0 [ 360.541240] [] driver_probe_device+0x125/0x3b0 [ 360.541255] [] ? driver_probe_device+0x3b0/0x3b0 [ 360.541269] [] __device_attach+0x3b/0x40 [ 360.541283] [] bus_for_each_drv+0x63/0xa0 [ 360.541297] [] device_attach+0x88/0xa0 [ 360.541311] [] bus_probe_device+0x98/0xc0 [ 360.541324] [] device_add+0x495/0x600 [ 360.541339] [] of_device_add+0x2f/0x40 [ 360.541352] [] of_platform_device_create_pdata+0x6b/0xb0 [ 360.541366] [] of_platform_bus_create+0xf3/0x200 [ 360.541378] [] ? __of_match_node+0x48/0xe0 [ 360.541392] [] of_platform_bus_create+0x14e/0x200 [ 360.541404] [] ? __of_find_property+0x3c/0x80 [ 360.541418] [] of_platform_populate+0x47/0x90 [ 360.541441] [] qt5023_of_populate+0x562/0x980 [qt5023] [ 360.541463] [] qt5023_of_probe+0x1d3/0x300 [qt5023] [ 360.541484] [] qt5023_pci_probe+0xd3/0x1c0 [qt5023] [ 360.541502] [] pci_device_probe+0x84/0xe0 [ 360.541517] [] driver_probe_device+0x125/0x3b0 [ 360.541620] [] __driver_attach+0x93/0xa0 [ 360.541636] [] ? __device_attach+0x40/0x40 [ 360.541650] [] bus_for_each_dev+0x63/0xa0 [ 360.541665] [] driver_attach+0x1e/0x20 [ 360.541680] [] bus_add_driver+0x180/0x250 [ 360.541748] [] ? 0xffffffffa000ffff [ 360.541793] [] driver_register+0x64/0xf0 [ 360.541845] [] ? 0xffffffffa000ffff [ 360.541895] [] __pci_register_driver+0x4b/0x50 [ 360.541954] [] qt5023_init+0x31/0x33 [qt5023] [ 360.542007] [] do_one_initcall+0xd2/0x180 [ 360.542062] [] ? __blocking_notifier_call_chain+0x58/0x70 [ 360.542085] [] load_module+0x1ad6/0x23a0 [ 360.542101] [] ? store_uevent+0x40/0x40 [ 360.542119] [] ? copy_module_from_fd.isra.50+0x12a/0x190 [ 360.542133] [] SyS_finit_module+0x86/0xb0 [ 360.542150] [] tracesys+0xd0/0xd5 Signed-off-by: Ricardo Ribalda Delgado --- drivers/spi/spi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 4eb9bf0..8331556 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1114,8 +1114,10 @@ static int spi_destroy_queue(struct spi_master *master) return ret; } - flush_kthread_worker(&master->kworker); - kthread_stop(master->kworker_task); + if (!IS_ERR(master->kworker_task)) { + flush_kthread_worker(&master->kworker); + kthread_stop(master->kworker_task); + } return 0; } -- 1.9.2