add patch add-missing-brelse-on-set_flex_bg_block_bitmap_error_path
[ext4-patch-queue.git] / avoid-long-hold-times
blob93bb60c2d6a7c768422b46a42c7743d2f1284fa3
1 jbd2: avoid long hold times of j_state_lock while committing a transaction
3 From: Jan Kara <jack@suse.cz>
5 We can hold j_state_lock for writing at the beginning of
6 jbd2_journal_commit_transaction() for a rather long time (reportedly
7 for 30 ms) due cleaning revoke bits of all revoked buffers under
8 it. The handling of revoke tables as well as cleaning of
9 t_reserved_list, and checkpoint lists does not need j_state_lock for
10 anything. Furthermore the transaction is in T_LOCKED state and we
11 waited for all outstanding handles so nobody is going to be adding
12 anything to the transaction.
14 Just drop the lock for unnecessary operations.
16 Reported-and-tested-by: Adrian Hunter <adrian.hunter@intel.com>
17 Signed-off-by: Jan Kara <jack@suse.cz>
18 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
19 ---
20  fs/jbd2/commit.c | 4 ++--
21  1 file changed, 2 insertions(+), 2 deletions(-)
23 diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
24 index 150cc030b4d7..356b75fa3101 100644
25 --- a/fs/jbd2/commit.c
26 +++ b/fs/jbd2/commit.c
27 @@ -422,6 +422,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
28                                        stats.run.rs_locked);
29         stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
30                                               stats.run.rs_locked);
31 +       write_unlock(&journal->j_state_lock);
33         spin_lock(&commit_transaction->t_handle_lock);
34         while (atomic_read(&commit_transaction->t_updates)) {
35 @@ -431,9 +432,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
36                                         TASK_UNINTERRUPTIBLE);
37                 if (atomic_read(&commit_transaction->t_updates)) {
38                         spin_unlock(&commit_transaction->t_handle_lock);
39 -                       write_unlock(&journal->j_state_lock);
40                         schedule();
41 -                       write_lock(&journal->j_state_lock);
42                         spin_lock(&commit_transaction->t_handle_lock);
43                 }
44                 finish_wait(&journal->j_wait_updates, &wait);
45 @@ -505,6 +504,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
46         atomic_sub(atomic_read(&journal->j_reserved_credits),
47                    &commit_transaction->t_outstanding_credits);
49 +       write_lock(&journal->j_state_lock);
50         trace_jbd2_commit_flushing(journal, commit_transaction);
51         stats.run.rs_flushing = jiffies;
52         stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
53 -- 
54 2.16.4