From patchwork Fri Apr 9 22:17:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chase Douglas X-Patchwork-Id: 49871 X-Patchwork-Delegate: apw@canonical.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 0C010B7CF8 for ; Sat, 10 Apr 2010 08:18:10 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1O0MWU-0008BI-W9; Fri, 09 Apr 2010 23:17:59 +0100 Received: from adelie.canonical.com ([91.189.90.139]) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1O0MWT-0008B8-Bs for kernel-team@lists.ubuntu.com; Fri, 09 Apr 2010 23:17:57 +0100 Received: from hutte.canonical.com ([91.189.90.181]) by adelie.canonical.com with esmtp (Exim 4.69 #1 (Debian)) id 1O0MWT-0000Kk-Ac for ; Fri, 09 Apr 2010 23:17:57 +0100 Received: from cpe-75-180-27-10.columbus.res.rr.com ([75.180.27.10] helo=canonical.com) by hutte.canonical.com with esmtpsa (TLS-1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.69) (envelope-from ) id 1O0MWT-0006fc-0i for kernel-team@lists.ubuntu.com; Fri, 09 Apr 2010 23:17:57 +0100 From: Chase Douglas To: kernel-team@lists.ubuntu.com Subject: [PATCH] dell-laptop: defer dell_rfkill_update to worker thread Date: Fri, 9 Apr 2010 18:17:55 -0400 Message-Id: <1270851475-22321-1-git-send-email-chase.douglas@canonical.com> X-Mailer: git-send-email 1.7.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Chase Douglas dell_rfkill_update fires an SMI, which must occur on cpu 0. Thus, if called on a different cpu, the task will block. Since it's called in hard irq context, we must defer this to the worker thread. It is potentially possible that two rfkill key events could be processed before the work completes on the first. The second event is dropped with a KERN_NOTICE message. BugLink: http://bugs.launchpad.net/bugs/555261 Signed-off-by: Chase Douglas Acked-by: Andy Whitcroft --- drivers/platform/x86/dell-laptop.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 8bf7ac7..15d96a0 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -288,8 +288,10 @@ static const struct rfkill_ops dell_rfkill_ops = { /* * Called for each KEY_WLAN key press event. Note that a physical * rf-kill switch change also causes the BIOS to emit a KEY_WLAN. + * + * dell_rfkill_set may block, so schedule it on a worker thread. */ -static void dell_rfkill_update(void) +static void dell_rfkill_update(struct work_struct *work) { hw_switch_status ^= BIT(HW_SWITCH_MASK); if (wifi_rfkill && (hw_switch_status & BIT(WLAN_SWITCH_MASK))) { @@ -307,6 +309,7 @@ static void dell_rfkill_update(void) dell_rfkill_set((void*)3, rfkill_blocked(wwan_rfkill)); } } +DECLARE_WORK(dell_rfkill_update_work, &dell_rfkill_update); static int dell_setup_rfkill(void) { @@ -431,7 +434,9 @@ static bool dell_input_filter(struct input_handle *handle, unsigned int type, unsigned int code, int value) { if (type == EV_KEY && code == KEY_WLAN && value == 1) { - dell_rfkill_update(); + if (!schedule_work(&dell_rfkill_update_work)) + printk(KERN_NOTICE "rfkill switch handling already " + "scheduled, dropping this event\n"); return 1; }