Snap for 8920865 from 3f8e855de983fa14eeb98f3b417d4491c3f36cac to tm-qpr1-release
Change-Id: Ia827da268aadd7e24fd105f76aa4439bdb6a2c70
diff --git a/IdleMaint.cpp b/IdleMaint.cpp
index 9d3450a..0c6b115 100644
--- a/IdleMaint.cpp
+++ b/IdleMaint.cpp
@@ -86,7 +86,6 @@
static const int GC_TIMEOUT_SEC = 420;
static const int DEVGC_TIMEOUT_SEC = 120;
static const int KBYTES_IN_SEGMENT = 2048;
-static const int MIN_GC_URGENT_SLEEP_TIME = 500;
static const int ONE_MINUTE_IN_MS = 60000;
static const int GC_NORMAL_MODE = 0;
static const int GC_URGENT_MID_MODE = 3;
@@ -509,9 +508,10 @@
}
void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate,
- float reclaimWeight, int32_t gcPeriod) {
+ float reclaimWeight, int32_t gcPeriod, int32_t minGCSleepTime,
+ int32_t targetDirtyRatio) {
std::list<std::string> paths;
- bool needGC = true;
+ bool needGC = false;
int32_t sleepTime;
addFromFstab(&paths, PathTypes::kBlkDevice, true);
@@ -554,25 +554,36 @@
int32_t reservedBlocks = std::stoi(ovpSegmentsStr) + std::stoi(reservedBlocksStr);
freeSegments = freeSegments > reservedBlocks ? freeSegments - reservedBlocks : 0;
- neededSegments *= reclaimWeight;
- if (freeSegments >= neededSegments) {
- LOG(INFO) << "Enough free segments: " << freeSegments
- << ", needed segments: " << neededSegments;
- needGC = false;
- } else if (freeSegments + dirtySegments < minSegmentThreshold) {
+ int32_t totalSegments = freeSegments + dirtySegments;
+ int32_t finalTargetSegments = 0;
+
+ if (totalSegments < minSegmentThreshold) {
LOG(INFO) << "The sum of free segments: " << freeSegments
- << ", dirty segments: " << dirtySegments << " is under " << minSegmentThreshold;
- needGC = false;
+ << ", dirty segments: " << dirtySegments << " is under " << minSegmentThreshold;
} else {
- neededSegments -= freeSegments;
- neededSegments = std::min(neededSegments, (int32_t)(dirtySegments * dirtyReclaimRate));
- if (neededSegments == 0) {
- LOG(INFO) << "Low dirty segments: " << dirtySegments;
- needGC = false;
+ int32_t dirtyRatio = dirtySegments * 100 / totalSegments;
+ int32_t neededForTargetRatio =
+ (dirtyRatio > targetDirtyRatio)
+ ? totalSegments * (dirtyRatio - targetDirtyRatio) / 100
+ : 0;
+ neededSegments *= reclaimWeight;
+ neededSegments = (neededSegments > freeSegments) ? neededSegments - freeSegments : 0;
+
+ finalTargetSegments = std::max(neededSegments, neededForTargetRatio);
+ if (finalTargetSegments == 0) {
+ LOG(INFO) << "Enough free segments: " << freeSegments;
} else {
- sleepTime = gcPeriod * ONE_MINUTE_IN_MS / neededSegments;
- if (sleepTime < MIN_GC_URGENT_SLEEP_TIME) {
- sleepTime = MIN_GC_URGENT_SLEEP_TIME;
+ finalTargetSegments =
+ std::min(finalTargetSegments, (int32_t)(dirtySegments * dirtyReclaimRate));
+ 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;
}
}
}
@@ -584,6 +595,11 @@
return;
}
+ sleepTime = gcPeriod * ONE_MINUTE_IN_MS / finalTargetSegments;
+ if (sleepTime < minGCSleepTime) {
+ sleepTime = minGCSleepTime;
+ }
+
if (!WriteStringToFile(std::to_string(sleepTime), gcSleepTimePath)) {
PLOG(WARNING) << "Writing failed in " << gcSleepTimePath;
return;
@@ -595,8 +611,8 @@
}
LOG(INFO) << "Successfully set gc urgent mode: "
- << "free segments: " << freeSegments << ", reclaim target: " << neededSegments
- << ", sleep time: " << sleepTime;
+ << "free segments: " << freeSegments << ", reclaim target: " << finalTargetSegments
+ << ", sleep time: " << sleepTime;
}
static int32_t getLifeTimeWrite() {
diff --git a/IdleMaint.h b/IdleMaint.h
index 9a2af4a..a28cde2 100644
--- a/IdleMaint.h
+++ b/IdleMaint.h
@@ -27,7 +27,8 @@
int AbortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
int32_t GetStorageLifeTime();
void SetGCUrgentPace(int32_t neededSegments, int32_t minSegmentThreshold, float dirtyReclaimRate,
- float reclaimWeight, int32_t gcPeriod);
+ float reclaimWeight, int32_t gcPeriod, int32_t minGCSleepTime,
+ int32_t targetDirtyRatio);
void RefreshLatestWrite();
int32_t GetWriteAmount();
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 8ba3aaf..5e838f6 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -495,11 +495,13 @@
binder::Status VoldNativeService::setGCUrgentPace(int32_t neededSegments,
int32_t minSegmentThreshold,
float dirtyReclaimRate, float reclaimWeight,
- int32_t gcPeriod) {
+ int32_t gcPeriod, int32_t minGCSleepTime,
+ int32_t targetDirtyRatio) {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_LOCK;
- SetGCUrgentPace(neededSegments, minSegmentThreshold, dirtyReclaimRate, reclaimWeight, gcPeriod);
+ SetGCUrgentPace(neededSegments, minSegmentThreshold, dirtyReclaimRate, reclaimWeight, gcPeriod,
+ minGCSleepTime, targetDirtyRatio);
return Ok();
}
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 423e8f9..ac5d852 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -90,7 +90,8 @@
binder::Status abortIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener);
binder::Status getStorageLifeTime(int32_t* _aidl_return);
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 targetDirtyRatio);
binder::Status refreshLatestWrite();
binder::Status getWriteAmount(int32_t* _aidl_return);
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index d77c7da..ea75864 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -69,7 +69,8 @@
int getStorageLifeTime();
void setGCUrgentPace(int neededSegments, int minSegmentThreshold,
float dirtyReclaimRate, float reclaimWeight,
- int gcPeriod);
+ int gcPeriod, int minGCSleepTime,
+ int targetDirtyRatio);
void refreshLatestWrite();
int getWriteAmount();