From patchwork Thu Aug 9 11:42:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 10561245 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 91B9A139A for ; Thu, 9 Aug 2018 11:42:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 807ED2AD89 for ; Thu, 9 Aug 2018 11:42:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7410B2ADB8; Thu, 9 Aug 2018 11:42:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 160322AD89 for ; Thu, 9 Aug 2018 11:42:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730132AbeHIOGq (ORCPT ); Thu, 9 Aug 2018 10:06:46 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:46462 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730090AbeHIOGq (ORCPT ); Thu, 9 Aug 2018 10:06:46 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9BFAB7A7ED; Thu, 9 Aug 2018 11:42:16 +0000 (UTC) Received: from shalem.localdomain.com (unknown [10.36.118.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id E28262026D66; Thu, 9 Aug 2018 11:42:15 +0000 (UTC) From: Hans de Goede To: Bartlomiej Zolnierkiewicz Cc: Hans de Goede , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org Subject: [PATCH v2] fbcon: Do not takeover the console from atomic context Date: Thu, 9 Aug 2018 13:42:15 +0200 Message-Id: <20180809114215.22028-1-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Thu, 09 Aug 2018 11:42:16 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Thu, 09 Aug 2018 11:42:16 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'hdegoede@redhat.com' RCPT:'' Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Taking over the console involves allocating mem with GFP_KERNEL, talking to drm drivers, etc. So this should not be done from an atomic context. But the console-output trigger deferred console takeover may happen from an atomic context, which leads to "BUG: sleeping function called from invalid context" errors. This commit fixes these errors by doing the deferred takeover from a workqueue when the notifier runs from an atomic context. Note this uses in_atomic, as checkpatch points out this should not be done from driver code. But the console subsys is not really normal driver code, specifically it plays some tricks where it disables some locking when logging an oops, or when logging a lockdep bug when lockdep debugging is turned on, so we need to make an exception here. Signed-off-by: Hans de Goede --- Changes in v2: -Add a comment fbcon.c and the commit message about why we need to use in_atomic here, no functional changes --- drivers/video/fbdev/core/fbcon.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index ef8b2d0b7071..31f518f8dde7 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3592,7 +3592,20 @@ static int fbcon_init_device(void) } #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER +static void fbcon_register_existing_fbs(struct work_struct *work) +{ + int i; + + console_lock(); + + for_each_registered_fb(i) + fbcon_fb_registered(registered_fb[i]); + + console_unlock(); +} + static struct notifier_block fbcon_output_nb; +static DECLARE_WORK(fbcon_deferred_takeover_work, fbcon_register_existing_fbs); static int fbcon_output_notifier(struct notifier_block *nb, unsigned long action, void *data) @@ -3607,8 +3620,20 @@ static int fbcon_output_notifier(struct notifier_block *nb, deferred_takeover = false; logo_shown = FBCON_LOGO_DONTSHOW; - for_each_registered_fb(i) - fbcon_fb_registered(registered_fb[i]); + /* + * Normally all console output happens in a sleeping context, but + * during oopses the kernel goes into a special mode where the + * console code may not sleep. We check for this using in_atomic + * as the note about in_atomic in preempt.h mentions, in_atomic + * does not detect a spinlock being held when non-preemptible, so + * we also check for irqs_disabled which covers this case. + */ + if (in_atomic() || irqs_disabled()) { + schedule_work(&fbcon_deferred_takeover_work); + } else { + for_each_registered_fb(i) + fbcon_fb_registered(registered_fb[i]); + } return NOTIFY_OK; }