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.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 0da58869006b..b6d7c6660149 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1746,7 +1746,7 @@ void pblk_up_rq(struct pblk *pblk, struct ppa_addr *ppa_list, int nr_ppas,
1746 1746
1747void pblk_update_map(struct pblk *pblk, sector_t lba, struct ppa_addr ppa) 1747void pblk_update_map(struct pblk *pblk, sector_t lba, struct ppa_addr ppa)
1748{ 1748{
1749 struct ppa_addr l2p_ppa; 1749 struct ppa_addr ppa_l2p;
1750 1750
1751 /* logic error: lba out-of-bounds. Ignore update */ 1751 /* logic error: lba out-of-bounds. Ignore update */
1752 if (!(lba < pblk->rl.nr_secs)) { 1752 if (!(lba < pblk->rl.nr_secs)) {
@@ -1755,10 +1755,10 @@ void pblk_update_map(struct pblk *pblk, sector_t lba, struct ppa_addr ppa)
1755 } 1755 }
1756 1756
1757 spin_lock(&pblk->trans_lock); 1757 spin_lock(&pblk->trans_lock);
1758 l2p_ppa = pblk_trans_map_get(pblk, lba); 1758 ppa_l2p = pblk_trans_map_get(pblk, lba);
1759 1759
1760 if (!pblk_addr_in_cache(l2p_ppa) && !pblk_ppa_empty(l2p_ppa)) 1760 if (!pblk_addr_in_cache(ppa_l2p) && !pblk_ppa_empty(ppa_l2p))
1761 pblk_map_invalidate(pblk, l2p_ppa); 1761 pblk_map_invalidate(pblk, ppa_l2p);
1762 1762
1763 pblk_trans_map_set(pblk, lba, ppa); 1763 pblk_trans_map_set(pblk, lba, ppa);
1764 spin_unlock(&pblk->trans_lock); 1764 spin_unlock(&pblk->trans_lock);
@@ -1775,16 +1775,16 @@ void pblk_update_map_cache(struct pblk *pblk, sector_t lba, struct ppa_addr ppa)
1775 pblk_update_map(pblk, lba, ppa); 1775 pblk_update_map(pblk, lba, ppa);
1776} 1776}
1777 1777
1778int pblk_update_map_gc(struct pblk *pblk, sector_t lba, struct ppa_addr ppa, 1778int pblk_update_map_gc(struct pblk *pblk, sector_t lba, struct ppa_addr ppa_new,
1779 struct pblk_line *gc_line) 1779 struct pblk_line *gc_line)
1780{ 1780{
1781 struct ppa_addr l2p_ppa; 1781 struct ppa_addr ppa_l2p;
1782 int ret = 1; 1782 int ret = 1;
1783 1783
1784#ifdef CONFIG_NVM_DEBUG 1784#ifdef CONFIG_NVM_DEBUG
1785 /* Callers must ensure that the ppa points to a cache address */ 1785 /* Callers must ensure that the ppa points to a cache address */
1786 BUG_ON(!pblk_addr_in_cache(ppa)); 1786 BUG_ON(!pblk_addr_in_cache(ppa_new));
1787 BUG_ON(pblk_rb_pos_oob(&pblk->rwb, pblk_addr_to_cacheline(ppa))); 1787 BUG_ON(pblk_rb_pos_oob(&pblk->rwb, pblk_addr_to_cacheline(ppa_new)));
1788#endif 1788#endif
1789 1789
1790 /* logic error: lba out-of-bounds. Ignore update */ 1790 /* logic error: lba out-of-bounds. Ignore update */
@@ -1794,36 +1794,38 @@ int pblk_update_map_gc(struct pblk *pblk, sector_t lba, struct ppa_addr ppa,
1794 } 1794 }
1795 1795
1796 spin_lock(&pblk->trans_lock); 1796 spin_lock(&pblk->trans_lock);
1797 l2p_ppa = pblk_trans_map_get(pblk, lba); 1797 ppa_l2p = pblk_trans_map_get(pblk, lba);
1798 1798
1799 /* Prevent updated entries to be overwritten by GC */ 1799 /* Prevent updated entries to be overwritten by GC */
1800 if (pblk_addr_in_cache(l2p_ppa) || pblk_ppa_empty(l2p_ppa) || 1800 if (pblk_addr_in_cache(ppa_l2p) || pblk_ppa_empty(ppa_l2p) ||
1801 pblk_tgt_ppa_to_line(l2p_ppa) != gc_line->id) { 1801 pblk_tgt_ppa_to_line(ppa_l2p) != gc_line->id) {
1802
1802 ret = 0; 1803 ret = 0;
1803 goto out; 1804 goto out;
1804 } 1805 }
1805 1806
1806 pblk_trans_map_set(pblk, lba, ppa); 1807 pblk_trans_map_set(pblk, lba, ppa_new);
1807out: 1808out:
1808 spin_unlock(&pblk->trans_lock); 1809 spin_unlock(&pblk->trans_lock);
1809 return ret; 1810 return ret;
1810} 1811}
1811 1812
1812void pblk_update_map_dev(struct pblk *pblk, sector_t lba, struct ppa_addr ppa, 1813void pblk_update_map_dev(struct pblk *pblk, sector_t lba,
1813 struct ppa_addr entry_line) 1814 struct ppa_addr ppa_mapped, struct ppa_addr ppa_cache)
1814{ 1815{
1815 struct ppa_addr l2p_line; 1816 struct ppa_addr ppa_l2p;
1816 1817
1817#ifdef CONFIG_NVM_DEBUG 1818#ifdef CONFIG_NVM_DEBUG
1818 /* Callers must ensure that the ppa points to a device address */ 1819 /* Callers must ensure that the ppa points to a device address */
1819 BUG_ON(pblk_addr_in_cache(ppa)); 1820 BUG_ON(pblk_addr_in_cache(ppa_mapped));
1820#endif 1821#endif
1821 /* Invalidate and discard padded entries */ 1822 /* Invalidate and discard padded entries */
1822 if (lba == ADDR_EMPTY) { 1823 if (lba == ADDR_EMPTY) {
1823#ifdef CONFIG_NVM_DEBUG 1824#ifdef CONFIG_NVM_DEBUG
1824 atomic_long_inc(&pblk->padded_wb); 1825 atomic_long_inc(&pblk->padded_wb);
1825#endif 1826#endif
1826 pblk_map_invalidate(pblk, ppa); 1827 if (!pblk_ppa_empty(ppa_mapped))
1828 pblk_map_invalidate(pblk, ppa_mapped);
1827 return; 1829 return;
1828 } 1830 }
1829 1831
@@ -1834,22 +1836,22 @@ void pblk_update_map_dev(struct pblk *pblk, sector_t lba, struct ppa_addr ppa,
1834 } 1836 }
1835 1837
1836 spin_lock(&pblk->trans_lock); 1838 spin_lock(&pblk->trans_lock);
1837 l2p_line = pblk_trans_map_get(pblk, lba); 1839 ppa_l2p = pblk_trans_map_get(pblk, lba);
1838 1840
1839 /* Do not update L2P if the cacheline has been updated. In this case, 1841 /* Do not update L2P if the cacheline has been updated. In this case,
1840 * the mapped ppa must be invalidated 1842 * the mapped ppa must be invalidated
1841 */ 1843 */
1842 if (l2p_line.ppa != entry_line.ppa) { 1844 if (!pblk_ppa_comp(ppa_l2p, ppa_cache)) {
1843 if (!pblk_ppa_empty(ppa)) 1845 if (!pblk_ppa_empty(ppa_mapped))
1844 pblk_map_invalidate(pblk, ppa); 1846 pblk_map_invalidate(pblk, ppa_mapped);
1845 goto out; 1847 goto out;
1846 } 1848 }
1847 1849
1848#ifdef CONFIG_NVM_DEBUG 1850#ifdef CONFIG_NVM_DEBUG
1849 WARN_ON(!pblk_addr_in_cache(l2p_line) && !pblk_ppa_empty(l2p_line)); 1851 WARN_ON(!pblk_addr_in_cache(ppa_l2p) && !pblk_ppa_empty(ppa_l2p));
1850#endif 1852#endif
1851 1853
1852 pblk_trans_map_set(pblk, lba, ppa); 1854 pblk_trans_map_set(pblk, lba, ppa_mapped);
1853out: 1855out:
1854 spin_unlock(&pblk->trans_lock); 1856 spin_unlock(&pblk->trans_lock);
1855} 1857}