|
@@ -373,8 +373,9 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc)
|
|
|
struct dirty_throttle_control *gdtc = mdtc_gdtc(dtc);
|
|
|
unsigned long bytes = vm_dirty_bytes;
|
|
|
unsigned long bg_bytes = dirty_background_bytes;
|
|
|
- unsigned long ratio = vm_dirty_ratio;
|
|
|
- unsigned long bg_ratio = dirty_background_ratio;
|
|
|
+ /* convert ratios to per-PAGE_SIZE for higher precision */
|
|
|
+ unsigned long ratio = (vm_dirty_ratio * PAGE_SIZE) / 100;
|
|
|
+ unsigned long bg_ratio = (dirty_background_ratio * PAGE_SIZE) / 100;
|
|
|
unsigned long thresh;
|
|
|
unsigned long bg_thresh;
|
|
|
struct task_struct *tsk;
|
|
@@ -386,26 +387,28 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc)
|
|
|
/*
|
|
|
* The byte settings can't be applied directly to memcg
|
|
|
* domains. Convert them to ratios by scaling against
|
|
|
- * globally available memory.
|
|
|
+ * globally available memory. As the ratios are in
|
|
|
+ * per-PAGE_SIZE, they can be obtained by dividing bytes by
|
|
|
+ * number of pages.
|
|
|
*/
|
|
|
if (bytes)
|
|
|
- ratio = min(DIV_ROUND_UP(bytes, PAGE_SIZE) * 100 /
|
|
|
- global_avail, 100UL);
|
|
|
+ ratio = min(DIV_ROUND_UP(bytes, global_avail),
|
|
|
+ PAGE_SIZE);
|
|
|
if (bg_bytes)
|
|
|
- bg_ratio = min(DIV_ROUND_UP(bg_bytes, PAGE_SIZE) * 100 /
|
|
|
- global_avail, 100UL);
|
|
|
+ bg_ratio = min(DIV_ROUND_UP(bg_bytes, global_avail),
|
|
|
+ PAGE_SIZE);
|
|
|
bytes = bg_bytes = 0;
|
|
|
}
|
|
|
|
|
|
if (bytes)
|
|
|
thresh = DIV_ROUND_UP(bytes, PAGE_SIZE);
|
|
|
else
|
|
|
- thresh = (ratio * available_memory) / 100;
|
|
|
+ thresh = (ratio * available_memory) / PAGE_SIZE;
|
|
|
|
|
|
if (bg_bytes)
|
|
|
bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE);
|
|
|
else
|
|
|
- bg_thresh = (bg_ratio * available_memory) / 100;
|
|
|
+ bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE;
|
|
|
|
|
|
if (bg_thresh >= thresh)
|
|
|
bg_thresh = thresh / 2;
|