six locks: be more careful about lost wakeups
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 6 Mar 2023 12:57:51 +0000 (07:57 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:56 +0000 (17:09 -0400)
This is a workaround for a lost wakeup bug we've been seeing - we still
need to discover the actual bug.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/six.c

index e1e9df0368b6c66f4130f21df55bf517c453a053..b54a2ac480c8ed4793d54b648456c93618ff3849 100644 (file)
@@ -142,8 +142,17 @@ static int __do_six_trylock_type(struct six_lock *lock,
                 * lock, issue a wakeup because we might have caused a
                 * spurious trylock failure:
                 */
+#if 0
+               /*
+                * This code should be sufficient, but we're seeing unexplained
+                * lost wakeups:
+                */
                if (old.write_locking)
                        ret = -1 - SIX_LOCK_write;
+#else
+               if (!ret)
+                       ret = -1 - SIX_LOCK_write;
+#endif
        } else if (type == SIX_LOCK_write && lock->readers) {
                if (try) {
                        atomic64_add(__SIX_VAL(write_locking, 1),
@@ -319,11 +328,10 @@ static bool __six_relock_type(struct six_lock *lock, enum six_lock_type type,
                 * Similar to the lock path, we may have caused a spurious write
                 * lock fail and need to issue a wakeup:
                 */
-               if (old.write_locking)
-                       six_lock_wakeup(lock, old, SIX_LOCK_write);
-
                if (ret)
                        six_acquire(&lock->dep_map, 1, type == SIX_LOCK_read, ip);
+               else
+                       six_lock_wakeup(lock, old, SIX_LOCK_write);
 
                return ret;
        }