Merge "Introduce target dirty segment ratio tunable parameter" am: c3a7391c94

Original change: https://android-review.googlesource.com/c/platform/system/vold/+/2135595

Change-Id: I42b8baffdfe9bea0d66d310952aa4c8403c36ad3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Daeho Jeong 2022-07-14 15:13:20 +00:00 committed by Automerger Merge Worker
commit 69754352bb
5 changed files with 45 additions and 25 deletions

View file

@ -508,9 +508,10 @@ int32_t GetStorageLifeTime() {
} }
void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate, void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate,
float reclaimWeight, int32_t gcPeriod, int32_t minGCSleepTime) { float reclaimWeight, int32_t gcPeriod, int32_t minGCSleepTime,
int32_t targetDirtyRatio) {
std::list<std::string> paths; std::list<std::string> paths;
bool needGC = true; bool needGC = false;
int32_t sleepTime; int32_t sleepTime;
addFromFstab(&paths, PathTypes::kBlkDevice, true); addFromFstab(&paths, PathTypes::kBlkDevice, true);
@ -553,25 +554,36 @@ void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float
int32_t reservedBlocks = std::stoi(ovpSegmentsStr) + std::stoi(reservedBlocksStr); int32_t reservedBlocks = std::stoi(ovpSegmentsStr) + std::stoi(reservedBlocksStr);
freeSegments = freeSegments > reservedBlocks ? freeSegments - reservedBlocks : 0; freeSegments = freeSegments > reservedBlocks ? freeSegments - reservedBlocks : 0;
neededSegments *= reclaimWeight; int32_t totalSegments = freeSegments + dirtySegments;
if (freeSegments >= neededSegments) { int32_t finalTargetSegments = 0;
LOG(INFO) << "Enough free segments: " << freeSegments
<< ", needed segments: " << neededSegments; if (totalSegments < minSegmentThreshold) {
needGC = false;
} else if (freeSegments + dirtySegments < minSegmentThreshold) {
LOG(INFO) << "The sum of free segments: " << freeSegments LOG(INFO) << "The sum of free segments: " << freeSegments
<< ", dirty segments: " << dirtySegments << " is under " << minSegmentThreshold; << ", dirty segments: " << dirtySegments << " is under " << minSegmentThreshold;
needGC = false;
} else { } else {
neededSegments -= freeSegments; int32_t dirtyRatio = dirtySegments * 100 / totalSegments;
neededSegments = std::min(neededSegments, (int32_t)(dirtySegments * dirtyReclaimRate)); int32_t neededForTargetRatio =
if (neededSegments == 0) { (dirtyRatio > targetDirtyRatio)
LOG(INFO) << "Low dirty segments: " << dirtySegments; ? totalSegments * (dirtyRatio - targetDirtyRatio) / 100
needGC = false; : 0;
neededSegments *= reclaimWeight;
neededSegments = (neededSegments > freeSegments) ? neededSegments - freeSegments : 0;
finalTargetSegments = std::max(neededSegments, neededForTargetRatio);
if (finalTargetSegments == 0) {
LOG(INFO) << "Enough free segments: " << freeSegments;
} else { } else {
sleepTime = gcPeriod * ONE_MINUTE_IN_MS / neededSegments; finalTargetSegments =
if (sleepTime < minGCSleepTime) { std::min(finalTargetSegments, (int32_t)(dirtySegments * dirtyReclaimRate));
sleepTime = minGCSleepTime; if (finalTargetSegments == 0) {
LOG(INFO) << "Low dirty segments: " << dirtySegments;
} else if (neededSegments >= neededForTargetRatio) {
LOG(INFO) << "Trigger GC, because of needed segments exceeding free segments";
needGC = true;
} else {
LOG(INFO) << "Trigger GC for target dirty ratio diff of: "
<< dirtyRatio - targetDirtyRatio;
needGC = true;
} }
} }
} }
@ -583,6 +595,11 @@ void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float
return; return;
} }
sleepTime = gcPeriod * ONE_MINUTE_IN_MS / finalTargetSegments;
if (sleepTime < minGCSleepTime) {
sleepTime = minGCSleepTime;
}
if (!WriteStringToFile(std::to_string(sleepTime), gcSleepTimePath)) { if (!WriteStringToFile(std::to_string(sleepTime), gcSleepTimePath)) {
PLOG(WARNING) << "Writing failed in " << gcSleepTimePath; PLOG(WARNING) << "Writing failed in " << gcSleepTimePath;
return; return;
@ -594,8 +611,8 @@ void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float
} }
LOG(INFO) << "Successfully set gc urgent mode: " LOG(INFO) << "Successfully set gc urgent mode: "
<< "free segments: " << freeSegments << ", reclaim target: " << neededSegments << "free segments: " << freeSegments << ", reclaim target: " << finalTargetSegments
<< ", sleep time: " << sleepTime; << ", sleep time: " << sleepTime;
} }
static int32_t getLifeTimeWrite() { static int32_t getLifeTimeWrite() {

View file

@ -27,7 +27,8 @@ int RunIdleMaint(bool needGC, const android::sp<android::os::IVoldTaskListener>&
int AbortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener); int AbortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
int32_t GetStorageLifeTime(); int32_t GetStorageLifeTime();
void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate, void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate,
float reclaimWeight, int32_t gcPeriod, int32_t minGCSleepTime); float reclaimWeight, int32_t gcPeriod, int32_t minGCSleepTime,
int32_t targetDirtyRatio);
void RefreshLatestWrite(); void RefreshLatestWrite();
int32_t GetWriteAmount(); int32_t GetWriteAmount();

