aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/pblk-init.c
diff options
context:
space:
mode:
authorJavier González <javier@javigon.com>2018-10-09 07:12:15 -0400
committerJens Axboe <axboe@kernel.dk>2018-10-09 10:25:08 -0400
commit766c8ceb16fce904d6b8985ca2c0a547e053d1d5 (patch)
tree36e7d365c27ed8c6173375b4ba59d5b6980dbdfa /drivers/lightnvm/pblk-init.c
parent8a57fc3823d08edb1661a06d9e0a8c2365ac561e (diff)
lightnvm: pblk: guarantee that backpointer is respected on writer stall
pblk's write buffer must guarantee that it respects the device's constrains for reads (i.e., mw_cunits). This is done by maintaining a backpointer that updates the L2P table as entries wrap up, making them point to the media instead of pointing to the write buffer. This mechanism can race in case that the write thread stalls, as the write pointer will protect the last written entry, thus disregarding the read constrains. This patch adds an extra check on wrap up, making sure that the threshold is respected at all times, preventing new entries to overwrite committed data, also in case of write thread stall. Reported-by: Heiner Litz <hlitz@ucsc.edu> Signed-off-by: Javier González <javier@cnexlabs.com> Reviewed-by: Heiner Litz <hlitz@ucsc.edu> Signed-off-by: Matias Bjørling <mb@lightnvm.io> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/lightnvm/pblk-init.c')
-rw-r--r--drivers/lightnvm/pblk-init.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index e5239aba806b..13822594647c 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -193,8 +193,9 @@ static int pblk_rwb_init(struct pblk *pblk)
193 struct nvm_tgt_dev *dev = pblk->dev; 193 struct nvm_tgt_dev *dev = pblk->dev;
194 struct nvm_geo *geo = &dev->geo; 194 struct nvm_geo *geo = &dev->geo;
195 unsigned long buffer_size; 195 unsigned long buffer_size;
196 int pgs_in_buffer; 196 int pgs_in_buffer, threshold;
197 197
198 threshold = geo->mw_cunits * geo->all_luns;
198 pgs_in_buffer = (max(geo->mw_cunits, geo->ws_opt) + geo->ws_opt) 199 pgs_in_buffer = (max(geo->mw_cunits, geo->ws_opt) + geo->ws_opt)
199 * geo->all_luns; 200 * geo->all_luns;
200 201
@@ -203,7 +204,7 @@ static int pblk_rwb_init(struct pblk *pblk)
203 else 204 else
204 buffer_size = pgs_in_buffer; 205 buffer_size = pgs_in_buffer;
205 206
206 return pblk_rb_init(&pblk->rwb, buffer_size, geo->csecs); 207 return pblk_rb_init(&pblk->rwb, buffer_size, threshold, geo->csecs);
207} 208}
208 209
209/* Minimum pages needed within a lun */ 210/* Minimum pages needed within a lun */