Whamcloud - gitweb
- Fixed a DLM deadlock bug
authorpschwan <pschwan>
Tue, 18 Jun 2002 03:12:12 +0000 (03:12 +0000)
committerpschwan <pschwan>
Tue, 18 Jun 2002 03:12:12 +0000 (03:12 +0000)
- Added the leak finding script

lustre/ldlm/ldlm_lock.c
lustre/tests/leak_finder.pl [new file with mode: 0644]

index 94df819..66cc28b 100644 (file)
@@ -512,12 +512,22 @@ ldlm_error_t ldlm_local_lock_enqueue(struct lustre_handle *lockh,
 
         /* policies are not executed on the client */
         if (!local && (policy = ldlm_res_policy_table[res->lr_type])) {
-                int rc = policy(lock, cookie, lock->l_req_mode, NULL);
+                int rc;
+
+                /* We do this dancing with refcounts and locks because the
+                 * policy function could send an RPC */
+                res->lr_refcount++;
+                spin_unlock(&res->lr_lock);
+
+                rc = policy(lock, cookie, lock->l_req_mode, NULL);
+
+                spin_lock(&res->lr_lock);
+                ldlm_resource_put(res);
+
                 if (rc == ELDLM_LOCK_CHANGED) {
                         res = lock->l_resource;
                         *flags |= LDLM_FL_LOCK_CHANGED;
-                }
-                if (rc == ELDLM_LOCK_ABORTED) {
+                } else if (rc == ELDLM_LOCK_ABORTED) {
                         /* Abort. */
                         ldlm_resource_put(lock->l_resource);
                         ldlm_lock_free(lock);
diff --git a/lustre/tests/leak_finder.pl b/lustre/tests/leak_finder.pl
new file mode 100644 (file)
index 0000000..99a0f67
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/perl -w
+
+my ($line, $memory);
+my $debug_line = 0;
+
+while ($line = <>) {
+    $debug_line++;
+    my ($file, $func, $lno, $name, $size, $addr, $type);
+    if ($line =~ m/^.*\(@\d+ (.*):(.*)\,l\. (\d+) .* k(.*) '(.*)': (\d+) at (.*) \(tot .*$/) {
+        $file = $1;
+        $func = $2;
+        $lno = $3;
+        $type = $4;
+        $name = $5;
+        $size = $6;
+        $addr = $7;
+        printf("%8s %6d bytes at %s called %s (%s:%s:%d)\n", $type, $size,
+               $addr, $name, $file, $func, $lno);
+    } else {
+        next;
+    }
+
+    if ($type eq 'malloced') {
+        $memory->{$addr}->{name} = $name;
+        $memory->{$addr}->{size} = $size;
+        $memory->{$addr}->{file} = $file;
+        $memory->{$addr}->{func} = $func;
+        $memory->{$addr}->{lno} = $lno;
+        $memory->{$addr}->{debug_line} = $debug_line;
+    } else {
+        if (!defined($memory->{$addr})) {
+            print "*** Free without malloc ($size bytes at $addr, $file:$func:$lno)\n";
+            next;
+        }
+        my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$addr};
+
+        if ($memory->{$addr}->{size} != $size) {
+            print "*** Free different size ($memory->{$addr}->{size} alloced, $size freed).\n";
+            print "    malloc at $memory->{$addr}->{file}:$memory->{$addr}->{func}:$memory->{$addr}->{lno}, free at $file:$func:$lno\n";
+            next;
+        }
+
+        delete $memory->{$addr};
+    }
+}
+
+my $key;
+foreach $key (keys(%{$memory})) {
+    my ($oldname, $oldsize, $oldfile, $oldfunc, $oldlno) = $memory->{$key};
+    print "*** Leak: $memory->{$key}->{size} bytes allocated at $key ($memory->{$key}->{file}:$memory->{$key}->{func}:$memory->{$key}->{lno}, debug file line $memory->{$key}->{debug_line})\n";
+}
+
+print "Done.\n";