[PATCH v6 7/7] platform/chrome: cros_ec_sensorhub: Drop sensor samples with past timestamps
From: Satyam Gupta
Date: Thu Oct 29 2026 - 05:33:41 EST
From: Scott Collyer <scollyer@xxxxxxxxxx>
When a sample timestamp is earlier than the newest timestamp seen for
that sensor, the sample is clamped to the last batch timestamp so that
the batch spreading logic re-times it. This makes the spreading logic
treat it as part of the previous batch, which produces stale timestamps
downstream.
Drop such Out Of Order (OOO) samples instead. The previous batch length
then no longer covers the interval up to the next batch, so reset it to
prevent the next batch from computing its sample period across the gap.
Rename cros_ec_sensor_ring_check_for_past_timestamp() to
cros_ec_sensor_ring_is_past_timestamp() and make it return true for past
timestamps.
Signed-off-by: Scott Collyer <scollyer@xxxxxxxxxx>
Signed-off-by: Satyam Gupta <sgsatyam@xxxxxxxxxx>
---
.../platform/chrome/cros_ec_sensorhub_ring.c | 43 +++++++++++++------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
index ef20aac..bc3f120 100644
--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
+++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
@@ -440,23 +440,29 @@ cros_ec_sensor_ring_fix_overflow(s64 *ts,
state->last = *ts;
}
-static void
-cros_ec_sensor_ring_check_for_past_timestamp(struct cros_ec_sensorhub
- *sensorhub,
- struct cros_ec_sensors_ring_sample
- *sample)
+static bool
+cros_ec_sensor_ring_is_past_timestamp(struct cros_ec_sensorhub *sensorhub,
+ struct cros_ec_sensors_ring_sample *sample)
{
const u8 sensor_id = sample->sensor_id;
- /* If this event is earlier than one we saw before... */
+ /*
+ * If this event is strictly earlier than one we saw before, it is truly
+ * out-of-order and must be dropped to preserve monotonicity.
+ *
+ * We intentionally allow duplicate timestamps (==) to pass through here
+ * because the EC/ISH may report a batch of samples with the same raw
+ * timestamp. These duplicates are required by the downstream spreading
+ * logic (cros_ec_sensor_ring_spread_add) to interpolate unique,
+ * monotonic timestamps for each sample in the batch.
+ */
if (sensorhub->batch_state[sensor_id].newest_sensor_event >
sample->timestamp)
- /* mark it for spreading. */
- sample->timestamp =
- sensorhub->batch_state[sensor_id].last_ts;
- else
- sensorhub->batch_state[sensor_id].newest_sensor_event =
- sample->timestamp;
+ return true;
+
+ sensorhub->batch_state[sensor_id].newest_sensor_event =
+ sample->timestamp;
+ return false;
}
/**
@@ -608,8 +614,17 @@ cros_ec_sensor_ring_process_event(struct cros_ec_sensorhub *sensorhub,
for (axis = 0; axis < 3; axis++)
out->vector[axis] = in->data[axis];
- if (sensorhub->tight_timestamps)
- cros_ec_sensor_ring_check_for_past_timestamp(sensorhub, out);
+ if (sensorhub->tight_timestamps &&
+ cros_ec_sensor_ring_is_past_timestamp(sensorhub, out)) {
+ /*
+ * Drop the sample. The previous batch length no longer
+ * covers the interval up to the next batch, so reset it to
+ * prevent the next batch from computing its sample period
+ * across the gap.
+ */
+ sensorhub->batch_state[out->sensor_id].last_len = 0;
+ return false;
+ }
return true;
}
--
2.56.0.307.g5fe7bd680c-goog