From patchwork Tue Aug 12 22:28:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Luis R. Rodriguez" X-Patchwork-Id: 379478 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9777E140085 for ; Wed, 13 Aug 2014 08:29:40 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932120AbaHLW2m (ORCPT ); Tue, 12 Aug 2014 18:28:42 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:56833 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754630AbaHLW2j (ORCPT ); Tue, 12 Aug 2014 18:28:39 -0400 Received: by mail-pa0-f45.google.com with SMTP id eu11so13677127pac.4 for ; Tue, 12 Aug 2014 15:28:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=9D7D+Gd9yEdlQGz8nAtJNZMGGsxxUbPpNomzkd13wy0=; b=HnPKvbn37W9XjYdKyuqjFNU8T+R28B3EsO3uVYtC3STOqa8FYVMQGkzJeAI3e80Vws 9V0/Onutl1AfUfPATw4CPZqybj5ngeuZ0p8LX+UlhTPPlHxGnuo2ypHfOixIeoDA2Khn 8ti0C4H/xVnZtcEwWmDIfuCh+YIV+LdTH/vWDNMDw6aIVANjeSfl095UDsa1o4JRVHWY ncnoEOqMCsPc4u2GN4qZ0Eak57Cs1u+k/ekwQrpw3OuPi4eCd6vm1LCPoGWwn50O74KQ nTpNI480+Lz3dgWNixmyrkOYdNRqPALrniZnRDJUbFvCO453uG1NV7vgEywKr32t9oVO Kghg== X-Received: by 10.70.33.161 with SMTP id s1mr616416pdi.10.1407882518590; Tue, 12 Aug 2014 15:28:38 -0700 (PDT) Received: from mcgrof@gmail.com (c-98-234-145-61.hsd1.ca.comcast.net. [98.234.145.61]) by mx.google.com with ESMTPSA id fn1sm16403pbc.77.2014.08.12.15.28.34 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 12 Aug 2014 15:28:37 -0700 (PDT) Received: by mcgrof@gmail.com (sSMTP sendmail emulation); Tue, 12 Aug 2014 15:28:33 -0700 From: "Luis R. Rodriguez" To: gregkh@linuxfoundation.org Cc: tiwai@suse.de, linux-kernel@vger.kernel.org, "Luis R. Rodriguez" , Tetsuo Handa , Joseph Salisbury , Kay Sievers , One Thousand Gnomes , Tim Gardner , Pierre Fersing , Andrew Morton , Oleg Nesterov , Benjamin Poirier , Nagalakshmi Nandigama , Praveen Krishnamoorthy , Sreekanth Reddy , Abhijit Mahajan , Hariprasad S , Santosh Rastapur , MPT-FusionLinux.pdl@avagotech.com, linux-scsi@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v3 1/3] init / kthread: add module_long_probe_init() and module_long_probe_exit() Date: Tue, 12 Aug 2014 15:28:25 -0700 Message-Id: <1407882507-325-2-git-send-email-mcgrof@do-not-panic.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1407882507-325-1-git-send-email-mcgrof@do-not-panic.com> References: <1407882507-325-1-git-send-email-mcgrof@do-not-panic.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: "Luis R. Rodriguez" Tetsuo bisected and found that commit 786235ee "kthread: make kthread_create() killable" modified kthread_create() to bail as soon as SIGKILL is received. This is causing some issues with some drivers and at times boot. Joseph then found that failures occur as the systemd-udevd process sends SIGKILL to modprobe if probe on a driver takes over 30 seconds. When this happens probe will fail on any driver, its why booting on some system will fail if the driver happens to be a storage related driver. Some folks have suggested fixing this by modifying kthread_create() to not leave upon SIGKILL [3], upon review Oleg rejected this change and the discussion was punted out to systemd to see if the default timeout could be increased from 30 seconds to 120. The opinion of the systemd maintainers is that the driver's behavior should be fixed [4]. Linus seems to agree [5], however more recently even networking drivers have been reported to fail on probe since just writing the firmware to a device and kicking it can take easy over 60 seconds [6]. Benjamim was able to trace the issues recently reported on cxgb4 down to the same systemd-udevd 30 second timeout [6]. This is an alternative solution which enables drivers that are known to take long to use kthread_run(), this avoids the 30 second timeout and lets us annotate drivers with long init sequences that need some love. [0] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1276705 [1] https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1297248 [2] http://lists.freedesktop.org/archives/systemd-devel/2014-March/018006.html [3] http://thread.gmane.org/gmane.linux.ubuntu.devel.kernel.general/39123 [4] http://article.gmane.org/gmane.comp.sysutils.systemd.devel/17860 [5] http://article.gmane.org/gmane.linux.kernel/1671333 [6] https://bugzilla.novell.com/show_bug.cgi?id=877622 Cc: Greg Kroah-Hartman Cc: Tetsuo Handa Cc: Joseph Salisbury Cc: Kay Sievers Cc: One Thousand Gnomes Cc: Tim Gardner Cc: Pierre Fersing Cc: Andrew Morton Cc: Oleg Nesterov Cc: Benjamin Poirier Cc: Greg Kroah-Hartman Cc: Nagalakshmi Nandigama Cc: Praveen Krishnamoorthy Cc: Sreekanth Reddy Cc: Abhijit Mahajan Cc: Hariprasad S Cc: Santosh Rastapur Cc: MPT-FusionLinux.pdl@avagotech.com Cc: linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Luis R. Rodriguez --- A few implementation notes: 1) Two wrappers are used to simply enable the same prototype as expected on modules for module_init() 2) The new helpers are stuffed under kthread.h since including kthread.h on init.h caused major issues which are not easy to resolve, in fact even including kernel.h in init.h cases some issues. We could have keep this under init.h if we ifef'd on _LINUX_KTHREAD_H as well but this seems a bit cleaner. include/linux/kthread.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 13d5520..2b5555a 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -1,6 +1,7 @@ #ifndef _LINUX_KTHREAD_H #define _LINUX_KTHREAD_H /* Simple interface for creating and stopping kernel threads without mess. */ +#include #include #include @@ -128,4 +129,38 @@ bool queue_kthread_work(struct kthread_worker *worker, void flush_kthread_work(struct kthread_work *work); void flush_kthread_worker(struct kthread_worker *worker); +#ifndef MODULE + +#define module_long_probe_init(x) __initcall(x); +#define module_long_probe_exit(x) __exitcall(x); + +#else +/* To be used by modules which can take over 30 seconds at probe */ +#define module_long_probe_init(initfn) \ + static struct task_struct *__init_thread; \ + static int _long_probe_##initfn(void *arg) \ + { \ + return initfn(); \ + } \ + static inline __init int __long_probe_##initfn(void) \ + { \ + __init_thread = kthread_run(_long_probe_##initfn,\ + NULL, \ + #initfn); \ + if (IS_ERR(__init_thread)) \ + return PTR_ERR(__init_thread); \ + return 0; \ + } \ + module_init(__long_probe_##initfn); +/* To be used by modules that require module_long_probe_init() */ +#define module_long_probe_exit(exitfn) \ + static inline void __long_probe_##exitfn(void) \ + { \ + exitfn(); \ + if (__init_thread) \ + kthread_stop(__init_thread); \ + } \ + module_exit(__long_probe_##exitfn); +#endif /* MODULE */ + #endif /* _LINUX_KTHREAD_H */