Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e99d8eb authored by Chris Mason's avatar Chris Mason
Browse files

Btrfs: fix async worker startup race



After a new worker thread starts, it is placed into the
list of idle threads.  But, this may race with a
check for idle done by the worker thread itself, resulting
in a double list_add operation.

This fix adds a check to make sure the idle thread addition
is done properly.

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 83ebade3
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -74,7 +74,12 @@ static void check_idle_worker(struct btrfs_worker_thread *worker)
		unsigned long flags;
		spin_lock_irqsave(&worker->workers->lock, flags);
		worker->idle = 1;
		list_move(&worker->worker_list, &worker->workers->idle_list);

		/* the list may be empty if the worker is just starting */
		if (!list_empty(&worker->worker_list)) {
			list_move(&worker->worker_list,
				 &worker->workers->idle_list);
		}
		spin_unlock_irqrestore(&worker->workers->lock, flags);
	}
}
@@ -90,8 +95,11 @@ static void check_busy_worker(struct btrfs_worker_thread *worker)
		unsigned long flags;
		spin_lock_irqsave(&worker->workers->lock, flags);
		worker->idle = 0;

		if (!list_empty(&worker->worker_list)) {
			list_move_tail(&worker->worker_list,
				      &worker->workers->worker_list);
		}
		spin_unlock_irqrestore(&worker->workers->lock, flags);
	}
}