Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1624432
| Path | csiph.com!news.mixmin.net!aioe.org!news.servidellagleba.it!bofh.it!news.nic.it!robomod |
|---|---|
| From | Daniel Lezcano <daniel.lezcano@linaro.org> |
| Newsgroups | linux.kernel |
| Subject | [PATCH 12/29] arm64: arch_timer: Allows a CPU-specific erratum to only affect a subset of CPUs |
| Date | Sun, 16 Apr 2017 22:30:02 +0200 |
| Message-ID | <twYY2-87V-19@gated-at.bofh.it> (permalink) |
| References | <twYY1-87V-3@gated-at.bofh.it> <twYY1-87V-5@gated-at.bofh.it> |
| Dkim-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8VhRqAkMimYWtWdUn3BrlxJA87Vw+h9uAQyt1LeVGAQ=; b=VwNNeRH+vx+I9PaDdbiQYk5Ig2Qa5Z55Vg7d2QA2T8lhVSqY31MoNb6A7YzqM1jN5C aCR2irt6IAeTHFrWPKjz2ua087HSCo6t0N2KdjUeBfE0LH5ZBIFvFmacvwuM9nP44WIp 56lynJPC2pThaUre5/NQtqQsvoxRBHLrTuuEg= |
| X-Google-Dkim-Signature | v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8VhRqAkMimYWtWdUn3BrlxJA87Vw+h9uAQyt1LeVGAQ=; b=pH1HZ539RMNxI7rCVU9tH0arPhObhBWIh8ohYsHlI6KoMszS1stkl6mxA2TGtmhp+I 5DK3SR975d5BD+JahhiXxwDavaNivDy1vdiaPnCFT5U9EGSYzotJUKczp1ixFdMytcxH kIgdVFsg4uPRO4EnXiYgku7vNdr0TlGjZXwgOXAuwDMIfBRLxao5qkHv1Jcq0ShHVAB1 2oFEANxI1DI8xa8M6HTnpoO0FiipdRfxpmvaPqDQ03buCRdUqXIILzw0Ussv3/93o5Wu X+b9fg95jskQbRg4hqyNms5d9yr4GmtVHE2bijiykee8bsSQqKi41yE1+Pii57rLffpY 3VyQ== |
| X-Gm-Message-State | AN3rC/4hfB5Bi7MAUG23UtH01u+iOkyaQ/O/D/DYikM2aO7GE/SQfYYT Jq4aCmxOjOXBZuIxHhw3Ug== |
| X-Received | by 10.223.178.68 with SMTP id y4mr16887515wra.88.1492374494999; Sun, 16 Apr 2017 13:28:14 -0700 (PDT) |
| X-Mailer | git-send-email 2.7.4 |
| Sender | robomod@news.nic.it |
| List-ID | <linux-kernel.vger.kernel.org> |
| X-Mailing-List | linux-kernel@vger.kernel.org |
| Approved | robomod@news.nic.it |
| Lines | 143 |
| Organization | linux.* mail to news gateway |
| X-Original-Cc | linux-kernel@vger.kernel.org, Marc Zyngier <marc.zyngier@arm.com>, Mark Rutland <mark.rutland@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will.deacon@arm.com>, linux-arm-kernel@lists.infradead.org (moderated list:ARM ARCHITECTED TIMER DRIVER) |
| X-Original-Date | Sun, 16 Apr 2017 22:27:02 +0200 |
| X-Original-Message-ID | <1492374441-23336-12-git-send-email-daniel.lezcano@linaro.org> |
| X-Original-References | <20170416202542.GV2078@mai> <1492374441-23336-1-git-send-email-daniel.lezcano@linaro.org> |
| X-Original-Sender | linux-kernel-owner@vger.kernel.org |
| Xref | csiph.com linux.kernel:1624432 |
Show key headers only | View raw
From: Marc Zyngier <marc.zyngier@arm.com>
Instead of applying a CPU-specific workaround to all CPUs in the system,
allow it to only affect a subset of them (typical big-little case).
This is done by turning the erratum pointer into a per-CPU variable.
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/arch_timer.h | 31 ++++++++++++++++----------
drivers/clocksource/arm_arch_timer.c | 42 +++++++++++++++++++++++++-----------
2 files changed, 50 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 01917b4..6bd1a9a 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -25,6 +25,7 @@
#include <linux/bug.h>
#include <linux/init.h>
#include <linux/jump_label.h>
+#include <linux/smp.h>
#include <linux/types.h>
#include <clocksource/arm_arch_timer.h>
@@ -55,17 +56,25 @@ struct arch_timer_erratum_workaround {
int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
};
-extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
-
-#define arch_timer_reg_read_stable(reg) \
-({ \
- u64 _val; \
- if (needs_unstable_timer_counter_workaround() && \
- timer_unstable_counter_workaround->read_##reg) \
- _val = timer_unstable_counter_workaround->read_##reg(); \
- else \
- _val = read_sysreg(reg); \
- _val; \
+DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
+ timer_unstable_counter_workaround);
+
+#define arch_timer_reg_read_stable(reg) \
+({ \
+ u64 _val; \
+ if (needs_unstable_timer_counter_workaround()) { \
+ const struct arch_timer_erratum_workaround *wa; \
+ preempt_disable(); \
+ wa = __this_cpu_read(timer_unstable_counter_workaround); \
+ if (wa && wa->read_##reg) \
+ _val = wa->read_##reg(); \
+ else \
+ _val = read_sysreg(reg); \
+ preempt_enable(); \
+ } else { \
+ _val = read_sysreg(reg); \
+ } \
+ _val; \
})
/*
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index a0c9ee8..4551587 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -235,7 +235,8 @@ static u64 notrace hisi_161010101_read_cntvct_el0(void)
#endif
#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
-const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
+DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *,
+ timer_unstable_counter_workaround);
EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
@@ -338,9 +339,18 @@ arch_timer_iterate_errata(enum arch_timer_erratum_match_type type,
}
static
-void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa)
+void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa,
+ bool local)
{
- timer_unstable_counter_workaround = wa;
+ int i;
+
+ if (local) {
+ __this_cpu_write(timer_unstable_counter_workaround, wa);
+ } else {
+ for_each_possible_cpu(i)
+ per_cpu(timer_unstable_counter_workaround, i) = wa;
+ }
+
static_branch_enable(&arch_timer_read_ool_enabled);
}
@@ -369,14 +379,17 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
return;
if (needs_unstable_timer_counter_workaround()) {
- if (wa != timer_unstable_counter_workaround)
+ const struct arch_timer_erratum_workaround *__wa;
+ __wa = __this_cpu_read(timer_unstable_counter_workaround);
+ if (__wa && wa != __wa)
pr_warn("Can't enable workaround for %s (clashes with %s\n)",
- wa->desc,
- timer_unstable_counter_workaround->desc);
- return;
+ wa->desc, __wa->desc);
+
+ if (__wa)
+ return;
}
- arch_timer_enable_workaround(wa);
+ arch_timer_enable_workaround(wa, local);
pr_info("Enabling %s workaround for %s\n",
local ? "local" : "global", wa->desc);
}
@@ -384,10 +397,15 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
#define erratum_handler(fn, r, ...) \
({ \
bool __val; \
- if (needs_unstable_timer_counter_workaround() && \
- timer_unstable_counter_workaround->fn) { \
- r = timer_unstable_counter_workaround->fn(__VA_ARGS__); \
- __val = true; \
+ if (needs_unstable_timer_counter_workaround()) { \
+ const struct arch_timer_erratum_workaround *__wa; \
+ __wa = __this_cpu_read(timer_unstable_counter_workaround); \
+ if (__wa && __wa->fn) { \
+ r = __wa->fn(__VA_ARGS__); \
+ __val = true; \
+ } else { \
+ __val = false; \
+ } \
} else { \
__val = false; \
} \
--
2.7.4
Back to linux.kernel | Previous | Next | Find similar | Unroll thread
[PATCH 12/29] arm64: arch_timer: Allows a CPU-specific erratum to only affect a subset of CPUs Daniel Lezcano <daniel.lezcano@linaro.org> - 2017-04-16 22:30 +0200
csiph-web