Skip to content

Commit 5a3735a

Browse files
committed
BUG/MEDIUM: clock: make sure now_ms cannot be TICK_ETERNITY
In clock ticks, 0 is TICK_ETERNITY. Long ago we used to make sure now_ms couldn't be zero so that it could be assigned to expiration timers, but it has long changed after functions like tick_add() were instrumented to make the check. The problem is that aside the rare few accidental direct assignments to expiration dates, it's also used to mark the beginning of an event that's later checked against TICK_ETERNITY to know if it has already struck. The problem in this case is that certain events may just be replaced or dropped just because they apparently never appeared. It's probably the case for stconn's "lra" and "fsb" fields, just like it is for all those involving tick_add_ifset(), like h2c->idle_start. The right approach would be to change the type of now_ms to something else that cannot take direct computations and that represents a timestamp, forcing to always use the conversion functions. The variables holding such timestamps would also be distinguished from intervals. At first glance we could have for timestamps: - 0 = never happened (for the past), eternity (for the future) - X = date and for intervals: - 0 = not set - X = interval However this requires significant changes. Instead for now, let's just make sure again that now_ms is never 0 by setting it to 1 when this happens (1 / 4 billion times, or 1ms every 49.7 days). This will need to be carefully backported to older versions. Note that with this patch backported, the previous ones fixing the zero date are not strictly needed.
1 parent ed55ff8 commit 5a3735a

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/clock.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ void clock_update_local_date(int max_wait, int interrupted)
254254
now_ns = date_ns + ofs;
255255
}
256256
now_ms = ns_to_ms(now_ns);
257+
258+
/* correct for TICK_ETNERITY (0) */
259+
if (unlikely(now_ms == TICK_ETERNITY))
260+
now_ms++;
257261
}
258262

259263
void clock_update_global_date()
@@ -285,6 +289,9 @@ void clock_update_global_date()
285289
* what we're doing here.
286290
*/
287291
now_ms = ns_to_ms(now_ns);
292+
/* correct for TICK_ETNERITY (0) */
293+
if (unlikely(now_ms == TICK_ETERNITY))
294+
now_ms++;
288295

289296
if (!((now_ns ^ old_now_ns) & ~0x7FFFULL))
290297
return;
@@ -330,7 +337,11 @@ void clock_init_process_date(void)
330337
now_offset = sec_to_ns((uint)((uint)(-global_now_ms) / 1000U - BOOT_TIME_WRAP_SEC));
331338
global_now_ns += now_offset;
332339
now_ns = global_now_ns;
333-
now_ms = global_now_ms = ns_to_ms(now_ns);
340+
now_ms = ns_to_ms(now_ns);
341+
/* correct for TICK_ETNERITY (0) */
342+
if (now_ms == TICK_ETERNITY)
343+
now_ms++;
344+
global_now_ms = now_ms;
334345

335346
th_ctx->idle_pct = 100;
336347
clock_update_date(0, 1);

0 commit comments

Comments
 (0)