% run as: octave-cli script % % Input configurations % ------------------- % E parent effective protection % n nominal protection of siblings set at the givel level % c current consumption -,,- % example from effective_protection 3. E = 2; n = [3 1 0 10]; c = [2 2 2 0]; % this converges to [1.16 0.84 0 0] % c = [6 2 2 0]; % keeps ratio [1.5 0.5 0 0] % c = [5 2 2 0]; % mixed ratio [1.45 0.55 0 0] % c = [8 2 2 0]; % mixed ratio [1.53 0.47 0 0] % example from effective_protection 5. %E = 2; %n = [1 0]; %c = [2 1]; % coming from close to equilibrium -> [1.50 0.50] %c = [100 100]; % coming from "infinity" -> [1.50 0.50] %c = [2 2]; % coming from uniformity -> [1.33 0.67] % example of recursion by default %E = 2; %n = [0 0]; %c = [2 1]; % coming from disbalance -> [1.33 0.67] %c = [100 100]; % coming from "infinity" -> [1.00 1.00] %c = [2 2]; % coming from uniformity -> [1.00 1.00] % example by using infinities (_without_ recursive protection) %E = 2; %n = [1e7 1e7]; %c = [2 1]; % coming from disbalance -> [1.33 0.67] %c = [100 100]; % coming from "infinity" -> [1.00 1.00] %c = [2 2]; % coming from uniformity -> [1.00 1.00] % Reclaim parameters % ------------------ % Minimal reclaim amount (GB) cluster = 4e-6; % Reclaim coefficient (think as 0.5^sc->priority) alpha = .1 % Simulation parameters % --------------------- epsilon = 1e-7; timeout = 1000; % Simulation loop % --------------------- % Simulation assumes siblings consumed the initial amount of memory (w/out % reclaim) and then the reclaim starts, all memory is reclaimable, i.e. treated % same. It simulates only non-low reclaim and assumes all memory.min = 0. ch = []; eh = []; rh = []; for t = 1:timeout % low_usage u = min(c, n); siblings = sum(u); % effective_protection() protected = min(n, c); % start with nominal e = protected * min(1, E / siblings); % normalize overcommit % recursive protection unclaimed = max(0, E - siblings); parent_overuse = sum(c) - siblings; if (unclaimed > 0 && parent_overuse > 0) overuse = max(0, c - protected); e += unclaimed * (overuse / parent_overuse); endif % get_scan_count() r = alpha * c; % assume all memory is in a single LRU list % 1bc63fb1272b ("mm, memcg: make scan aggression always exclude protection") sz = max(e, c); r .*= (1 - (e+epsilon) ./ (sz+epsilon)); % uncomment to debug prints e, c, r % nothing to reclaim, reached equilibrium if max(r) < epsilon break; endif % SWAP_CLUSTER_MAX r = max(r, (r > epsilon) .* cluster); c = max(c - r, 0); ch = [ch ; c]; eh = [eh ; e]; rh = [rh ; r]; endfor t c, e plot([ch, eh]) pause()