Skip to content

Commit d8adaa3

Browse files
javigonaxboe
authored andcommitted
lightnvm: pblk: fix race condition on metadata I/O
In pblk, when a new line is allocated, metadata for the previously written line is scheduled. This is done through a fixed memory region that is shared through time and contexts across different lines and therefore protected by a lock. Unfortunately, this lock is not properly covering all the metadata used for sharing this memory regions, resulting in a race condition. This patch fixes this race condition by protecting this metadata properly. Fixes: dd2a434 ("lightnvm: pblk: sched. metadata on write thread") Signed-off-by: Javier González <[email protected]> Signed-off-by: Matias Bjørling <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 656e33c commit d8adaa3

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

drivers/lightnvm/pblk-write.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -417,12 +417,11 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line)
417417
rqd->ppa_list[i] = addr_to_gen_ppa(pblk, paddr, id);
418418
}
419419

420+
spin_lock(&l_mg->close_lock);
420421
emeta->mem += rq_len;
421-
if (emeta->mem >= lm->emeta_len[0]) {
422-
spin_lock(&l_mg->close_lock);
422+
if (emeta->mem >= lm->emeta_len[0])
423423
list_del(&meta_line->list);
424-
spin_unlock(&l_mg->close_lock);
425-
}
424+
spin_unlock(&l_mg->close_lock);
426425

427426
pblk_down_page(pblk, rqd->ppa_list, rqd->nr_ppas);
428427

@@ -491,14 +490,15 @@ static struct pblk_line *pblk_should_submit_meta_io(struct pblk *pblk,
491490
struct pblk_line *meta_line;
492491

493492
spin_lock(&l_mg->close_lock);
494-
retry:
495493
if (list_empty(&l_mg->emeta_list)) {
496494
spin_unlock(&l_mg->close_lock);
497495
return NULL;
498496
}
499497
meta_line = list_first_entry(&l_mg->emeta_list, struct pblk_line, list);
500-
if (meta_line->emeta->mem >= lm->emeta_len[0])
501-
goto retry;
498+
if (meta_line->emeta->mem >= lm->emeta_len[0]) {
499+
spin_unlock(&l_mg->close_lock);
500+
return NULL;
501+
}
502502
spin_unlock(&l_mg->close_lock);
503503

504504
if (!pblk_valid_meta_ppa(pblk, meta_line, data_rqd))

0 commit comments

Comments
 (0)