Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp794780yba; Thu, 9 May 2019 06:08:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqx8ML0sOjSpS1SS6E/i0m0K2t/GA8ejZ0e7v1DlIiVTTkyCy4160ByvA0m4jTHI+blTFOg+ X-Received: by 2002:a17:902:d88b:: with SMTP id b11mr5055412plz.186.1557407312143; Thu, 09 May 2019 06:08:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557407312; cv=none; d=google.com; s=arc-20160816; b=IgsKGQxaFJ85nD5CAvde5m6Bqie2mTXnSfXKkNuppY9VJJJ8jergcFGBUJq3bMkgUR QFdYzjRKkvL0BC4di5ZcTiod5vhMrGk/X8HM39gamcFMbiY9p++27cQ/hEcYJWynU7GC x69OMCIqXLdUnHhdbFFDzYdi91wwokjMZFpcl7MtmVunaUgqoe8QoU9YEjUnfQm7xcNp TiHTXkK97OCHJvYWfbwGXiip3zAn1cUmzTTDFnJiYsYBfusF8/wIO6hUuyiI2aejMSlB b1xUq/gTE2FMohLqlYcIAPU+RDzgx3Iy5aGRNRySvPVqc3kV0KHpDMsQMRX7AmDmV23B 059A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=dDHzEizTc5iYLRPdBf/FVK/yUV4INbU48OdqJ7lgHxc=; b=VSR7CxdInIaoQnz8xNSRib6tCpKSxiJV4wJlyurvFICPO1ntqChkyG8MwMSmr8Xb9k k77mtXfZ10bdU9VuM2o/YRQoMiI+/aiOGwYOlVMQ4y6jrEYt+dfWkwgsHYubV4iq6Lf8 HFh/pKnp4zpqTSOkaAB41Z3R6DvzPdovDLXZxLiZDD4Yd+fD3yrzZYpgUNZZKO/yjPOA PjYvnfL7YuQfEUpxz5e0JJ4I+7+/4tkU0SANnL60oe0AVFzS1UB+kcNOFvF2PSNRmh8q Fr1c68hXLFcIQrJtYqIhBlRr5VAfXHoq3HjWSk0nr3Y32GeKJ88mH2+RSMF8tZMqCN04 msRQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=WXWvm+RM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 10si2769491pgm.332.2019.05.09.06.08.09; Thu, 09 May 2019 06:08:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=WXWvm+RM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726653AbfEINGW (ORCPT + 99 others); Thu, 9 May 2019 09:06:22 -0400 Received: from mail-it1-f194.google.com ([209.85.166.194]:56125 "EHLO mail-it1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726448AbfEINGW (ORCPT ); Thu, 9 May 2019 09:06:22 -0400 Received: by mail-it1-f194.google.com with SMTP id q132so3375427itc.5 for ; Thu, 09 May 2019 06:06:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=dDHzEizTc5iYLRPdBf/FVK/yUV4INbU48OdqJ7lgHxc=; b=WXWvm+RMP8NWmdvwirguzLRMlo+T+wAS5vXiS2fbQKs74buNlCr+k7I546dBLsEZc/ LBmc0l/tnX6mJ96HeTxICfz3t18xxx+PAJXHxj0y54oTetc7vgB5iHzRcjiLuc4hKaeT ovGlHzI33mWXaOz4AbjxIh4hQis+oJ0alNYaw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=dDHzEizTc5iYLRPdBf/FVK/yUV4INbU48OdqJ7lgHxc=; b=ody1HuRkivb030LJutsCzLXFHFi1eGywvkteIjij9z95P+jTTfO850d4RXBNz52f1M I7sV4EIYyxg5HCG8uniAP55FNwD3RnOwdpl08dwmpTHpBh2PKjoyMWhSKctx1BmR/TPU nxiOnhJu983yYybJOirHH4+XsbYjUg6OTSGMrSfF5GyQNFNvyd7cVuhuKrO/o3/jDkOY yf8XMZ3aJBol/fXuPMnJtnKECDDolLPWZnidnavVGmC2IrsKDh6uUhMfb5hBQCAxH6jL g1wMMBKCGoVJIuCp5pm/zQTT/JjsAXiIZ898YsJCQ1xPJ2b/d5MfBT8m2FgmzSejwuuL tTeg== X-Gm-Message-State: APjAAAX5ZjzWXSK8u04SuVR9Jc+Dxgl3y/x/8z4aqZCFUhhFdQCfP8Q3 Tvb0BVTYSQNdseCX98EAgw4q9N/uxPs51hFzyB7W9w== X-Received: by 2002:a05:660c:6c8:: with SMTP id z8mr1720655itk.51.1557407181048; Thu, 09 May 2019 06:06:21 -0700 (PDT) MIME-Version: 1.0 References: <20190509120903.28939-1-daniel.vetter@ffwll.ch> <20190509123104.GQ2589@hirez.programming.kicks-ass.net> In-Reply-To: <20190509123104.GQ2589@hirez.programming.kicks-ass.net> From: Daniel Vetter Date: Thu, 9 May 2019 15:06:09 +0200 Message-ID: Subject: Re: [PATCH] RFC: console: hack up console_lock more v3 To: Peter Zijlstra Cc: Intel Graphics Development , DRI Development , Daniel Vetter , Ingo Molnar , Will Deacon , Petr Mladek , Sergey Senozhatsky , Steven Rostedt , John Ogness , Chris Wilson , Linux Kernel Mailing List Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, May 9, 2019 at 2:31 PM Peter Zijlstra wrote: > On Thu, May 09, 2019 at 02:09:03PM +0200, Daniel Vetter wrote: > > Fix this by creating a prinkt_safe_up() which calls wake_up_process > > outside of the spinlock. This isn't correct in full generality, but > > good enough for console_lock: > > > > - console_lock doesn't use interruptible or killable or timeout down() > > calls, hence an up() is the only thing that can wake up a process. > > Wrong :/ Any task can be woken at any random time. We must, at all > times, assume spurious wakeups will happen. Out of curiosity, where do these come from? I know about the races where you need to recheck on the waiter side to avoid getting stuck, but didn't know about this. Are these earlier (possibly spurious) wakeups that got held up and delayed for a while, then hit the task much later when it's already continued doing something else? Or even more random, and even if I never put a task on a wait list or anything else, ever, it can get woken spuriously? > > +void printk_safe_up(struct semaphore *sem) > > +{ > > + unsigned long flags; > > + struct semaphore_waiter *waiter = NULL; > > + > > + raw_spin_lock_irqsave(&sem->lock, flags); > > + if (likely(list_empty(&sem->wait_list))) { > > + sem->count++; > > + } else { > > + waiter = list_first_entry(&sem->wait_list, > > + struct semaphore_waiter, list); > > + list_del(&waiter->list); > > + waiter->up = true; > > + } > > + raw_spin_unlock_irqrestore(&sem->lock, flags); > > + > > + if (waiter) /* protected by being sole wake source */ > > + wake_up_process(waiter->task); > > +} > > +EXPORT_SYMBOL(printk_safe_up); > > Since its only used from printk, that EXPORT really isn't needed. > > Something like the below might work. Yeah that looks like the proper fix. I guess semaphores are uncritical enough that we can roll this out for everyone. Thanks for the hint. -Daniel > > --- > kernel/locking/semaphore.c | 26 +++++++++++++------------- > 1 file changed, 13 insertions(+), 13 deletions(-) > > diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c > index 561acdd39960..ac0a67e95aac 100644 > --- a/kernel/locking/semaphore.c > +++ b/kernel/locking/semaphore.c > @@ -38,7 +38,6 @@ static noinline void __down(struct semaphore *sem); > static noinline int __down_interruptible(struct semaphore *sem); > static noinline int __down_killable(struct semaphore *sem); > static noinline int __down_timeout(struct semaphore *sem, long timeout); > -static noinline void __up(struct semaphore *sem); > > /** > * down - acquire the semaphore > @@ -178,14 +177,24 @@ EXPORT_SYMBOL(down_timeout); > */ > void up(struct semaphore *sem) > { > + struct semaphore_waiter *waiter; > + DEFINE_WAKE_Q(wake_q); > unsigned long flags; > > raw_spin_lock_irqsave(&sem->lock, flags); > - if (likely(list_empty(&sem->wait_list))) > + if (likely(list_empty(&sem->wait_list))) { > sem->count++; > - else > - __up(sem); > + goto unlock; > + } > + > + waiter = list_first_entry(&sem->wait_list, struct semaphore_waiter, list); > + list_del(&waiter->list); > + waiter->up = true; > + wake_q_add(&wake_q, waiter->task); > +unlock: > raw_spin_unlock_irqrestore(&sem->lock, flags); > + > + wake_up_q(&wake_q); > } > EXPORT_SYMBOL(up); > > @@ -252,12 +261,3 @@ static noinline int __sched __down_timeout(struct semaphore *sem, long timeout) > { > return __down_common(sem, TASK_UNINTERRUPTIBLE, timeout); > } > - > -static noinline void __sched __up(struct semaphore *sem) > -{ > - struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, > - struct semaphore_waiter, list); > - list_del(&waiter->list); > - waiter->up = true; > - wake_up_process(waiter->task); > -} -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch