spin_unlock(&journal->j_state_lock);
del_timer_sync(journal->j_commit_timer);
journal_commit_transaction(journal);
-@@ -168,6 +172,27 @@ loop:
+@@ -168,6 +172,33 @@ loop:
}
wake_up(&journal->j_wait_done_commit);
+ * Do this after wake-up to reduce waiters latency.
+ */
+ spin_unlock(&journal->j_state_lock);
-+ down(&journal->j_checkpoint_sem);
-+ spin_lock(&journal->j_state_lock);
-+ while (__log_space_left(journal) <
-+ journal->j_max_transaction_buffers + 2 * transaction_size) {
-+ int result;
++ /*
++ * Trylock to avoid deadlock with threads waiting for commit under
++ * journal->j_checkpoint_sem.
++ */
++ if (!down_trylock(&journal->j_checkpoint_sem)) {
++ spin_lock(&journal->j_state_lock);
++ while (__log_space_left(journal) <
++ journal->j_max_transaction_buffers +
++ 2 * transaction_size) {
++ int result;
+
-+ spin_unlock(&journal->j_state_lock);
-+ result = log_do_checkpoint(journal);
-+ spin_lock(&journal->j_state_lock);
-+ if (result < 0)
-+ break;
++ spin_unlock(&journal->j_state_lock);
++ result = log_do_checkpoint(journal);
++ spin_lock(&journal->j_state_lock);
++ if (result < 0)
++ break;
++ }
++ up(&journal->j_checkpoint_sem);
+ }
-+ up(&journal->j_checkpoint_sem);
+
if (current->flags & PF_FREEZE) {
/*