On 7/22/24 15:30, David Finkel wrote:
diff --git a/mm/page_counter.c b/mm/page_counter.c
index db20d6452b71..40d5f4990218 100644
--- a/mm/page_counter.c
+++ b/mm/page_counter.c
@@ -82,6 +82,8 @@ void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)
*/
if (new > READ_ONCE(c->watermark))
WRITE_ONCE(c->watermark, new);
+ if (new > READ_ONCE(c->local_watermark))
+ WRITE_ONCE(c->local_watermark, new);
Hm, can't we have a single comparison on the hot path?
Also, we read and write c->local_watermark speculatively here, Idk if it's still
acceptable with an ability to reset watermarks "locally". Maybe it is, but
it definitely deserves at least a comment with an explanation.
Unfortunately, since the two watermarks may be reset at different
times I don't think we
can consolidate.
e.g. I think that if the usage peaked, dropped down a bit and then was
going back
up again when the "local_watermark" was reset, we'll continue only
bumping local_watermark,
but we don't want to touch "watermark" until we hit that watermark again.
If we make page_counter_reset_watermark() reset the local_watermark as well,
we can guarantee "local_watermark <= watermark" and wrap one check inside
the other.
if (new > READ_ONCE(c->local_watermark)) {
WRITE_ONCE(c->local_watermark, new);
if (new > READ_ONCE(c->watermark))
WRITE_ONCE(c->watermark, new);
}
Cheers,
Longman