btrfs: Fix busyloops in transaction waiting code
authorJan Kara <jack@suse.cz>
Thu, 26 Jan 2012 20:01:11 +0000 (15:01 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 26 Jan 2012 20:01:11 +0000 (15:01 -0500)
wait_log_commit() and wait_for_writer() were using slightly different
conditions for deciding whether they should call schedule() and whether they
should continue in the wait loop. Thus it could happen that we busylooped when
the first condition was not true while the second one was. That is burning CPU
cycles needlessly and is deadly on UP machines...

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/tree-log.c

index cb877e0886a71b80e0f44f60e0d884f57203a597..966cc74f5d6c7303b06bb8bd067826f07510ffc8 100644 (file)
@@ -1957,7 +1957,8 @@ static int wait_log_commit(struct btrfs_trans_handle *trans,
 
                finish_wait(&root->log_commit_wait[index], &wait);
                mutex_lock(&root->log_mutex);
-       } while (root->log_transid < transid + 2 &&
+       } while (root->fs_info->last_trans_log_full_commit !=
+                trans->transid && root->log_transid < transid + 2 &&
                 atomic_read(&root->log_commit[index]));
        return 0;
 }
@@ -1966,7 +1967,8 @@ static int wait_for_writer(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root)
 {
        DEFINE_WAIT(wait);
-       while (atomic_read(&root->log_writers)) {
+       while (root->fs_info->last_trans_log_full_commit !=
+              trans->transid && atomic_read(&root->log_writers)) {
                prepare_to_wait(&root->log_writer_wait,
                                &wait, TASK_UNINTERRUPTIBLE);
                mutex_unlock(&root->log_mutex);