Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp5585049img; Wed, 27 Mar 2019 11:09:58 -0700 (PDT) X-Google-Smtp-Source: APXvYqyc46xW9R9Ahc6m5SBEju5B8gQwEsMEv3mpPLykFyivJNmxniAbx+CU5r7LFNbrA/TY6FKg X-Received: by 2002:aa7:8092:: with SMTP id v18mr21146831pff.35.1553710198800; Wed, 27 Mar 2019 11:09:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553710198; cv=none; d=google.com; s=arc-20160816; b=Y/jyaQ5UAOfVvCgvJ53GvOg8PPz1CFiqfbPnF4B2gcd030SeDaQY6f/F793I2aUlGw rExYlE43tX1NXQS3WB2pnv4AhXv65aPalX/ntxis9sofNqMwS0JgMsbXnb0tTTgutdDe MvzDYE7u2VLii0EHGJ8QDZYr/BG4u1wb/89YgnnPLzj768Gk233q+XYqay6enKn1rwG9 5ObR+20pI+MEdzQt6y41lKU/09tm7i0dXZw3mPOzQIXC1V2ZWHXgSZltv0g2UBWZsph6 KqiuCffdH/fbbDckiQDkj5rKoLoCDMYPOdiLdTBK75Z3NoOn9Wj7sDkjLeniasuU+S/0 si+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=MSZF9tn8iJx9E1l92yzjOB5w90As314xImB9p6acJMc=; b=vLK20J/RlMxOQLRsSPzrdGolCSM10eNMQzfwaqE4c9tZiKNuygmBBAGulBS0YMWBju L07RBqd0ojRtkggdfBg0/VXEMiaIlkeWycoo47YonZ2OwfamweAYtndYFoi8EXWux4FH leP9Hhv8tGFT8UKiLdsSU1GKHYdrMvqlIqw/Yz7dH67Ex8obBljX2fd3a5f0fNj4DBU3 Y0munEi5A6RaBS1+BcDIOAZPhwKET9daNLZcuaiZOQsPxnli9Xjd80pIwjmcRjZJLXI3 EaZ3QHfv0mDMIV0t3P6ff/OZFXOQ2lKMB1a3Ljq+YShD0SE8jcJmNo5den1NdMQN4+0f UjaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="fw1SJ/NR"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r3si18634401pgp.154.2019.03.27.11.09.42; Wed, 27 Mar 2019 11:09:58 -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=@kernel.org header.s=default header.b="fw1SJ/NR"; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388116AbfC0SHM (ORCPT + 99 others); Wed, 27 Mar 2019 14:07:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:48994 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388110AbfC0SHL (ORCPT ); Wed, 27 Mar 2019 14:07:11 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2E35B2075C; Wed, 27 Mar 2019 18:07:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1553710029; bh=03A983v8weT+8KlbhGVL1S+RFHDqiiuYlKjpBx5eWbw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fw1SJ/NRPE2+pmbyDjEngIkHimNrpZxUvN121i4y6Tk0ApeFsR43OX50FxuniqKSx eEYifJqm0v8vUc6ZxKuLGAgrqJdoFS9H9IGCF4jlpOdKvoU2ufVhzChBN+Gx2UPBtJ 1DB6geuH8HpQ0yF30zyzHnJxeZwAYa6wCpio88ZY= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Thomas Gleixner , Matthew Wilcox , Andrew Morton , Alexey Dobriyan , Kees Cook , linux-fsdevel@vger.kernel.org, Davidlohr Bueso , Miklos Szeredi , Daniel Colascione , Dave Chinner , Randy Dunlap , Sasha Levin Subject: [PATCH AUTOSEL 5.0 164/262] genirq: Avoid summation loops for /proc/stat Date: Wed, 27 Mar 2019 14:00:19 -0400 Message-Id: <20190327180158.10245-164-sashal@kernel.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190327180158.10245-1-sashal@kernel.org> References: <20190327180158.10245-1-sashal@kernel.org> MIME-Version: 1.0 X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thomas Gleixner [ Upstream commit 1136b0728969901a091f0471968b2b76ed14d9ad ] Waiman reported that on large systems with a large amount of interrupts the readout of /proc/stat takes a long time to sum up the interrupt statistics. In principle this is not a problem. but for unknown reasons some enterprise quality software reads /proc/stat with a high frequency. The reason for this is that interrupt statistics are accounted per cpu. So the /proc/stat logic has to sum up the interrupt stats for each interrupt. This can be largely avoided for interrupts which are not marked as 'PER_CPU' interrupts by simply adding a per interrupt summation counter which is incremented along with the per interrupt per cpu counter. The PER_CPU interrupts need to avoid that and use only per cpu accounting because they share the interrupt number and the interrupt descriptor and concurrent updates would conflict or require unwanted synchronization. Reported-by: Waiman Long Signed-off-by: Thomas Gleixner Reviewed-by: Waiman Long Reviewed-by: Marc Zyngier Reviewed-by: Davidlohr Bueso Cc: Matthew Wilcox Cc: Andrew Morton Cc: Alexey Dobriyan Cc: Kees Cook Cc: linux-fsdevel@vger.kernel.org Cc: Davidlohr Bueso Cc: Miklos Szeredi Cc: Daniel Colascione Cc: Dave Chinner Cc: Randy Dunlap Link: https://lkml.kernel.org/r/20190208135020.925487496@linutronix.de 8<------------- v2: Undo the unintentional layout change of struct irq_desc. include/linux/irqdesc.h | 1 + kernel/irq/chip.c | 12 ++++++++++-- kernel/irq/internals.h | 8 +++++++- kernel/irq/irqdesc.c | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) Signed-off-by: Sasha Levin --- include/linux/irqdesc.h | 1 + kernel/irq/chip.c | 12 ++++++++++-- kernel/irq/internals.h | 8 +++++++- kernel/irq/irqdesc.c | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index dd1e40ddac7d..875c41b23f20 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -65,6 +65,7 @@ struct irq_desc { unsigned int core_internal_state__do_not_mess_with_it; unsigned int depth; /* nested irq disables */ unsigned int wake_depth; /* nested wake enables */ + unsigned int tot_count; unsigned int irq_count; /* For detecting broken IRQs */ unsigned long last_unhandled; /* Aging timer for unhandled count */ unsigned int irqs_unhandled; diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 34e969069488..e960c4f46ee0 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -855,7 +855,11 @@ void handle_percpu_irq(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); - kstat_incr_irqs_this_cpu(desc); + /* + * PER CPU interrupts are not serialized. Do not touch + * desc->tot_count. + */ + __kstat_incr_irqs_this_cpu(desc); if (chip->irq_ack) chip->irq_ack(&desc->irq_data); @@ -884,7 +888,11 @@ void handle_percpu_devid_irq(struct irq_desc *desc) unsigned int irq = irq_desc_get_irq(desc); irqreturn_t res; - kstat_incr_irqs_this_cpu(desc); + /* + * PER CPU interrupts are not serialized. Do not touch + * desc->tot_count. + */ + __kstat_incr_irqs_this_cpu(desc); if (chip->irq_ack) chip->irq_ack(&desc->irq_data); diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h index ca6afa267070..e74e7eea76cf 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -242,12 +242,18 @@ static inline void irq_state_set_masked(struct irq_desc *desc) #undef __irqd_to_state -static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) +static inline void __kstat_incr_irqs_this_cpu(struct irq_desc *desc) { __this_cpu_inc(*desc->kstat_irqs); __this_cpu_inc(kstat.irqs_sum); } +static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc) +{ + __kstat_incr_irqs_this_cpu(desc); + desc->tot_count++; +} + static inline int irq_desc_get_node(struct irq_desc *desc) { return irq_common_data_get_node(&desc->irq_common_data); diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index ef8ad36cadcf..84fa255d0329 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -119,6 +119,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, desc->depth = 1; desc->irq_count = 0; desc->irqs_unhandled = 0; + desc->tot_count = 0; desc->name = NULL; desc->owner = owner; for_each_possible_cpu(cpu) @@ -919,11 +920,15 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) unsigned int kstat_irqs(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); - int cpu; unsigned int sum = 0; + int cpu; if (!desc || !desc->kstat_irqs) return 0; + if (!irq_settings_is_per_cpu_devid(desc) && + !irq_settings_is_per_cpu(desc)) + return desc->tot_count; + for_each_possible_cpu(cpu) sum += *per_cpu_ptr(desc->kstat_irqs, cpu); return sum; -- 2.19.1