aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-11-06 17:50:21 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-11-06 17:50:21 -0500
commitfb68407b0d9efba962c03f55009c797e22f024bc (patch)
treeb3f33f513969d6f77c5b6a6f71b662057d3440a5
parentc3a326a657562dab81acf05aee106dc1fe345eb4 (diff)
jbd2: Call journal commit callback without holding j_list_lock
Avoid freeing the transaction in __jbd2_journal_drop_transaction() so the journal commit callback can run without holding j_list_lock, to avoid lock contention on this spinlock. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/jbd2/checkpoint.c2
-rw-r--r--fs/jbd2/commit.c13
-rw-r--r--include/linux/jbd2.h4
3 files changed, 11 insertions, 8 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index adc08ec875ed..17159cacbd9e 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -682,6 +682,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
682 safely remove this transaction from the log */ 682 safely remove this transaction from the log */
683 683
684 __jbd2_journal_drop_transaction(journal, transaction); 684 __jbd2_journal_drop_transaction(journal, transaction);
685 kfree(transaction);
685 686
686 /* Just in case anybody was waiting for more transactions to be 687 /* Just in case anybody was waiting for more transactions to be
687 checkpointed... */ 688 checkpointed... */
@@ -756,5 +757,4 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transact
756 J_ASSERT(journal->j_running_transaction != transaction); 757 J_ASSERT(journal->j_running_transaction != transaction);
757 758
758 jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid); 759 jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
759 kfree(transaction);
760} 760}
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index f22d1828ea85..0ad84162c425 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -363,7 +363,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
363 int space_left = 0; 363 int space_left = 0;
364 int first_tag = 0; 364 int first_tag = 0;
365 int tag_flag; 365 int tag_flag;
366 int i; 366 int i, to_free = 0;
367 int tag_bytes = journal_tag_bytes(journal); 367 int tag_bytes = journal_tag_bytes(journal);
368 struct buffer_head *cbh = NULL; /* For transactional checksums */ 368 struct buffer_head *cbh = NULL; /* For transactional checksums */
369 __u32 crc32_sum = ~0; 369 __u32 crc32_sum = ~0;
@@ -1011,12 +1011,10 @@ restart_loop:
1011 journal->j_average_commit_time = commit_time; 1011 journal->j_average_commit_time = commit_time;
1012 spin_unlock(&journal->j_state_lock); 1012 spin_unlock(&journal->j_state_lock);
1013 1013
1014 if (journal->j_commit_callback)
1015 journal->j_commit_callback(journal, commit_transaction);
1016
1017 if (commit_transaction->t_checkpoint_list == NULL && 1014 if (commit_transaction->t_checkpoint_list == NULL &&
1018 commit_transaction->t_checkpoint_io_list == NULL) { 1015 commit_transaction->t_checkpoint_io_list == NULL) {
1019 __jbd2_journal_drop_transaction(journal, commit_transaction); 1016 __jbd2_journal_drop_transaction(journal, commit_transaction);
1017 to_free = 1;
1020 } else { 1018 } else {
1021 if (journal->j_checkpoint_transactions == NULL) { 1019 if (journal->j_checkpoint_transactions == NULL) {
1022 journal->j_checkpoint_transactions = commit_transaction; 1020 journal->j_checkpoint_transactions = commit_transaction;
@@ -1035,11 +1033,16 @@ restart_loop:
1035 } 1033 }
1036 spin_unlock(&journal->j_list_lock); 1034 spin_unlock(&journal->j_list_lock);
1037 1035
1036 if (journal->j_commit_callback)
1037 journal->j_commit_callback(journal, commit_transaction);
1038
1038 trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", 1039 trace_mark(jbd2_end_commit, "dev %s transaction %d head %d",
1039 journal->j_devname, journal->j_commit_sequence, 1040 journal->j_devname, commit_transaction->t_tid,
1040 journal->j_tail_sequence); 1041 journal->j_tail_sequence);
1041 jbd_debug(1, "JBD: commit %d complete, head %d\n", 1042 jbd_debug(1, "JBD: commit %d complete, head %d\n",
1042 journal->j_commit_sequence, journal->j_tail_sequence); 1043 journal->j_commit_sequence, journal->j_tail_sequence);
1044 if (to_free)
1045 kfree(commit_transaction);
1043 1046
1044 wake_up(&journal->j_wait_done_commit); 1047 wake_up(&journal->j_wait_done_commit);
1045} 1048}
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 004c9a8d63ed..9d82084a1605 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1179,8 +1179,8 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
1179int jbd2_log_do_checkpoint(journal_t *journal); 1179int jbd2_log_do_checkpoint(journal_t *journal);
1180 1180
1181void __jbd2_log_wait_for_space(journal_t *journal); 1181void __jbd2_log_wait_for_space(journal_t *journal);
1182extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); 1182extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
1183extern int jbd2_cleanup_journal_tail(journal_t *); 1183extern int jbd2_cleanup_journal_tail(journal_t *);
1184 1184
1185/* Debugging code only: */ 1185/* Debugging code only: */
1186 1186