Commit 3c05ef11 authored by Hans Holmberg's avatar Hans Holmberg Committed by Jens Axboe

lightnvm: pblk: prevent race in pblk_rb_flush_point_set

Make sure that we are not advancing the sync pointer while
we're adding bios to the write buffer entry completion list.

This race condition results in bios not completing and was identified
by a hang when running xfstest generic/113.
Signed-off-by: default avatarHans Holmberg <hans.holmberg@cnexlabs.com>
Reviewed-by: default avatarJavier González <javier@cnexlabs.com>
Signed-off-by: default avatarMatias Bjørling <mb@lightnvm.io>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent b966c50b
...@@ -355,10 +355,13 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio, ...@@ -355,10 +355,13 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio,
struct pblk_rb_entry *entry; struct pblk_rb_entry *entry;
unsigned int sync, flush_point; unsigned int sync, flush_point;
pblk_rb_sync_init(rb, NULL);
sync = READ_ONCE(rb->sync); sync = READ_ONCE(rb->sync);
if (pos == sync) if (pos == sync) {
pblk_rb_sync_end(rb, NULL);
return 0; return 0;
}
#ifdef CONFIG_NVM_DEBUG #ifdef CONFIG_NVM_DEBUG
atomic_inc(&rb->inflight_flush_point); atomic_inc(&rb->inflight_flush_point);
...@@ -367,8 +370,6 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio, ...@@ -367,8 +370,6 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio,
flush_point = (pos == 0) ? (rb->nr_entries - 1) : (pos - 1); flush_point = (pos == 0) ? (rb->nr_entries - 1) : (pos - 1);
entry = &rb->entries[flush_point]; entry = &rb->entries[flush_point];
pblk_rb_sync_init(rb, NULL);
/* Protect flush points */ /* Protect flush points */
smp_store_release(&rb->flush_point, flush_point); smp_store_release(&rb->flush_point, flush_point);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment