diff options
Diffstat (limited to 'drivers/lightnvm/pblk-core.c')
| -rw-r--r-- | drivers/lightnvm/pblk-core.c | 48 |
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 | ||
| 1747 | void pblk_update_map(struct pblk *pblk, sector_t lba, struct ppa_addr ppa) | 1747 | void 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 | ||
| 1778 | int pblk_update_map_gc(struct pblk *pblk, sector_t lba, struct ppa_addr ppa, | 1778 | int 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); |
| 1807 | out: | 1808 | out: |
| 1808 | spin_unlock(&pblk->trans_lock); | 1809 | spin_unlock(&pblk->trans_lock); |
| 1809 | return ret; | 1810 | return ret; |
| 1810 | } | 1811 | } |
| 1811 | 1812 | ||
| 1812 | void pblk_update_map_dev(struct pblk *pblk, sector_t lba, struct ppa_addr ppa, | 1813 | void 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); |
| 1853 | out: | 1855 | out: |
| 1854 | spin_unlock(&pblk->trans_lock); | 1856 | spin_unlock(&pblk->trans_lock); |
| 1855 | } | 1857 | } |
