jbd2: move lockdep tracking to journal_s
authorJan Kara <jack@suse.cz>
Thu, 30 Jun 2016 15:39:38 +0000 (11:39 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 30 Jun 2016 15:39:38 +0000 (11:39 -0400)
Currently lockdep map is tracked in each journal handle. To be able to
expand lockdep support to cover also other cases where we depend on
transaction commit and where handle is not available, move lockdep map
into struct journal_s. Since this makes the lockdep map shared for all
handles, we have to use rwsem_acquire_read() for acquisitions now.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/jbd2/journal.c
fs/jbd2/transaction.c
include/linux/jbd2.h

index b31852f76f46585137021df6266a18ba743b8528..208e4058040b65a3af7066596a27a0622830b317 100644 (file)
@@ -1091,6 +1091,7 @@ static void jbd2_stats_proc_exit(journal_t *journal)
 
 static journal_t * journal_init_common (void)
 {
+       static struct lock_class_key jbd2_trans_commit_key;
        journal_t *journal;
        int err;
 
@@ -1126,6 +1127,9 @@ static journal_t * journal_init_common (void)
 
        spin_lock_init(&journal->j_history_lock);
 
+       lockdep_init_map(&journal->j_trans_commit_map, "jbd2_handle",
+                        &jbd2_trans_commit_key, 0);
+
        return journal;
 }
 
index 41249538c0472f6ab4cd3afa3ec4c17c9836f2fa..c0065040c5bebe13f877f7c48768663978d45439 100644 (file)
@@ -382,13 +382,11 @@ repeat:
        read_unlock(&journal->j_state_lock);
        current->journal_info = handle;
 
-       lock_map_acquire(&handle->h_lockdep_map);
+       rwsem_acquire_read(&journal->j_trans_commit_map, 0, 0, _THIS_IP_);
        jbd2_journal_free_transaction(new_transaction);
        return 0;
 }
 
-static struct lock_class_key jbd2_handle_key;
-
 /* Allocate a new handle.  This should probably be in a slab... */
 static handle_t *new_handle(int nblocks)
 {
@@ -398,9 +396,6 @@ static handle_t *new_handle(int nblocks)
        handle->h_buffer_credits = nblocks;
        handle->h_ref = 1;
 
-       lockdep_init_map(&handle->h_lockdep_map, "jbd2_handle",
-                                               &jbd2_handle_key, 0);
-
        return handle;
 }
 
@@ -672,7 +667,7 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask)
        if (need_to_start)
                jbd2_log_start_commit(journal, tid);
 
-       lock_map_release(&handle->h_lockdep_map);
+       rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
        handle->h_buffer_credits = nblocks;
        ret = start_this_handle(journal, handle, gfp_mask);
        return ret;
@@ -1750,7 +1745,7 @@ int jbd2_journal_stop(handle_t *handle)
                        wake_up(&journal->j_wait_transaction_locked);
        }
 
-       lock_map_release(&handle->h_lockdep_map);
+       rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
 
        if (wait_for_commit)
                err = jbd2_log_wait_commit(journal, tid);
index efb232c5f66867851053da799c83428e576ebb57..3d210cbe4e1b905f99d6780659ec88cda5d927c1 100644 (file)
@@ -491,10 +491,6 @@ struct jbd2_journal_handle
 
        unsigned long           h_start_jiffies;
        unsigned int            h_requested_credits;
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-       struct lockdep_map      h_lockdep_map;
-#endif
 };
 
 
@@ -793,6 +789,7 @@ jbd2_time_diff(unsigned long start, unsigned long end)
  * @j_proc_entry: procfs entry for the jbd statistics directory
  * @j_stats: Overall statistics
  * @j_private: An opaque pointer to fs-private information.
+ * @j_trans_commit_map: Lockdep entity to track transaction commit dependencies
  */
 
 struct journal_s
@@ -1035,6 +1032,18 @@ struct journal_s
 
        /* Precomputed journal UUID checksum for seeding other checksums */
        __u32 j_csum_seed;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       /*
+        * Lockdep entity to track transaction commit dependencies. Handles
+        * hold this "lock" for read, when we wait for commit, we acquire the
+        * "lock" for writing. This matches the properties of jbd2 journalling
+        * where the running transaction has to wait for all handles to be
+        * dropped to commit that transaction and also acquiring a handle may
+        * require transaction commit to finish.
+        */
+       struct lockdep_map      j_trans_commit_map;
+#endif
 };
 
 /* journal feature predicate functions */