Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
This is prototype version of guest virtio driver.
    Guest reads the persistent memory range information
    over virtio bus from the Qemu and reserves the range
    as persistent memory. Guest also allocates a block
    device corresponding to the pmem range which later
    can be accessed with DAX compatible file systems.

    Idea is to use the virtio channel between guest and
    host to perform the block device flush for guest pmem DAX
    device.
  • Loading branch information
Pankaj Gupta committed Oct 11, 2017
1 parent 5969d1b commit d15cf90
Show file tree
Hide file tree
Showing 10 changed files with 486 additions and 93 deletions.
14 changes: 0 additions & 14 deletions drivers/nvdimm/pfn.h
Expand Up @@ -40,18 +40,4 @@ struct nd_pfn_sb {
__le64 checksum;
};

#ifdef CONFIG_SPARSEMEM
#define PFN_SECTION_ALIGN_DOWN(x) SECTION_ALIGN_DOWN(x)
#define PFN_SECTION_ALIGN_UP(x) SECTION_ALIGN_UP(x)
#else
/*
* In this case ZONE_DEVICE=n and we will disable 'pfn' device support,
* but we still want pmem to compile.
*/
#define PFN_SECTION_ALIGN_DOWN(x) (x)
#define PFN_SECTION_ALIGN_UP(x) (x)
#endif

#define PHYS_SECTION_ALIGN_DOWN(x) PFN_PHYS(PFN_SECTION_ALIGN_DOWN(PHYS_PFN(x)))
#define PHYS_SECTION_ALIGN_UP(x) PFN_PHYS(PFN_SECTION_ALIGN_UP(PHYS_PFN(x)))
#endif /* __NVDIMM_PFN_H */
20 changes: 0 additions & 20 deletions drivers/nvdimm/pfn_devs.c
Expand Up @@ -501,26 +501,6 @@ int nd_pfn_probe(struct device *dev, struct nd_namespace_common *ndns)
}
EXPORT_SYMBOL(nd_pfn_probe);

/*
* We hotplug memory at section granularity, pad the reserved area from
* the previous section base to the namespace base address.
*/
static unsigned long init_altmap_base(resource_size_t base)
{
unsigned long base_pfn = PHYS_PFN(base);

return PFN_SECTION_ALIGN_DOWN(base_pfn);
}

static unsigned long init_altmap_reserve(resource_size_t base)
{
unsigned long reserve = PHYS_PFN(SZ_8K);
unsigned long base_pfn = PHYS_PFN(base);

reserve += base_pfn - PFN_SECTION_ALIGN_DOWN(base_pfn);
return reserve;
}

static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
struct resource *res, struct vmem_altmap *altmap)
{
Expand Down
43 changes: 1 addition & 42 deletions drivers/nvdimm/pmem.c
Expand Up @@ -77,46 +77,6 @@ static blk_status_t pmem_clear_poison(struct pmem_device *pmem,
return rc;
}

static void write_pmem(void *pmem_addr, struct page *page,
unsigned int off, unsigned int len)
{
unsigned int chunk;
void *mem;

while (len) {
mem = kmap_atomic(page);
chunk = min_t(unsigned int, len, PAGE_SIZE);
memcpy_flushcache(pmem_addr, mem + off, chunk);
kunmap_atomic(mem);
len -= chunk;
off = 0;
page++;
pmem_addr += PAGE_SIZE;
}
}

static blk_status_t read_pmem(struct page *page, unsigned int off,
void *pmem_addr, unsigned int len)
{
unsigned int chunk;
int rc;
void *mem;

while (len) {
mem = kmap_atomic(page);
chunk = min_t(unsigned int, len, PAGE_SIZE);
rc = memcpy_mcsafe(mem + off, pmem_addr, chunk);
kunmap_atomic(mem);
if (rc)
return BLK_STS_IOERR;
len -= chunk;
off = 0;
page++;
pmem_addr += PAGE_SIZE;
}
return BLK_STS_OK;
}

static blk_status_t pmem_do_bvec(struct pmem_device *pmem, struct page *page,
unsigned int len, unsigned int off, bool is_write,
sector_t sector)
Expand Down Expand Up @@ -206,8 +166,7 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector,
struct pmem_device *pmem = bdev->bd_queue->queuedata;
blk_status_t rc;

rc = pmem_do_bvec(pmem, page, hpage_nr_pages(page) * PAGE_SIZE,
0, is_write, sector);
rc = pmem_do_bvec(pmem, page, PAGE_SIZE, 0, is_write, sector);

/*
* The ->rw_page interface is subtle and tricky. The core
Expand Down
18 changes: 1 addition & 17 deletions drivers/nvdimm/pmem.h
@@ -1,23 +1,7 @@
#ifndef __NVDIMM_PMEM_H__
#define __NVDIMM_PMEM_H__
#include <linux/badblocks.h>
#include <linux/types.h>
#include <linux/pfn_t.h>
#include <linux/fs.h>

#ifdef CONFIG_ARCH_HAS_PMEM_API
#define ARCH_MEMREMAP_PMEM MEMREMAP_WB
void arch_wb_cache_pmem(void *addr, size_t size);
void arch_invalidate_pmem(void *addr, size_t size);
#else
#define ARCH_MEMREMAP_PMEM MEMREMAP_WT
static inline void arch_wb_cache_pmem(void *addr, size_t size)
{
}
static inline void arch_invalidate_pmem(void *addr, size_t size)
{
}
#endif
#include <linux/pmem_common.h>

/* this definition is in it's own header for tools/testing/nvdimm to consume */
struct pmem_device {
Expand Down
9 changes: 9 additions & 0 deletions drivers/virtio/Kconfig
Expand Up @@ -38,6 +38,15 @@ config VIRTIO_PCI_LEGACY

If unsure, say Y.

config VIRTIO_PMEM
tristate "Virtio pmem driver"
depends on VIRTIO
---help---
This driver onlines pmem memory
range within a KVM guest.

If unsure, say M.

config VIRTIO_BALLOON
tristate "Virtio balloon driver"
depends on VIRTIO
Expand Down

0 comments on commit d15cf90

Please sign in to comment.