Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp239123ybi; Wed, 29 May 2019 20:25:16 -0700 (PDT) X-Google-Smtp-Source: APXvYqwx4qBJDxr0Vsxn+MMbXr8U3IAcFXXMpUN1fjzus7X9uAa63r3ZsElM41upeuT2OKblqTp6 X-Received: by 2002:a65:56cc:: with SMTP id w12mr1626214pgs.415.1559186715926; Wed, 29 May 2019 20:25:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559186715; cv=none; d=google.com; s=arc-20160816; b=q9qlROfKmBDkbL7zzRROYeMPuO7Kf2KRXoHzVvxCPFg/vnSokDRjQ92EGApqOHOWm3 cVYpjyUQOFf8yMZAA1tXt3N6Ezm6CER6c+GQloto8ugYD5GTvwZapK8t8B5DcEhFgFgJ p5fk9JZwNDmKvDlRR1RrG2w2Bej0IT2cWcrh3PNVh4MFjIyJ7Zz9h0k7PJ6EMPkovn1W 30Sthq0PBe+igjg1ZXwHexbotxoo4U6y7kuI8sXUHPtr8l8mM33AXKm34O72D/eBpU09 lcAodt58b+RAIiwPml7zLNZ4TGHgziKdB0PD6rgY3kyKDTr7h3uqK4+p7Soxp22x3JV6 HBRg== 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=qsP0i9eoh7at6IQBDfJF4liyXQIQ7i9jB2z8V4Mwk8w=; b=ELzs2QuEhaUrnmrd8pesxZweoa/I4BWF921DAVJm++zdyIGjMahXkVp1cqRMdAU7L4 RSqn2e/B/i9LVA8OPZA71wQfXwZuQQAkvqv7ajE7RCOFwU14YXbNnGDgTRt6Qyj/mUz6 GaaD9ebNPOps5FTshmdOc6J6VPKPRuYCWOQ1Z5Qm0mFyHOEzYWw5+IEn0CvP2x3wNsoM zRXO9rA9Zs1OnzfvJ4eEcICrG367aW81TKPbcKfeTLu5xqpw4Ik6mOSgcfbSOz8hzMpW eTC4Nw75ythHqEWA+03Coyca/SruXLENrA9pZvqIcfPGWdYjq7IZ2j19CtMWZ5uah5ge 3XYA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=lJR8+yoS; 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 m4si1627978pjk.66.2019.05.29.20.24.59; Wed, 29 May 2019 20:25:15 -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=lJR8+yoS; 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 S1733010AbfE3DXG (ORCPT + 99 others); Wed, 29 May 2019 23:23:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:45602 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731002AbfE3DRP (ORCPT ); Wed, 29 May 2019 23:17:15 -0400 Received: from localhost (ip67-88-213-2.z213-88-67.customer.algx.net [67.88.213.2]) (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 038F224688; Thu, 30 May 2019 03:17:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186234; bh=lZqlFI5rRdNdBUUDFTiQ61znwPK0+JBPzKezX7TVJFQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lJR8+yoS3Xss3HyUyY7RiAYGZPXihnef/kQ4sY9UmqqHjTxB4dwt3rgtkhvHVLAkT bmNbZHfYlEwCQ83ujapPD8zuFevrX+lvqXqeRuzDPdTvEVg0Jkdeb0PnPJBEE8IlEc ZiO3YCso/eZ97OoBtW3+yz6J7CV9PZLXbapYi7KY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Steven Rostedt , Sebastian Andrzej Siewior , Nicholas Piggin , "Peter Zijlstra (Intel)" , Frederic Weisbecker , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Linus Torvalds , Paul Mackerras , Suraj Jitindar Singh , Thomas Gleixner , Ingo Molnar , Sasha Levin Subject: [PATCH 4.19 141/276] irq_work: Do not raise an IPI when queueing work on the local CPU Date: Wed, 29 May 2019 20:04:59 -0700 Message-Id: <20190530030534.501329077@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190530030523.133519668@linuxfoundation.org> References: <20190530030523.133519668@linuxfoundation.org> User-Agent: quilt/0.66 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 [ Upstream commit 471ba0e686cb13752bc1ff3216c54b69a2d250ea ] The QEMU PowerPC/PSeries machine model was not expecting a self-IPI, and it may be a bit surprising thing to do, so have irq_work_queue_on do local queueing when target is the current CPU. Suggested-by: Steven Rostedt Reported-by: Sebastian Andrzej Siewior Tested-by: Sebastian Andrzej Siewior Signed-off-by: Nicholas Piggin Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Cc: Linus Torvalds Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Suraj Jitindar Singh Cc: Thomas Gleixner Link: https://lkml.kernel.org/r/20190409093403.20994-1-npiggin@gmail.com [ Simplified the preprocessor comments. Fixed unbalanced curly brackets pointed out by Thomas. ] Signed-off-by: Ingo Molnar Signed-off-by: Sasha Levin --- kernel/irq_work.c | 75 ++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/kernel/irq_work.c b/kernel/irq_work.c index 6b7cdf17ccf89..73288914ed5e7 100644 --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -56,61 +56,70 @@ void __weak arch_irq_work_raise(void) */ } -/* - * Enqueue the irq_work @work on @cpu unless it's already pending - * somewhere. - * - * Can be re-enqueued while the callback is still in progress. - */ -bool irq_work_queue_on(struct irq_work *work, int cpu) +/* Enqueue on current CPU, work must already be claimed and preempt disabled */ +static void __irq_work_queue_local(struct irq_work *work) { - /* All work should have been flushed before going offline */ - WARN_ON_ONCE(cpu_is_offline(cpu)); - -#ifdef CONFIG_SMP - - /* Arch remote IPI send/receive backend aren't NMI safe */ - WARN_ON_ONCE(in_nmi()); + /* If the work is "lazy", handle it from next tick if any */ + if (work->flags & IRQ_WORK_LAZY) { + if (llist_add(&work->llnode, this_cpu_ptr(&lazy_list)) && + tick_nohz_tick_stopped()) + arch_irq_work_raise(); + } else { + if (llist_add(&work->llnode, this_cpu_ptr(&raised_list))) + arch_irq_work_raise(); + } +} +/* Enqueue the irq work @work on the current CPU */ +bool irq_work_queue(struct irq_work *work) +{ /* Only queue if not already pending */ if (!irq_work_claim(work)) return false; - if (llist_add(&work->llnode, &per_cpu(raised_list, cpu))) - arch_send_call_function_single_ipi(cpu); - -#else /* #ifdef CONFIG_SMP */ - irq_work_queue(work); -#endif /* #else #ifdef CONFIG_SMP */ + /* Queue the entry and raise the IPI if needed. */ + preempt_disable(); + __irq_work_queue_local(work); + preempt_enable(); return true; } +EXPORT_SYMBOL_GPL(irq_work_queue); -/* Enqueue the irq work @work on the current CPU */ -bool irq_work_queue(struct irq_work *work) +/* + * Enqueue the irq_work @work on @cpu unless it's already pending + * somewhere. + * + * Can be re-enqueued while the callback is still in progress. + */ +bool irq_work_queue_on(struct irq_work *work, int cpu) { +#ifndef CONFIG_SMP + return irq_work_queue(work); + +#else /* CONFIG_SMP: */ + /* All work should have been flushed before going offline */ + WARN_ON_ONCE(cpu_is_offline(cpu)); + /* Only queue if not already pending */ if (!irq_work_claim(work)) return false; - /* Queue the entry and raise the IPI if needed. */ preempt_disable(); - - /* If the work is "lazy", handle it from next tick if any */ - if (work->flags & IRQ_WORK_LAZY) { - if (llist_add(&work->llnode, this_cpu_ptr(&lazy_list)) && - tick_nohz_tick_stopped()) - arch_irq_work_raise(); + if (cpu != smp_processor_id()) { + /* Arch remote IPI send/receive backend aren't NMI safe */ + WARN_ON_ONCE(in_nmi()); + if (llist_add(&work->llnode, &per_cpu(raised_list, cpu))) + arch_send_call_function_single_ipi(cpu); } else { - if (llist_add(&work->llnode, this_cpu_ptr(&raised_list))) - arch_irq_work_raise(); + __irq_work_queue_local(work); } - preempt_enable(); return true; +#endif /* CONFIG_SMP */ } -EXPORT_SYMBOL_GPL(irq_work_queue); + bool irq_work_needs_cpu(void) { -- 2.20.1