TimeStats: fix a racing case
setPostTime is plumbed without BufferQueue lock, and it's called at the
end of queueBuffer. If the addAndGetFrameTimestamps is delayed by
queueBuffer back pressure (this could happen on special SF/BQ configs),
setAcquireFence will be called with a out-of-bound index internally.
So this change will tweak the order of the back Pressure logic to make
the post time correct when queueBuffer back pressure happens as well as
guarding the TimeStats more strictly.
Bug: 130515827
Test: all SurfaceFlinger tests
Change-Id: I2eace6d8693cc647284de0f33e7b58a6bf79eaaf
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 78c6e74..740099e 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -291,6 +291,9 @@
std::lock_guard<std::mutex> lock(mMutex);
if (!mTimeStatsTracker.count(layerID)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerID];
+ if (layerRecord.waitData < 0 ||
+ layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+ return;
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.latchTime = latchTime;
@@ -306,6 +309,9 @@
std::lock_guard<std::mutex> lock(mMutex);
if (!mTimeStatsTracker.count(layerID)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerID];
+ if (layerRecord.waitData < 0 ||
+ layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+ return;
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.desiredTime = desiredTime;
@@ -321,6 +327,9 @@
std::lock_guard<std::mutex> lock(mMutex);
if (!mTimeStatsTracker.count(layerID)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerID];
+ if (layerRecord.waitData < 0 ||
+ layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+ return;
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.acquireTime = acquireTime;
@@ -338,6 +347,9 @@
std::lock_guard<std::mutex> lock(mMutex);
if (!mTimeStatsTracker.count(layerID)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerID];
+ if (layerRecord.waitData < 0 ||
+ layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+ return;
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.acquireFence = acquireFence;
@@ -353,6 +365,9 @@
std::lock_guard<std::mutex> lock(mMutex);
if (!mTimeStatsTracker.count(layerID)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerID];
+ if (layerRecord.waitData < 0 ||
+ layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+ return;
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.frameTime.presentTime = presentTime;
@@ -374,6 +389,9 @@
std::lock_guard<std::mutex> lock(mMutex);
if (!mTimeStatsTracker.count(layerID)) return;
LayerRecord& layerRecord = mTimeStatsTracker[layerID];
+ if (layerRecord.waitData < 0 ||
+ layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size()))
+ return;
TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData];
if (timeRecord.frameTime.frameNumber == frameNumber) {
timeRecord.presentFence = presentFence;