With xen_shim_domain() enabled, the struct pages used for grant mappings are only valid in the interval between GNTTABOP_map_grant_ref and GNTTABOP_unmap_grant_ref. Ensure that we do not cache the struct page outside that duration. Also, update the struct page for the segment after GNTTABOP_map_grant_ref, for the subsequent tracking or when doing IO. In addition, we disable persistent grants for this configuration, since the map/unmap overhead is fairly small (in the fast path, page lookup, get_page() and put_page().) This reduces the memory usage in blkback/blkfront. Co-developed-by: Ankur Arora <ankur.a.arora@xxxxxxxxxx> Signed-off-by: Joao Martins <joao.m.martins@xxxxxxxxxx> Signed-off-by: Ankur Arora <ankur.a.arora@xxxxxxxxxx> --- drivers/block/xen-blkback/blkback.c | 19 ++++++++++++++++--- drivers/block/xen-blkback/xenbus.c | 5 +++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index d51d88be88e1..20c15e6787b1 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -167,6 +167,15 @@ static inline void put_free_pages(struct xen_blkif_ring *ring, struct page **pag unsigned long flags; int i; + /* + * We don't own the struct page after unmap has been called. + * Reallocation is cheap anyway for the shim domain case, so free it. + */ + if (xen_shim_domain()) { + gnttab_free_pages(num, page); + return; + } + spin_lock_irqsave(&ring->free_pages_lock, flags); for (i = 0; i < num; i++) list_add(&page[i]->lru, &ring->free_pages); @@ -825,7 +834,7 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, */ again: for (i = map_until; i < num; i++) { - uint32_t flags; + uint32_t flags = 0; if (use_persistent_gnts) { persistent_gnt = get_persistent_gnt( @@ -846,7 +855,8 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, addr = vaddr(pages[i]->page); pages_to_gnt[segs_to_map] = pages[i]->page; pages[i]->persistent_gnt = NULL; - flags = GNTMAP_host_map; + if (!xen_shim_domain()) + flags = GNTMAP_host_map; if (!use_persistent_gnts && ro) flags |= GNTMAP_readonly; gnttab_set_map_op(&map[segs_to_map++], addr, @@ -880,6 +890,8 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, goto next; } pages[seg_idx]->handle = map[new_map_idx].handle; + if (xen_shim_domain()) + pages[seg_idx]->page = pages_to_gnt[new_map_idx]; } else { continue; } @@ -1478,7 +1490,7 @@ static int __init xen_blkif_init(void) { int rc = 0; - if (!xen_domain()) + if (!xen_domain() && !xen_shim_domain_get()) return -ENODEV; if (xen_blkif_max_ring_order > XENBUS_MAX_RING_GRANT_ORDER) { @@ -1508,6 +1520,7 @@ static void __exit xen_blkif_exit(void) { xen_blkif_interface_exit(); xen_blkif_xenbus_exit(); + xen_shim_domain_put(); } module_exit(xen_blkif_exit); diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 424e2efebe85..11be0c052b77 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -871,7 +871,8 @@ static void connect(struct backend_info *be) xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); - err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", 1); + err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", + !xen_shim_domain()); if (err) { xenbus_dev_fatal(dev, err, "writing %s/feature-persistent", dev->nodename); @@ -1059,7 +1060,7 @@ static int connect_ring(struct backend_info *be) } pers_grants = xenbus_read_unsigned(dev->otherend, "feature-persistent", 0); - be->blkif->vbd.feature_gnt_persistent = pers_grants; + be->blkif->vbd.feature_gnt_persistent = pers_grants && !xen_shim_domain(); be->blkif->vbd.overflow_max_grants = 0; /* -- 2.11.0