]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
lightnvm: pblk: prevent race in pblk_rb_flush_point_set
authorHans Holmberg <hans.holmberg@cnexlabs.com>
Thu, 29 Mar 2018 22:04:58 +0000 (00:04 +0200)
committerJens Axboe <axboe@kernel.dk>
Thu, 29 Mar 2018 23:29:09 +0000 (17:29 -0600)
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: Hans Holmberg <hans.holmberg@cnexlabs.com>
Reviewed-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/lightnvm/pblk-rb.c

index 8b1434060fb3bdfb9a905cabf2a18afd20424a89..52fdd85dbc972ec95c21b053bb87a21138170443 100644 (file)
@@ -355,10 +355,13 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio,
        struct pblk_rb_entry *entry;
        unsigned int sync, flush_point;
 
+       pblk_rb_sync_init(rb, NULL);
        sync = READ_ONCE(rb->sync);
 
-       if (pos == sync)
+       if (pos == sync) {
+               pblk_rb_sync_end(rb, NULL);
                return 0;
+       }
 
 #ifdef CONFIG_NVM_DEBUG
        atomic_inc(&rb->inflight_flush_point);
@@ -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);
        entry = &rb->entries[flush_point];
 
-       pblk_rb_sync_init(rb, NULL);
-
        /* Protect flush points */
        smp_store_release(&rb->flush_point, flush_point);