1. 08 Aug, 2013 1 commit
    • Jeff Mahoney's avatar
      reiserfs: locking, handle nested locks properly · 278f6679
      Jeff Mahoney authored
      The reiserfs write lock replaced the BKL and uses similar semantics.
      Frederic's locking code makes a distinction between when the lock is nested
      and when it's being acquired/released, but I don't think that's the right
      distinction to make.
      The right distinction is between the lock being released at end-of-use and
      the lock being released for a schedule. The unlock should return the depth
      and the lock should restore it, rather than the other way around as it is now.
      This patch implements that and adds a number of places where the lock
      should be dropped.
      Signed-off-by: default avatarJeff Mahoney <jeffm@suse.com>
  2. 21 Mar, 2012 1 commit
  3. 31 Mar, 2011 1 commit
  4. 02 Jan, 2010 1 commit
    • Frederic Weisbecker's avatar
      reiserfs: Warn on lock relax if taken recursively · c4a62ca3
      Frederic Weisbecker authored
      When we relax the reiserfs lock to avoid creating unwanted
      dependencies against others locks while grabbing these,
      we want to ensure it has not been taken recursively, otherwise
      the lock won't be really relaxed. Only its depth will be decreased.
      The unwanted dependency would then actually happen.
      To prevent from that, add a reiserfs_lock_check_recursive() call
      in the places that need it.
      Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
      Cc: Alexander Beregalov <a.beregalov@gmail.com>
      Cc: Chris Mason <chris.mason@oracle.com>
      Cc: Ingo Molnar <mingo@elte.hu>
  5. 14 Sep, 2009 3 commits
    • Frederic Weisbecker's avatar
      kill-the-bkl/reiserfs: panic in case of lock imbalance · 80503185
      Frederic Weisbecker authored
      Until now, trying to unlock the reiserfs write lock whereas the current
      task doesn't hold it lead to a simple warning.
      We should actually warn and panic in this case to avoid the user datas
      to reach an unstable state.
      Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
      Cc: Jeff Mahoney <jeffm@suse.com>
      Cc: Chris Mason <chris.mason@oracle.com>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: Alexander Beregalov <a.beregalov@gmail.com>
      Cc: Laurent Riffard <laurent.riffard@free.fr>
    • Frederic Weisbecker's avatar
      kill-the-BKL/reiserfs: provide a tool to lock only once the write lock · daf88c89
      Frederic Weisbecker authored
      Sometimes we don't want to recursively hold the per superblock write
      lock because we want to be sure it is actually released when we come
      to sleep.
      This patch introduces the necessary tools for that.
      reiserfs_write_lock_once() does the same job than reiserfs_write_lock()
      except that it won't try to acquire recursively the lock if the current
      task already owns it. Also the lock_depth before the call of this function
      is returned.
      reiserfs_write_unlock_once() unlock only if reiserfs_write_lock_once()
      returned a depth equal to -1, ie: only if it actually locked.
      Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
      Cc: Alessio Igor Bogani <abogani@texware.it>
      Cc: Jeff Mahoney <jeffm@suse.com>
      Cc: Alexander Beregalov <a.beregalov@gmail.com>
      Cc: Chris Mason <chris.mason@oracle.com>
      LKML-Reference: <1239680065-25013-2-git-send-email-fweisbec@gmail.com>
      Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    • Frederic Weisbecker's avatar
      reiserfs: kill-the-BKL · 8ebc4232
      Frederic Weisbecker authored
      This patch is an attempt to remove the Bkl based locking scheme from
      reiserfs and is intended.
      It is a bit inspired from an old attempt by Peter Zijlstra:
      The bkl is heavily used in this filesystem to prevent from
      concurrent write accesses on the filesystem.
      Reiserfs makes a deep use of the specific properties of the Bkl:
      - It can be acqquired recursively by a same task
      - It is released on the schedule() calls and reacquired when schedule() returns
      The two properties above are a roadmap for the reiserfs write locking so it's
      very hard to simply replace it with a common mutex.
      - We need a recursive-able locking unless we want to restructure several blocks
        of the code.
      - We need to identify the sites where the bkl was implictly relaxed
        (schedule, wait, sync, etc...) so that we can in turn release and
        reacquire our new lock explicitly.
        Such implicit releases of the lock are often required to let other
        resources producer/consumer do their job or we can suffer unexpected
        starvations or deadlocks.
      So the new lock that replaces the bkl here is a per superblock mutex with a
      specific property: it can be acquired recursively by a same task, like the
      For such purpose, we integrate a lock owner and a lock depth field on the
      superblock information structure.
      The first axis on this patch is to turn reiserfs_write_(un)lock() function
      into a wrapper to manage this mutex. Also some explicit calls to
      lock_kernel() have been converted to reiserfs_write_lock() helpers.
      The second axis is to find the important blocking sites (schedule...(),
      wait_on_buffer(), sync_dirty_buffer(), etc...) and then apply an explicit
      release of the write lock on these locations before blocking. Then we can
      safely wait for those who can give us resources or those who need some.
      Typically this is a fight between the current writer, the reiserfs workqueue
      (aka the async commiter) and the pdflush threads.
      The third axis is a consequence of the second. The write lock is usually
      on top of a lock dependency chain which can include the journal lock, the
      flush lock or the commit lock. So it's dangerous to release and trying to
      reacquire the write lock while we still hold other locks.
      This is fine with the bkl:
            T1                       T2
          // do something
                                      mutex_lock(A) -> already locked by T1
                                      schedule() (and then unlock_kernel())
      This is not fine with a mutex:
            T1                       T2
          // do something
                                    mutex_lock(A) -> already locked by T1
          mutex_lock(write) -> already locked by T2
      The solution in this patch is to provide a helper which releases the write
      lock and sleep a bit if we can't lock a mutex that depend on it. It's another
      simulation of the bkl behaviour.
      The last axis is to locate the fs callbacks that are called with the bkl held,
      according to Documentation/filesystem/Locking.
      Those are:
      - reiserfs_remount
      - reiserfs_fill_super
      - reiserfs_put_super
      Reiserfs didn't need to explicitly lock because of the context of these callbacks.
      But now we must take care of that with the new locking.
      After this patch, reiserfs suffers from a slight performance regression (for now).
      On UP, a high volume write with dd reports an average of 27 MB/s instead
      of 30 MB/s without the patch applied.
      Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
      Reviewed-by: default avatarIngo Molnar <mingo@elte.hu>
      Cc: Jeff Mahoney <jeffm@suse.com>
      Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
      Cc: Bron Gondwana <brong@fastmail.fm>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      LKML-Reference: <1239070789-13354-1-git-send-email-fweisbec@gmail.com>
      Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>