]> granicus.if.org Git - zfs/commitdiff
Fix kmem:slab_overcommit regression test locking
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Dec 2009 20:46:11 +0000 (12:46 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Dec 2009 20:46:11 +0000 (12:46 -0800)
This regression test could crash in splat_kmem_cache_test_reclaim()
due to a race between the slab relclaim and the normal exiting of
the thread.  Specifically, the kct structure could be free'd by
the thread performing the allocations while the reclaim function
was also working on that's threads kct structure.  The simplest
fix is to extend the kcp->kcp_lock over the reclaim to prevent
the kct from being freed.  A better fix would be to ref count
these structures, but since is just a regression this locking
change is enough.  Surprisingly this was only observed commonly
under RHEL5.4 but all platform could have hit this.

module/splat/splat-kmem.c

index 6957f1f1c29c68cd7dd2bfdf116f5b93c40433e9..c743dd163ddd247a1e94073bfba5282ed6e1c861 100644 (file)
@@ -418,9 +418,10 @@ splat_kmem_cache_test_reclaim(void *priv)
        for (i = 0; i < kcp->kcp_kct_count; i++) {
                spin_lock(&kcp->kcp_lock);
                kct = kcp->kcp_kct[i];
-               spin_unlock(&kcp->kcp_lock);
-               if (!kct)
+               if (!kct) {
+                       spin_unlock(&kcp->kcp_lock);
                        continue;
+               }
 
                spin_lock(&kct->kct_lock);
                count = kct->kct_kcd_count * SPLAT_KMEM_OBJ_RECLAIM / 100;
@@ -435,6 +436,7 @@ splat_kmem_cache_test_reclaim(void *priv)
                        }
                }
                spin_unlock(&kct->kct_lock);
+               spin_unlock(&kcp->kcp_lock);
        }
 
        return;