From patchwork Mon Jun 22 03:31:15 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Rui" X-Patchwork-Id: 31696 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n5M3UbIx016127 for ; Mon, 22 Jun 2009 03:30:38 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752730AbZFVDae (ORCPT ); Sun, 21 Jun 2009 23:30:34 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753098AbZFVDae (ORCPT ); Sun, 21 Jun 2009 23:30:34 -0400 Received: from mga11.intel.com ([192.55.52.93]:56781 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752281AbZFVDad (ORCPT ); Sun, 21 Jun 2009 23:30:33 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 21 Jun 2009 20:23:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.42,265,1243839600"; d="scan'208";a="701311612" Received: from rzhang-dt.sh.intel.com (HELO localhost.localdomain) ([10.239.36.94]) by fmsmga001.fm.intel.com with ESMTP; 21 Jun 2009 20:33:58 -0700 From: Zhang Rui To: lenb@kernel.org Cc: linux-acpi@vger.kernel.org, Zhang Rui Subject: [PATCH 2/5] fix a deadlock in hotplug case Date: Mon, 22 Jun 2009 11:31:15 +0800 Message-Id: <1245641478-31805-2-git-send-email-rui.zhang@intel.com> X-Mailer: git-send-email 1.5.4.4 In-Reply-To: <1245641478-31805-1-git-send-email-rui.zhang@intel.com> References: <1245641478-31805-1-git-send-email-rui.zhang@intel.com> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org we used to run the hotplug code in keventd_wq. But when hot removing the ACPI battery device, power_supply_unregister invokes flush_scheduled_work. This causes a deadlock. Introduce a new workqueue for hotplug in this patch. http://bugzilla.kernel.org/show_bug.cgi?id=13533 Tested-by: Paul Martin Tested-by: Vojtech Gondzala Signed-off-by: Zhang Rui --- drivers/acpi/osl.c | 23 ++++++++++++++--------- 1 files changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index d916bea..80488db 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -79,6 +79,11 @@ static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; static struct workqueue_struct *kacpi_notify_wq; +/* + * run the hotplug code in a seperate workqueue + * to avoid the deadlock issue + */ +static struct workqueue_struct *kacpi_hotplug_wq; struct acpi_res_list { resource_size_t start; @@ -192,8 +197,10 @@ acpi_status acpi_os_initialize1(void) { kacpid_wq = create_singlethread_workqueue("kacpid"); kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); + kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); BUG_ON(!kacpid_wq); BUG_ON(!kacpi_notify_wq); + BUG_ON(!kacpi_hotplug_wq); return AE_OK; } @@ -206,6 +213,7 @@ acpi_status acpi_os_terminate(void) destroy_workqueue(kacpid_wq); destroy_workqueue(kacpi_notify_wq); + destroy_workqueue(kacpi_hotplug_wq); return AE_OK; } @@ -716,6 +724,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, acpi_status status = AE_OK; struct acpi_os_dpc *dpc; struct workqueue_struct *queue; + work_func_t func; int ret; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", @@ -740,15 +749,11 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, dpc->function = function; dpc->context = context; - if (!hp) { - INIT_WORK(&dpc->work, acpi_os_execute_deferred); - queue = (type == OSL_NOTIFY_HANDLER) ? - kacpi_notify_wq : kacpid_wq; - ret = queue_work(queue, &dpc->work); - } else { - INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); - ret = schedule_work(&dpc->work); - } + queue = hp ? kacpi_hotplug_wq : + (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); + func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred; + INIT_WORK(&dpc->work, func); + ret = queue_work(queue, &dpc->work); if (!ret) { printk(KERN_ERR PREFIX