The reporting loop in kmemleak_scan() decided whether to tag an object as
a reported leak with a four-term compound condition whose last operand
also had a side effect (++object->unref_scans). Mixing the candidate
tests with the counter update made the check hard to read.

Move the state transition into confirm_leak(): it returns true when a
still-unreferenced suspect crosses min_unref_scans consecutive scans and
is newly flagged OBJECT_REPORTED, leaving only the reporting bookkeeping
in the caller. No functional change.

Signed-off-by: Breno Leitao <[email protected]>
---
 mm/kmemleak.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 2fff11637e490..85f18b17e79c4 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -2014,6 +2014,26 @@ static int __kmemleak_scan(bool full)
        return nr_suspects;
 }
 
+/*
+ * Promote a suspected object to a reported leak once it has stayed
+ * unreferenced for min_unref_scans consecutive scans. Called with
+ * object->lock held; returns true when the object is newly reported.
+ */
+static bool confirm_leak(struct kmemleak_object *object)
+{
+       if (!unreferenced_object(object) ||
+           !(object->flags & OBJECT_SUSPECT) ||
+           (object->flags & OBJECT_REPORTED))
+               return false;
+
+       object->unref_scans += 1;
+       if (object->unref_scans < min_unref_scans)
+               return false;
+
+       object->flags |= OBJECT_REPORTED;
+       return true;
+}
+
 /*
  * Scan the memory and report the unreferenced objects as leaks. Must be
  * called with the scan_mutex held.
@@ -2074,11 +2094,7 @@ static void kmemleak_scan(void)
                trace_handle = 0;
                dedup_print = false;
 
-               if (unreferenced_object(object) &&
-                   (object->flags & OBJECT_SUSPECT) &&
-                   !(object->flags & OBJECT_REPORTED) &&
-                   ++object->unref_scans >= min_unref_scans) {
-                       object->flags |= OBJECT_REPORTED;
+               if (confirm_leak(object)) {
                        if (kmemleak_verbose) {
                                trace_handle = object->trace_handle;
                                dedup_print = true;

-- 
2.53.0-Meta


Reply via email to