From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755590AbcGHOBw (ORCPT ); Fri, 8 Jul 2016 10:01:52 -0400 Received: from mail-qt0-f193.google.com ([209.85.216.193]:36350 "EHLO mail-qt0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754746AbcGHOBo (ORCPT ); Fri, 8 Jul 2016 10:01:44 -0400 Date: Fri, 8 Jul 2016 16:01:41 +0200 From: Frederic Weisbecker To: Rik van Riel Cc: linux-kernel@vger.kernel.org, peterz@infradead.org, mingo@kernel.org, pbonzini@redhat.com, fweisbec@redhat.com, wanpeng.li@hotmail.com, efault@gmx.de, tglx@linutronix.de, rkrcmar@redhat.com Subject: Re: [PATCH 4/4] irqtime: drop local_irq_save/restore from irqtime_account_irq Message-ID: <20160708140139.GF30200@lerouge> References: <1467315350-3152-1-git-send-email-riel@redhat.com> <1467315350-3152-5-git-send-email-riel@redhat.com> <20160708123010.GD30200@lerouge> <1467983987.13253.25.camel@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1467983987.13253.25.camel@redhat.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jul 08, 2016 at 09:19:47AM -0400, Rik van Riel wrote: > On Fri, 2016-07-08 at 14:30 +0200, Frederic Weisbecker wrote: > > > + if (irqtype == HARDIRQ_OFFSET) { > > > + bool leaving_hardirq = hardirq_count(); > > > + delta = sched_clock_cpu(cpu) - > > > __this_cpu_read(hardirq_start_time); > > > + __this_cpu_add(hardirq_start_time, delta); > > > + if (leaving_hardirq) { > > > + hardirq_time_write_begin(); > > > + __this_cpu_add(cpu_hardirq_time, delta); > > > + hardirq_time_write_end(); > > > + } > > > > This doesn't seem to work with nesting hardirqs. > > > > Thanks. > > Where does it break? > > enter hardirq A -> hardirq_start_time = now > > enter hardirq B -> hardirq_start_time = now, >                    account already elapsed time > > leave hardirq B -> account elapsed time, set >                    hardirq_start_time = now > > leave hardirq A -> account elapsed time > > What am I missing, except a softirq-style do-while > loop to account for hardirq A being interrupted by > hardirq B while updating the statistics? How about: enter hardirq A -> delta = sched_clock_cpu(cpu) - __this_cpu_read(hardirq_start_time); enter hardirq B -> delta = sched_clock_cpu(cpu) - __this_cpu_read(hardirq_start_time); __this_cpu_add(hardirq_start_time, delta); ... exit hardirq B __this_cpu_add(hardirq_start_time, delta); Also seqcount writers can't nest.