Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1029532yba; Thu, 4 Apr 2019 02:48:33 -0700 (PDT) X-Google-Smtp-Source: APXvYqzXrQggMhcbOY8yL8IDWnsDkP2nLnxw6uPI/RhuiL52CfrZuN0aZiUZoi6oonXS4CUcaoV4 X-Received: by 2002:a62:6c43:: with SMTP id h64mr4942580pfc.123.1554371313690; Thu, 04 Apr 2019 02:48:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554371313; cv=none; d=google.com; s=arc-20160816; b=esOq0DKHbY1cCn6IHYOz41XOZFdJ+cYLhnSJ7KSZlOqNi+Mw1sr6qM4x904vq9xNqJ 8oRMluv3GDztkId1OtoQDCBku8swKVgxZmn320R5YXm0DcNxLVPhimD6GKtLy8WJXFjd X2BumkS1mQn7DLv8gHbOnRmxR+9lM1W9ttW3L53V99FhARzYGGVrCRpVd12IKQiH944t gdKcauaKjVmn382e3R5ChK3kA+/FPWxBQMfx9Lrpf/w/FyARpxdlk5xeiQy3RgxqPj3X VwrZoDYIDubB1NN+3WuoH3hHx5CFSV6fu6lZ0GsX81DYLbthrlr7pahInoOZ3y88MKq1 pdjw== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=RoRiAITOx94iawcV9JTwmZTfHLe2o/YCfcm3pGMpo30=; b=dxKxETw+VVWSIUyju8+638zDOE3mw98uUdgzSGN6wZgYtK9m5nePMfTa3K8p5gvm4F 6sWXJk3yZ3npAXuL487eiGbmb37CZJ1Jgv1RA9Hoq3Z5swQYJrKfhAcSWmiEC9QzSnCp AaJOTn1ufM9XDQh9n3rbGekGKbNy1uR4YaZiri5Odtgm6jYDp1o9GN3otIuidO9t7Fcc EJIrq5MJylrhuhNklEDfq0IxeaYxyXmOD++FFjket+qXjVvUTzLzoatv8w1e2m6WUZ4Y bjUFjac/3zqFK55q8+jHiO2kIfa0yPqaUuNdJMIZ7v3CLMe7AMeYAbI/bMmAgK6+ZsUc HE/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=O74EdeMg; 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 v10si16754477pgj.576.2019.04.04.02.48.18; Thu, 04 Apr 2019 02:48:33 -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=O74EdeMg; 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 S1730884AbfDDJrm (ORCPT + 99 others); Thu, 4 Apr 2019 05:47:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:33222 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730720AbfDDI5j (ORCPT ); Thu, 4 Apr 2019 04:57:39 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C350020652; Thu, 4 Apr 2019 08:57:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554368258; bh=LqcGMgBo5Gg2+sw0oDlru1+dVxUXUdl8jPHJmcAEu9I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O74EdeMgBXtr2hcyHyaCoDOPX0jRzn9mIsApP9YAK9YdFedRnKIY/kzrB91oKAeN0 /VIiDLtUksx85ohPtkRTssA+OLXJIh8xGK+WV4Pb8BfbbTnVdcM4hTfrE1708gUdzU AWPB82swZz+34pXg8cCaeEYaIM/n/LlW96ljODgM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Waiman Long , Thomas Gleixner , Marc Zyngier , Davidlohr Bueso , 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 4.14 079/121] genirq: Avoid summation loops for /proc/stat Date: Thu, 4 Apr 2019 10:47:47 +0200 Message-Id: <20190404084549.542093618@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190404084545.245659903@linuxfoundation.org> References: <20190404084545.245659903@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ [ 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 b6084898d330..234f0d1f8dca 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 5a2ef92c2782..0fa7ef74303b 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -834,7 +834,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); @@ -863,7 +867,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 44ed5f8c8759..4ef7f3b820ce 100644 --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -240,12 +240,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 e97bbae947f0..c2bfb11a9d05 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) @@ -895,11 +896,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