View file

@ -495,12 +495,13 @@ binder::Status VoldNativeService::getStorageLifeTime(int32_t* _aidl_return) {
binder::Status VoldNativeService::setGCUrgentPace(int32_t neededSegments, binder::Status VoldNativeService::setGCUrgentPace(int32_t neededSegments,
int32_t minSegmentThreshold, int32_t minSegmentThreshold,
float dirtyReclaimRate, float reclaimWeight, float dirtyReclaimRate, float reclaimWeight,
int32_t gcPeriod, int32_t minGCSleepTime) { int32_t gcPeriod, int32_t minGCSleepTime,
int32_t targetDirtyRatio) {
ENFORCE_SYSTEM_OR_ROOT; ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_LOCK; ACQUIRE_LOCK;
SetGCUrgentPace(neededSegments, minSegmentThreshold, dirtyReclaimRate, reclaimWeight, gcPeriod, SetGCUrgentPace(neededSegments, minSegmentThreshold, dirtyReclaimRate, reclaimWeight, gcPeriod,
minGCSleepTime); minGCSleepTime, targetDirtyRatio);
return Ok(); return Ok();
} }

View file

@ -91,7 +91,7 @@ class VoldNativeService : public BinderService<VoldNativeService>, public os::Bn
binder::Status getStorageLifeTime(int32_t* _aidl_return); binder::Status getStorageLifeTime(int32_t* _aidl_return);
binder::Status setGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, binder::Status setGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold,
float dirtyReclaimRate, float reclaimWeight, int32_t gcPeriod, float dirtyReclaimRate, float reclaimWeight, int32_t gcPeriod,
int32_t minGCSleepTime); int32_t minGCSleepTime, int32_t targetDirtyRatio);
binder::Status refreshLatestWrite(); binder::Status refreshLatestWrite();
binder::Status getWriteAmount(int32_t* _aidl_return); binder::Status getWriteAmount(int32_t* _aidl_return);

View file

@ -69,7 +69,8 @@ interface IVold {
int getStorageLifeTime(); int getStorageLifeTime();
void setGCUrgentPace(int neededSegments, int minSegmentThreshold, void setGCUrgentPace(int neededSegments, int minSegmentThreshold,
float dirtyReclaimRate, float reclaimWeight, float dirtyReclaimRate, float reclaimWeight,
int gcPeriod, int minGCSleepTime); int gcPeriod, int minGCSleepTime,
int targetDirtyRatio);
void refreshLatestWrite(); void refreshLatestWrite();
int getWriteAmount(); int getWriteAmount();