On Fri, Mar 22, 2019 at 10:49:46PM +0000, Chris Down wrote: > Roman Gushchin writes: > > I've noticed that the old version is just wrong: if cgroup_size is way smaller > > than max(min, low), scan will be set to -lruvec_size. > > Given that it's unsigned long, we'll end up with scanning the whole list > > (due to clamp() below). > > Are you certain? If so, I don't see what you mean. This is how the code > looks in Linus' tree after the fixups: > > unsigned long cgroup_size = mem_cgroup_size(memcg); > unsigned long baseline = 0; > > if (!sc->memcg_low_reclaim) > baseline = lruvec_size; > scan = lruvec_size * cgroup_size / protection - baseline; > > This works correctly as far as I can tell: I'm blaming the old version, not the new one. New one is perfectly fine, thanks to these lines: + /* Avoid TOCTOU with earlier protection check */ + cgroup_size = max(cgroup_size, protection); The old one was racy. Thanks!