[REGRESSION][BISECTED] Boot hangs on Allwinner D1 RISC-V board

Indrek Kruusa <[email protected]>
Newsgroups dev.linux.lists.regressions
Message-ID <[email protected]>
Hi!

I have an Allwinner D1 based board whose boot process hangs before the root filesystem is mounted. The issue has been present since v7.1-rc1.

A git bisect points to:
ff1c0c5d07028 Merge branch 'timers/urgent' into timers/core

The board boots normally if I revert the changes in kernel/time/clockevents.c back to commit 09c04714cb455 (patch included below to speed up the testing).

This platform has a history of requiring special quirks ([1], [2]).

I originally reported this issue here [3]

[1] https://lore.kernel.org/lkml/[email protected]/
[2] https://lore.kernel.org/linux-riscv/[email protected]/
[3] https://lore.kernel.org/linux-riscv/CA+fTLhgLmTY+exGujKf8OYYQvcEW5X5NJ_5sLq2AYL6zER2c0A@mail.gmail.com/

Best regards,
Indrek


diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 5e22697b098d8..83712aa1d385c 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -94,9 +94,6 @@ static int __clockevents_switch_state(struct clock_event_device *dev,
 	if (dev->features & CLOCK_EVT_FEAT_DUMMY)
 		return 0;
 
-	/* On state transitions clear the forced flag unconditionally */
-	dev->next_event_forced = 0;
-
 	/* Transition with new state-specific callbacks */
 	switch (state) {
 	case CLOCK_EVT_STATE_DETACHED:
@@ -175,7 +172,6 @@ void clockevents_shutdown(struct clock_event_device *dev)
 {
 	clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
 	dev->next_event = KTIME_MAX;
-	dev->next_event_forced = 0;
 }
 
 /**
@@ -340,6 +336,7 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, b
 {
 	int64_t delta;
 	u64 cycles;
+	int rc;
 
 	if (WARN_ON_ONCE(expires < 0))
 		return -ETIME;
@@ -361,29 +358,16 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, b
 		return 0;
 
 	delta = ktime_to_ns(ktime_sub(expires, ktime_get()));
+	if (delta <= 0)
+		return force ? clockevents_program_min_delta(dev) : -ETIME;
 
-	/* Required for tick_periodic() during early boot */
-	if (delta <= 0 && !force)
-		return -ETIME;
+	delta = min(delta, (int64_t) dev->max_delta_ns);
+	delta = max(delta, (int64_t) dev->min_delta_ns);
 
-	if (delta > (int64_t)dev->min_delta_ns) {
-		delta = min(delta, (int64_t) dev->max_delta_ns);
-		cycles = ((u64)delta * dev->mult) >> dev->shift;
-		if (!dev->set_next_event((unsigned long) cycles, dev)) {
-			dev->next_event_forced = 0;
-			return 0;
-		}
-	}
+	cycles = ((u64)delta * dev->mult) >> dev->shift;
+	rc = dev->set_next_event((unsigned long) cycles, dev);
 
-	if (dev->next_event_forced)
-		return 0;
-
-	if (dev->set_next_event(dev->min_delta_ticks, dev)) {
-		if (!force || clockevents_program_min_delta(dev))
-			return -ETIME;
-	}
-	dev->next_event_forced = 1;
-	return 0;
+	return (rc && force) ? clockevents_program_min_delta(dev) : rc;
 }
 
 /*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.