Commit 4ca88524 authored by Igor Konopko's avatar Igor Konopko Committed by Jens Axboe
Browse files

lightnvm: pblk: fix race during put line



In the pblk_put_line_back function, a race condition with
__pblk_map_invalidate can make a line not part of any lists.

Fix gc_list by resetting it to null fixes the above issue.

Fixes: a4bd217b ("lightnvm: physical block device (pblk) target")
Signed-off-by: default avatarIgor Konopko <igor.j.konopko@intel.com>
Reviewed-by: default avatarJavier González <javier@javigon.com>
Reviewed-by: default avatarHans Holmberg <hans.holmberg@cnexlabs.com>
Signed-off-by: default avatarMatias Bjørling <mb@lightnvm.io>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d378561b
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -64,20 +64,24 @@ static void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line)
	struct pblk_line_mgmt *l_mg = &pblk->l_mg;
	struct list_head *move_list;

	spin_lock(&l_mg->gc_lock);
	spin_lock(&line->lock);
	WARN_ON(line->state != PBLK_LINESTATE_GC);
	line->state = PBLK_LINESTATE_CLOSED;
	trace_pblk_line_state(pblk_disk_name(pblk), line->id,
					line->state);

	/* We need to reset gc_group in order to ensure that
	 * pblk_line_gc_list will return proper move_list
	 * since right now current line is not on any of the
	 * gc lists.
	 */
	line->gc_group = PBLK_LINEGC_NONE;
	move_list = pblk_line_gc_list(pblk, line);
	spin_unlock(&line->lock);

	if (move_list) {
		spin_lock(&l_mg->gc_lock);
	list_add_tail(&line->list, move_list);
	spin_unlock(&l_mg->gc_lock);
}
}

static void pblk_gc_line_ws(struct work_struct *work)
{