aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier González <javier@javigon.com>2018-06-01 10:41:14 -0400
committerJens Axboe <axboe@kernel.dk>2018-06-01 11:02:53 -0400
commit9cfd5a95381e960bdbc5cd24ec7987205a3a9bee (patch)
treeeeeae46b5f4f72b3e6f174f12e3d1b885072c8f6
parentcc9c9a00b10eaf33abe1cece2c05ea34601af21b (diff)
lightnvm: pblk: take bitmap alloc. out of critical section
pblk allocates line bitmaps within the line lock unnecessarily. In order to take pressure out of the fast patch, allocate line bitmaps outside of this lock and refactor accordingly. Signed-off-by: Javier González <javier@cnexlabs.com> Signed-off-by: Matias Bjørling <mb@lightnvm.io> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/lightnvm/pblk-core.c97
1 files changed, 56 insertions, 41 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index a5750534efed..ed9cc977c8b3 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1067,6 +1067,25 @@ static int pblk_line_init_metadata(struct pblk *pblk, struct pblk_line *line,
1067 return 1; 1067 return 1;
1068} 1068}
1069 1069
1070static int pblk_line_alloc_bitmaps(struct pblk *pblk, struct pblk_line *line)
1071{
1072 struct pblk_line_meta *lm = &pblk->lm;
1073
1074 line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_KERNEL);
1075 if (!line->map_bitmap)
1076 return -ENOMEM;
1077
1078 /* will be initialized using bb info from map_bitmap */
1079 line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_KERNEL);
1080 if (!line->invalid_bitmap) {
1081 kfree(line->map_bitmap);
1082 line->map_bitmap = NULL;
1083 return -ENOMEM;
1084 }
1085
1086 return 0;
1087}
1088
1070/* For now lines are always assumed full lines. Thus, smeta former and current 1089/* For now lines are always assumed full lines. Thus, smeta former and current
1071 * lun bitmaps are omitted. 1090 * lun bitmaps are omitted.
1072 */ 1091 */
@@ -1171,18 +1190,7 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
1171{ 1190{
1172 struct pblk_line_meta *lm = &pblk->lm; 1191 struct pblk_line_meta *lm = &pblk->lm;
1173 int blk_in_line = atomic_read(&line->blk_in_line); 1192 int blk_in_line = atomic_read(&line->blk_in_line);
1174 int blk_to_erase, ret; 1193 int blk_to_erase;
1175
1176 line->map_bitmap = kzalloc(lm->sec_bitmap_len, GFP_ATOMIC);
1177 if (!line->map_bitmap)
1178 return -ENOMEM;
1179
1180 /* will be initialized using bb info from map_bitmap */
1181 line->invalid_bitmap = kmalloc(lm->sec_bitmap_len, GFP_ATOMIC);
1182 if (!line->invalid_bitmap) {
1183 ret = -ENOMEM;
1184 goto fail_free_map_bitmap;
1185 }
1186 1194
1187 /* Bad blocks do not need to be erased */ 1195 /* Bad blocks do not need to be erased */
1188 bitmap_copy(line->erase_bitmap, line->blk_bitmap, lm->blk_per_line); 1196 bitmap_copy(line->erase_bitmap, line->blk_bitmap, lm->blk_per_line);
@@ -1200,15 +1208,15 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
1200 } 1208 }
1201 1209
1202 if (blk_in_line < lm->min_blk_line) { 1210 if (blk_in_line < lm->min_blk_line) {
1203 ret = -EAGAIN; 1211 spin_unlock(&line->lock);
1204 goto fail_free_invalid_bitmap; 1212 return -EAGAIN;
1205 } 1213 }
1206 1214
1207 if (line->state != PBLK_LINESTATE_FREE) { 1215 if (line->state != PBLK_LINESTATE_FREE) {
1208 WARN(1, "pblk: corrupted line %d, state %d\n", 1216 WARN(1, "pblk: corrupted line %d, state %d\n",
1209 line->id, line->state); 1217 line->id, line->state);
1210 ret = -EINTR; 1218 spin_unlock(&line->lock);
1211 goto fail_free_invalid_bitmap; 1219 return -EINTR;
1212 } 1220 }
1213 1221
1214 line->state = PBLK_LINESTATE_OPEN; 1222 line->state = PBLK_LINESTATE_OPEN;
@@ -1222,16 +1230,6 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
1222 kref_init(&line->ref); 1230 kref_init(&line->ref);
1223 1231
1224 return 0; 1232 return 0;
1225
1226fail_free_invalid_bitmap:
1227 spin_unlock(&line->lock);
1228 kfree(line->invalid_bitmap);
1229 line->invalid_bitmap = NULL;
1230fail_free_map_bitmap:
1231 kfree(line->map_bitmap);
1232 line->map_bitmap = NULL;
1233
1234 return ret;
1235} 1233}
1236 1234
1237int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line) 1235int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line)
@@ -1251,13 +1249,16 @@ int pblk_line_recov_alloc(struct pblk *pblk, struct pblk_line *line)
1251 } 1249 }
1252 spin_unlock(&l_mg->free_lock); 1250 spin_unlock(&l_mg->free_lock);
1253 1251
1254 pblk_rl_free_lines_dec(&pblk->rl, line, true); 1252 ret = pblk_line_alloc_bitmaps(pblk, line);
1253 if (ret)
1254 return ret;
1255 1255
1256 if (!pblk_line_init_bb(pblk, line, 0)) { 1256 if (!pblk_line_init_bb(pblk, line, 0)) {
1257 list_add(&line->list, &l_mg->free_list); 1257 list_add(&line->list, &l_mg->free_list);
1258 return -EINTR; 1258 return -EINTR;
1259 } 1259 }
1260 1260
1261 pblk_rl_free_lines_dec(&pblk->rl, line, true);
1261 return 0; 1262 return 0;
1262} 1263}
1263 1264
@@ -1269,6 +1270,24 @@ void pblk_line_recov_close(struct pblk *pblk, struct pblk_line *line)
1269 line->emeta = NULL; 1270 line->emeta = NULL;
1270} 1271}
1271 1272
1273static void pblk_line_reinit(struct pblk_line *line)
1274{
1275 *line->vsc = cpu_to_le32(EMPTY_ENTRY);
1276
1277 line->map_bitmap = NULL;
1278 line->invalid_bitmap = NULL;
1279 line->smeta = NULL;
1280 line->emeta = NULL;
1281}
1282
1283void pblk_line_free(struct pblk_line *line)
1284{
1285 kfree(line->map_bitmap);
1286 kfree(line->invalid_bitmap);
1287
1288 pblk_line_reinit(line);
1289}
1290
1272struct pblk_line *pblk_line_get(struct pblk *pblk) 1291struct pblk_line *pblk_line_get(struct pblk *pblk)
1273{ 1292{
1274 struct pblk_line_mgmt *l_mg = &pblk->l_mg; 1293 struct pblk_line_mgmt *l_mg = &pblk->l_mg;
@@ -1335,11 +1354,14 @@ retry:
1335 return NULL; 1354 return NULL;
1336 } 1355 }
1337 1356
1357 retry_line->map_bitmap = line->map_bitmap;
1358 retry_line->invalid_bitmap = line->invalid_bitmap;
1338 retry_line->smeta = line->smeta; 1359 retry_line->smeta = line->smeta;
1339 retry_line->emeta = line->emeta; 1360 retry_line->emeta = line->emeta;
1340 retry_line->meta_line = line->meta_line; 1361 retry_line->meta_line = line->meta_line;
1341 1362
1342 pblk_line_free(line); 1363 pblk_line_reinit(line);
1364
1343 l_mg->data_line = retry_line; 1365 l_mg->data_line = retry_line;
1344 spin_unlock(&l_mg->free_lock); 1366 spin_unlock(&l_mg->free_lock);
1345 1367
@@ -1392,6 +1414,9 @@ struct pblk_line *pblk_line_get_first_data(struct pblk *pblk)
1392 } 1414 }
1393 spin_unlock(&l_mg->free_lock); 1415 spin_unlock(&l_mg->free_lock);
1394 1416
1417 if (pblk_line_alloc_bitmaps(pblk, line))
1418 return NULL;
1419
1395 if (pblk_line_erase(pblk, line)) { 1420 if (pblk_line_erase(pblk, line)) {
1396 line = pblk_line_retry(pblk, line); 1421 line = pblk_line_retry(pblk, line);
1397 if (!line) 1422 if (!line)
@@ -1536,6 +1561,9 @@ retry_erase:
1536 goto retry_erase; 1561 goto retry_erase;
1537 } 1562 }
1538 1563
1564 if (pblk_line_alloc_bitmaps(pblk, new))
1565 return NULL;
1566
1539retry_setup: 1567retry_setup:
1540 if (!pblk_line_init_metadata(pblk, new, cur)) { 1568 if (!pblk_line_init_metadata(pblk, new, cur)) {
1541 new = pblk_line_retry(pblk, new); 1569 new = pblk_line_retry(pblk, new);
@@ -1575,19 +1603,6 @@ out:
1575 return new; 1603 return new;
1576} 1604}
1577 1605
1578void pblk_line_free(struct pblk_line *line)
1579{
1580 kfree(line->map_bitmap);
1581 kfree(line->invalid_bitmap);
1582
1583 *line->vsc = cpu_to_le32(EMPTY_ENTRY);
1584
1585 line->map_bitmap = NULL;
1586 line->invalid_bitmap = NULL;
1587 line->smeta = NULL;
1588 line->emeta = NULL;
1589}
1590
1591static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line) 1606static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line)
1592{ 1607{
1593 struct pblk_line_mgmt *l_mg = &pblk->l_mg; 1608 struct pblk_line_mgmt *l_mg = &pblk->l_mg;