1 |
From a615cca1e1cc5d94a4da1fb60d0e4acfd621909f Mon Sep 17 00:00:00 2001 |
2 |
From: =?UTF-8?q?Javier=20Gonz=C3=A1lez?= <javier@javigon.com> |
3 |
Date: Tue, 9 Oct 2018 13:11:35 +0200 |
4 |
Subject: [PATCH 016/145] lightnvm: pblk: fix race condition on metadata I/O |
5 |
MIME-Version: 1.0 |
6 |
Content-Type: text/plain; charset=UTF-8 |
7 |
Content-Transfer-Encoding: 8bit |
8 |
|
9 |
[ Upstream commit d8adaa3b86324c6186d0adf74bc256bdacfffdb6 ] |
10 |
|
11 |
In pblk, when a new line is allocated, metadata for the previously |
12 |
written line is scheduled. This is done through a fixed memory region |
13 |
that is shared through time and contexts across different lines and |
14 |
therefore protected by a lock. Unfortunately, this lock is not properly |
15 |
covering all the metadata used for sharing this memory regions, |
16 |
resulting in a race condition. |
17 |
|
18 |
This patch fixes this race condition by protecting this metadata |
19 |
properly. |
20 |
|
21 |
Fixes: dd2a43437337 ("lightnvm: pblk: sched. metadata on write thread") |
22 |
Signed-off-by: Javier González <javier@cnexlabs.com> |
23 |
Signed-off-by: Matias Bjørling <mb@lightnvm.io> |
24 |
Signed-off-by: Jens Axboe <axboe@kernel.dk> |
25 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
26 |
--- |
27 |
drivers/lightnvm/pblk-write.c | 14 +++++++------- |
28 |
1 file changed, 7 insertions(+), 7 deletions(-) |
29 |
|
30 |
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c |
31 |
index ee774a86cf1e..879227d584e7 100644 |
32 |
--- a/drivers/lightnvm/pblk-write.c |
33 |
+++ b/drivers/lightnvm/pblk-write.c |
34 |
@@ -417,12 +417,11 @@ int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line) |
35 |
rqd->ppa_list[i] = addr_to_gen_ppa(pblk, paddr, id); |
36 |
} |
37 |
|
38 |
+ spin_lock(&l_mg->close_lock); |
39 |
emeta->mem += rq_len; |
40 |
- if (emeta->mem >= lm->emeta_len[0]) { |
41 |
- spin_lock(&l_mg->close_lock); |
42 |
+ if (emeta->mem >= lm->emeta_len[0]) |
43 |
list_del(&meta_line->list); |
44 |
- spin_unlock(&l_mg->close_lock); |
45 |
- } |
46 |
+ spin_unlock(&l_mg->close_lock); |
47 |
|
48 |
pblk_down_page(pblk, rqd->ppa_list, rqd->nr_ppas); |
49 |
|
50 |
@@ -491,14 +490,15 @@ static struct pblk_line *pblk_should_submit_meta_io(struct pblk *pblk, |
51 |
struct pblk_line *meta_line; |
52 |
|
53 |
spin_lock(&l_mg->close_lock); |
54 |
-retry: |
55 |
if (list_empty(&l_mg->emeta_list)) { |
56 |
spin_unlock(&l_mg->close_lock); |
57 |
return NULL; |
58 |
} |
59 |
meta_line = list_first_entry(&l_mg->emeta_list, struct pblk_line, list); |
60 |
- if (meta_line->emeta->mem >= lm->emeta_len[0]) |
61 |
- goto retry; |
62 |
+ if (meta_line->emeta->mem >= lm->emeta_len[0]) { |
63 |
+ spin_unlock(&l_mg->close_lock); |
64 |
+ return NULL; |
65 |
+ } |
66 |
spin_unlock(&l_mg->close_lock); |
67 |
|
68 |
if (!pblk_valid_meta_ppa(pblk, meta_line, data_rqd)) |
69 |
-- |
70 |
2.19.1 |
71 |
|