Received: by 2002:a05:6a10:a841:0:0:0:0 with SMTP id d1csp3595283pxy; Mon, 26 Apr 2021 05:34:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzUwQOAOV2E/xuRtfApC7fmJXMz4MmDcnqvT1pTpyiRmOGWkhZnbftd7VblS8wLIlhAg3wA X-Received: by 2002:a17:906:2408:: with SMTP id z8mr1776658eja.60.1619440494128; Mon, 26 Apr 2021 05:34:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1619440494; cv=none; d=google.com; s=arc-20160816; b=qCsrvWdHg0rpXg4j+MWtbv33u9JfWrHvLpZRUUoFVMOCSAoTu9Ipnmr3IB6Y0aZTh8 a9WTVwEyhgr+EhmTAMxu/z0h2KAZMEI8exgFMzS23acDgUU/vAdsLGTJ4pSTMZ9UFRRG UojWf9P1RCabUuk28qi6AsMSJe8ETbesBr4Kw2nKKWQEp3s2WIGy71wJpRspACDV2Wok AtCkZpFw5n7SlGlHNsMoG5FvoLVBP8YQ6+gBQG4ZfSF73kI3yG14mrufuLq+ChhHI/u2 GGmq9qTvZ/ewveMqEUBS5lSLMdomSDwFHUu7jMhRlz8QLboethbevQL5Mm8ezEjas395 RHdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:dkim-signature:dkim-signature:from; bh=Tstdcx/ZfhFpFfki9DQLaQFX4+9YKggD9tcQ4CyOZi4=; b=ZsEHK4QnBntshgeaFYKLDWRHmhHyNHDDGRAKZM0/wqyN/vJyQm3y9Yz3xwMPS5UTj2 Awzi61p9cOAYMr+oE9REGyU/Xx6S3gJILzpxPk7FD0x6gsjvb0do7SxmZ1iU8GFOnH9f u29ZDrpBUrqFSBsoxHggyETZrfXwEIb9le01ApwA4FZCOffDrw/D5Yx09Y4axs19WMxl lyxuryjPO32m6RqYrzzGW7gDzj9zYo77yHc3kysTyRvSorwUEIwlRIvHy+bIUQekqRQ0 YOiWbxHQ0o7DZI16qiVOAxrt4rdnGqG0jfcr4PkkJVNuhr11DnXLkDSC+b+e1KB0loEb qKyw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="lY7l/lzf"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d16si12652740edz.507.2021.04.26.05.34.30; Mon, 26 Apr 2021 05:34:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="lY7l/lzf"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233356AbhDZMdt (ORCPT + 99 others); Mon, 26 Apr 2021 08:33:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233385AbhDZMdp (ORCPT ); Mon, 26 Apr 2021 08:33:45 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52045C061763 for ; Mon, 26 Apr 2021 05:33:03 -0700 (PDT) From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1619440381; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Tstdcx/ZfhFpFfki9DQLaQFX4+9YKggD9tcQ4CyOZi4=; b=lY7l/lzfL81Mv9zdV21JmneH55OZPQ4HddlsyGmQyowBco9t7PBEVhMi4hYC1orj3oDmMe fN7V7tjEF1a7AGqckwkL9UlsPEQN2onTRqIqUoylTRu4oFYsAgOKXWH7aZGfluQzgYXIDC RXJQ4ujxftf9TZi8AwbtcW3ofwp2ZuKGJPk+nJy3l079vYLi0SP6NqAIgrdTk3NSo8Nate N2iI2fIU6yMgdvgsQuAmYIZPaOF0/2UbWAtkPRt8dOFWKEbuFisXr7+EKcWfsdmM035xCM uKKHN7Swr8RYnyLow6jcL8a6XajNpr7T/ZZy8ad3PsiDqPfcsHdEWTj0y7KCLA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1619440381; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Tstdcx/ZfhFpFfki9DQLaQFX4+9YKggD9tcQ4CyOZi4=; b=J5hVqx9+pyRCXchYGLWtIgBCvH50phRedQ231JFjKsxeGImQqDwRbz0IVqSR4WflnrTTBH Y3+oe39tL2O9DnCw== To: Peter Zijlstra Cc: Lorenzo Colitti , Greg KH , Maciej =?utf-8?Q?=C5=BBenczykowski?= , Ingo Molnar , Anna-Maria Behnsen , lkml , mikael.beckius@windriver.com, Maciej =?utf-8?Q?=C5=BBenczykowski?= , Will Deacon Subject: Re: [PATCH] hrtimer: Avoid double reprogramming in __hrtimer_start_range_ns() In-Reply-To: References: <87r1jbv6jc.ffs@nanos.tec.linutronix.de> <87eef5qbrx.ffs@nanos.tec.linutronix.de> <87v989topu.ffs@nanos.tec.linutronix.de> Date: Mon, 26 Apr 2021 14:33:00 +0200 Message-ID: <87sg3dtedf.ffs@nanos.tec.linutronix.de> MIME-Version: 1.0 Content-Type: text/plain Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Apr 26 2021 at 11:40, Peter Zijlstra wrote: > On Mon, Apr 26, 2021 at 10:49:33AM +0200, Thomas Gleixner wrote: >> If __hrtimer_start_range_ns() is invoked with an already armed hrtimer then >> the timer has to be canceled first and then added back. If the timer is the >> first expiring timer then on removal the clockevent device is reprogrammed >> to the next expiring timer to avoid that the pending expiry fires needlessly. >> /* >> * Remove the timer and force reprogramming when high >> @@ -1048,8 +1049,16 @@ remove_hrtimer(struct hrtimer *timer, st >> debug_deactivate(timer); >> reprogram = base->cpu_base == this_cpu_ptr(&hrtimer_bases); >> >> + /* >> + * If the timer is not restarted then reprogramming is >> + * required if the timer is local. If it is local and about >> + * to be restarted, avoid programming it twice (on removal >> + * and a moment later when it's requeued). >> + */ >> if (!restart) >> state = HRTIMER_STATE_INACTIVE; >> + else >> + reprogram &= !keep_local; > > reprogram = reprogram && !keep_local; > > perhaps? Maybe >> >> __remove_hrtimer(timer, base, state, reprogram); >> return 1; >> @@ -1103,9 +1112,31 @@ static int __hrtimer_start_range_ns(stru >> struct hrtimer_clock_base *base) >> { >> struct hrtimer_clock_base *new_base; >> + bool force_local, first; >> >> - /* Remove an active timer from the queue: */ >> - remove_hrtimer(timer, base, true); >> + /* >> + * If the timer is on the local cpu base and is the first expiring >> + * timer then this might end up reprogramming the hardware twice >> + * (on removal and on enqueue). To avoid that by prevent the >> + * reprogram on removal, keep the timer local to the current CPU >> + * and enforce reprogramming after it is queued no matter whether >> + * it is the new first expiring timer again or not. >> + */ >> + force_local = base->cpu_base == this_cpu_ptr(&hrtimer_bases); >> + force_local &= base->cpu_base->next_timer == timer; > > Using bitwise ops on a bool is cute and all, but isn't that more > readable when written like: > > force_local = base->cpu_base == this_cpu_ptr(&hrtimer_bases) && > base->cpu_base->next_timer == timer; > Which results in an extra conditional branch. >> + /* >> + * Timer was forced to stay on the current CPU to avoid >> + * reprogramming on removal and enqueue. Force reprogram the >> + * hardware by evaluating the new first expiring timer. >> + */ >> + hrtimer_force_reprogram(new_base->cpu_base, 1); >> + return 0; >> } > > There is an unfortunate amount of duplication between > hrtimer_force_reprogram() and hrtimer_reprogram(). The obvious cleanups > don't work however :/ Still, does that in_hrtirq optimization make sense > to have in force_reprogram ? Yes, no, do not know. Let me have a look. Thanks, tglx