lkml.org 
[lkml]   [2022]   [Apr]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 6/7] pmem: refactor pmem_clear_poison()
    Date
    Refactor the pmem_clear_poison() function such that the common
    shared code between the typical write path and the recovery write
    path is factored out.

    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Dan Williams <dan.j.williams@intel.com>
    Signed-off-by: Jane Chu <jane.chu@oracle.com>
    ---
    drivers/nvdimm/pmem.c | 73 ++++++++++++++++++++++++++++---------------
    1 file changed, 48 insertions(+), 25 deletions(-)

    diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
    index 3c0cad38ec33..c3772304d417 100644
    --- a/drivers/nvdimm/pmem.c
    +++ b/drivers/nvdimm/pmem.c
    @@ -45,9 +45,25 @@ static struct nd_region *to_region(struct pmem_device *pmem)
    return to_nd_region(to_dev(pmem)->parent);
    }

    -static void hwpoison_clear(struct pmem_device *pmem,
    - phys_addr_t phys, unsigned int len)
    +static phys_addr_t to_phys(struct pmem_device *pmem, phys_addr_t offset)
    {
    + return pmem->phys_addr + offset;
    +}
    +
    +static sector_t to_sect(struct pmem_device *pmem, phys_addr_t offset)
    +{
    + return (offset - pmem->data_offset) >> SECTOR_SHIFT;
    +}
    +
    +static phys_addr_t to_offset(struct pmem_device *pmem, sector_t sector)
    +{
    + return (sector << SECTOR_SHIFT) + pmem->data_offset;
    +}
    +
    +static void pmem_mkpage_present(struct pmem_device *pmem, phys_addr_t offset,
    + unsigned int len)
    +{
    + phys_addr_t phys = to_phys(pmem, offset);
    unsigned long pfn_start, pfn_end, pfn;

    /* only pmem in the linear map supports HWPoison */
    @@ -69,33 +85,40 @@ static void hwpoison_clear(struct pmem_device *pmem,
    }
    }

    -static blk_status_t pmem_clear_poison(struct pmem_device *pmem,
    - phys_addr_t offset, unsigned int len)
    +static void pmem_clear_bb(struct pmem_device *pmem, sector_t sector, long blks)
    {
    - struct device *dev = to_dev(pmem);
    - sector_t sector;
    - long cleared;
    - blk_status_t rc = BLK_STS_OK;
    + if (blks == 0)
    + return;
    + badblocks_clear(&pmem->bb, sector, blks);
    + if (pmem->bb_state)
    + sysfs_notify_dirent(pmem->bb_state);
    +}

    - sector = (offset - pmem->data_offset) / 512;
    +static long __pmem_clear_poison(struct pmem_device *pmem,
    + phys_addr_t offset, unsigned int len)
    +{
    + phys_addr_t phys = to_phys(pmem, offset);
    + long cleared = nvdimm_clear_poison(to_dev(pmem), phys, len);

    - cleared = nvdimm_clear_poison(dev, pmem->phys_addr + offset, len);
    - if (cleared < len)
    - rc = BLK_STS_IOERR;
    - if (cleared > 0 && cleared / 512) {
    - hwpoison_clear(pmem, pmem->phys_addr + offset, cleared);
    - cleared /= 512;
    - dev_dbg(dev, "%#llx clear %ld sector%s\n",
    - (unsigned long long) sector, cleared,
    - cleared > 1 ? "s" : "");
    - badblocks_clear(&pmem->bb, sector, cleared);
    - if (pmem->bb_state)
    - sysfs_notify_dirent(pmem->bb_state);
    + if (cleared > 0) {
    + pmem_mkpage_present(pmem, offset, cleared);
    + arch_invalidate_pmem(pmem->virt_addr + offset, len);
    }
    + return cleared;
    +}

    - arch_invalidate_pmem(pmem->virt_addr + offset, len);
    +static blk_status_t pmem_clear_poison(struct pmem_device *pmem,
    + phys_addr_t offset, unsigned int len)
    +{
    + long cleared = __pmem_clear_poison(pmem, offset, len);

    - return rc;
    + if (cleared < 0)
    + return BLK_STS_IOERR;
    +
    + pmem_clear_bb(pmem, to_sect(pmem, offset), cleared >> SECTOR_SHIFT);
    + if (cleared < len)
    + return BLK_STS_IOERR;
    + return BLK_STS_OK;
    }

    static void write_pmem(void *pmem_addr, struct page *page,
    @@ -143,7 +166,7 @@ static blk_status_t pmem_do_read(struct pmem_device *pmem,
    sector_t sector, unsigned int len)
    {
    blk_status_t rc;
    - phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
    + phys_addr_t pmem_off = to_offset(pmem, sector);
    void *pmem_addr = pmem->virt_addr + pmem_off;

    if (unlikely(is_bad_pmem(&pmem->bb, sector, len)))
    @@ -158,7 +181,7 @@ static blk_status_t pmem_do_write(struct pmem_device *pmem,
    struct page *page, unsigned int page_off,
    sector_t sector, unsigned int len)
    {
    - phys_addr_t pmem_off = sector * 512 + pmem->data_offset;
    + phys_addr_t pmem_off = to_offset(pmem, sector);
    void *pmem_addr = pmem->virt_addr + pmem_off;

    if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) {
    --
    2.18.4
    \
     
     \ /
      Last update: 2022-04-20 04:07    [W:5.977 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site