aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm/pblk-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lightnvm/pblk-core.c')
-rw-r--r--drivers/lightnvm/pblk-core.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 08d166ac4f3c..0a41fb998d55 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1460,10 +1460,8 @@ void pblk_line_free(struct pblk *pblk, struct pblk_line *line)
1460 line->emeta = NULL; 1460 line->emeta = NULL;
1461} 1461}
1462 1462
1463void pblk_line_put(struct kref *ref) 1463static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line)
1464{ 1464{
1465 struct pblk_line *line = container_of(ref, struct pblk_line, ref);
1466 struct pblk *pblk = line->pblk;
1467 struct pblk_line_mgmt *l_mg = &pblk->l_mg; 1465 struct pblk_line_mgmt *l_mg = &pblk->l_mg;
1468 1466
1469 spin_lock(&line->lock); 1467 spin_lock(&line->lock);
@@ -1481,6 +1479,43 @@ void pblk_line_put(struct kref *ref)
1481 pblk_rl_free_lines_inc(&pblk->rl, line); 1479 pblk_rl_free_lines_inc(&pblk->rl, line);
1482} 1480}
1483 1481
1482static void pblk_line_put_ws(struct work_struct *work)
1483{
1484 struct pblk_line_ws *line_put_ws = container_of(work,
1485 struct pblk_line_ws, ws);
1486 struct pblk *pblk = line_put_ws->pblk;
1487 struct pblk_line *line = line_put_ws->line;
1488
1489 __pblk_line_put(pblk, line);
1490 mempool_free(line_put_ws, pblk->gen_ws_pool);
1491}
1492
1493void pblk_line_put(struct kref *ref)
1494{
1495 struct pblk_line *line = container_of(ref, struct pblk_line, ref);
1496 struct pblk *pblk = line->pblk;
1497
1498 __pblk_line_put(pblk, line);
1499}
1500
1501void pblk_line_put_wq(struct kref *ref)
1502{
1503 struct pblk_line *line = container_of(ref, struct pblk_line, ref);
1504 struct pblk *pblk = line->pblk;
1505 struct pblk_line_ws *line_put_ws;
1506
1507 line_put_ws = mempool_alloc(pblk->gen_ws_pool, GFP_ATOMIC);
1508 if (!line_put_ws)
1509 return;
1510
1511 line_put_ws->pblk = pblk;
1512 line_put_ws->line = line;
1513 line_put_ws->priv = NULL;
1514
1515 INIT_WORK(&line_put_ws->ws, pblk_line_put_ws);
1516 queue_work(pblk->r_end_wq, &line_put_ws->ws);
1517}
1518
1484int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa) 1519int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa)
1485{ 1520{
1486 struct nvm_rq *rqd; 1521 struct nvm_rq *rqd;
@@ -1878,8 +1913,19 @@ void pblk_lookup_l2p_seq(struct pblk *pblk, struct ppa_addr *ppas,
1878 int i; 1913 int i;
1879 1914
1880 spin_lock(&pblk->trans_lock); 1915 spin_lock(&pblk->trans_lock);
1881 for (i = 0; i < nr_secs; i++) 1916 for (i = 0; i < nr_secs; i++) {
1882 ppas[i] = pblk_trans_map_get(pblk, blba + i); 1917 struct ppa_addr ppa;
1918
1919 ppa = ppas[i] = pblk_trans_map_get(pblk, blba + i);
1920
1921 /* If the L2P entry maps to a line, the reference is valid */
1922 if (!pblk_ppa_empty(ppa) && !pblk_addr_in_cache(ppa)) {
1923 int line_id = pblk_dev_ppa_to_line(ppa);
1924 struct pblk_line *line = &pblk->lines[line_id];
1925
1926 kref_get(&line->ref);
1927 }
1928 }
1883 spin_unlock(&pblk->trans_lock); 1929 spin_unlock(&pblk->trans_lock);
1884} 1930}
1885 1931