History

Merge tag 'timers-core-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner: "Updates for the time(r) subsystem: Core: - Make the clocksource watchdog more robust by better validation checks of the measurement. Drivers: - New drivers for MStar and SSD20xd SOCs - The usual cleanups and improvements all over the place" * tag 'timers-core-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: dt-bindings: timer: Add Mstar MSC313e timer devicetree bindings documentation clocksource/drivers/msc313e: Add support for ssd20xd-based platforms clocksource/drivers: Add MStar MSC313e timer support clocksource/drivers/pistachio: Fix -Wunused-but-set-variable warning clocksource/drivers/timer-imx-sysctr: Set cpumask to cpu_possible_mask clocksource/drivers/imx-sysctr: Mark two variable with __ro_after_init clocksource/drivers/renesas,ostm: Make RENESAS_OSTM symbol visible clocksource/drivers/renesas-ostm: Add RZ/G2L OSTM support dt-bindings: timer: renesas: ostm: Document Renesas RZ/G2L OSTM clocksource/drivers/exynos_mct: Fix silly typo resulting in checkpatch warning clocksource: Reduce the default clocksource_watchdog() retries to 2 clocksource: Avoid accidental unstable marking of clocksources dt-bindings: timer: tpm-timer: Add imx8ulp compatible string reset: Add of_reset_control_get_optional_exclusive() clocksource/drivers/exynos_mct: Refactor resources allocation dt-bindings: timer: remove rockchip,rk3066-timer compatible string from rockchip,rk-timer.yaml dt-bindings: timer: cadence_ttc: Add power-domains

Linus Torvalds committed 4 years ago

Commit fd048992 parents 147cc58 35e13e916 files · +475 −44Browse files

Showing the changes to kernel (1 of 16 files). Show all

Unified · Split

kernel/time/clocksource.c+42−10
@@ -107,7 +107,7 @@ static u64 suspend_start; · 106 unmodified lines
107 * This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as107 * This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as
108 * a lower bound for cs->uncertainty_margin values when registering clocks.108 * a lower bound for cs->uncertainty_margin values when registering clocks.
109 */109 */
110#define WATCHDOG_MAX_SKEW (50 * NSEC_PER_USEC)110#define WATCHDOG_MAX_SKEW (100 * NSEC_PER_USEC)
111 111
112#ifdef CONFIG_CLOCKSOURCE_WATCHDOG112#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
113static void clocksource_watchdog_work(struct work_struct *work);113static void clocksource_watchdog_work(struct work_struct *work);
@@ -199,23 +199,30 @@ void clocksource_mark_unstable(struct clocksource *cs) · 85 unmodified lines
199 spin_unlock_irqrestore(&watchdog_lock, flags);199 spin_unlock_irqrestore(&watchdog_lock, flags);
200}200}
201 201
202ulong max_cswd_read_retries = 3;202ulong max_cswd_read_retries = 2;
203module_param(max_cswd_read_retries, ulong, 0644);203module_param(max_cswd_read_retries, ulong, 0644);
204EXPORT_SYMBOL_GPL(max_cswd_read_retries);204EXPORT_SYMBOL_GPL(max_cswd_read_retries);
205static int verify_n_cpus = 8;205static int verify_n_cpus = 8;
206module_param(verify_n_cpus, int, 0644);206module_param(verify_n_cpus, int, 0644);
207 207
208static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)208enum wd_read_status {
209 WD_READ_SUCCESS,
210 WD_READ_UNSTABLE,
211 WD_READ_SKIP
212};
213
214static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)
209{215{
210 unsigned int nretries;216 unsigned int nretries;
211 u64 wd_end, wd_delta;217 u64 wd_end, wd_end2, wd_delta;
212 int64_t wd_delay;218 int64_t wd_delay, wd_seq_delay;
213 219
214 for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) {220 for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) {
215 local_irq_disable();221 local_irq_disable();
216 *wdnow = watchdog->read(watchdog);222 *wdnow = watchdog->read(watchdog);
217 *csnow = cs->read(cs);223 *csnow = cs->read(cs);
218 wd_end = watchdog->read(watchdog);224 wd_end = watchdog->read(watchdog);
225 wd_end2 = watchdog->read(watchdog);
219 local_irq_enable();226 local_irq_enable();
220 227
221 wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask);228 wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask);
@@ -226,13 +233,34 @@ static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) · 4 unmodified lines
226 pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",233 pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",
227 smp_processor_id(), watchdog->name, nretries);234 smp_processor_id(), watchdog->name, nretries);
228 }235 }
229 return true;236 return WD_READ_SUCCESS;
230 }237 }
238
239 /*
240 * Now compute delay in consecutive watchdog read to see if
241 * there is too much external interferences that cause
242 * significant delay in reading both clocksource and watchdog.
243 *
244 * If consecutive WD read-back delay > WATCHDOG_MAX_SKEW/2,
245 * report system busy, reinit the watchdog and skip the current
246 * watchdog test.
247 */
248 wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask);
249 wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift);
250 if (wd_seq_delay > WATCHDOG_MAX_SKEW/2)
251 goto skip_test;
231 }252 }
232 253
233 pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n",254 pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n",
234 smp_processor_id(), watchdog->name, wd_delay, nretries);255 smp_processor_id(), watchdog->name, wd_delay, nretries);
235 return false;256 return WD_READ_UNSTABLE;
257
258skip_test:
259 pr_info("timekeeping watchdog on CPU%d: %s wd-wd read-back delay of %lldns\n",
260 smp_processor_id(), watchdog->name, wd_seq_delay);
261 pr_info("wd-%s-wd read-back delay of %lldns, clock-skew test skipped!\n",
262 cs->name, wd_delay);
263 return WD_READ_SKIP;
236}264}
237 265
238static u64 csnow_mid;266static u64 csnow_mid;
@@ -356,6 +384,7 @@ static void clocksource_watchdog(struct timer_list *unused) · 117 unmodified lines
356 int next_cpu, reset_pending;384 int next_cpu, reset_pending;
357 int64_t wd_nsec, cs_nsec;385 int64_t wd_nsec, cs_nsec;
358 struct clocksource *cs;386 struct clocksource *cs;
387 enum wd_read_status read_ret;
359 u32 md;388 u32 md;
360 389
361 spin_lock(&watchdog_lock);390 spin_lock(&watchdog_lock);
@@ -373,9 +402,12 @@ static void clocksource_watchdog(struct timer_list *unused) · 11 unmodified lines
373 continue;402 continue;
374 }403 }
375 404
376 if (!cs_watchdog_read(cs, &csnow, &wdnow)) {405 read_ret = cs_watchdog_read(cs, &csnow, &wdnow);
377 /* Clock readout unreliable, so give it up. */406
378 __clocksource_unstable(cs);407 if (read_ret != WD_READ_SUCCESS) {
408 if (read_ret == WD_READ_UNSTABLE)
409 /* Clock readout unreliable, so give it up. */
410 __clocksource_unstable(cs);
379 continue;411 continue;
380 }412 }
381 413