Skip to content

Commit

Permalink
s390x/pci: coalesce unmap operations
Browse files Browse the repository at this point in the history
Currently, each unmapped page is handled as an individual iommu
region notification.  Attempt to group contiguous unmap operations
into fewer notifications to reduce overhead.

Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Message-Id: <20221028194758.204007-3-mjrosato@linux.ibm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
  • Loading branch information
rosatomj authored and huth committed Dec 14, 2022
1 parent 5204b49 commit 264de3b
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions hw/s390x/s390-pci-inst.c
Expand Up @@ -640,6 +640,8 @@ static uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
}
g_hash_table_remove(iommu->iotlb, &entry->iova);
inc_dma_avail(iommu);
/* Don't notify the iommu yet, maybe we can bundle contiguous unmaps */
goto out;
} else {
if (cache) {
if (cache->perm == entry->perm &&
Expand All @@ -663,15 +665,44 @@ static uint32_t s390_pci_update_iotlb(S390PCIIOMMU *iommu,
dec_dma_avail(iommu);
}

/*
* All associated iotlb entries have already been cleared, trigger the
* unmaps.
*/
memory_region_notify_iommu(&iommu->iommu_mr, 0, event);

out:
return iommu->dma_limit ? iommu->dma_limit->avail : 1;
}

static void s390_pci_batch_unmap(S390PCIIOMMU *iommu, uint64_t iova,
uint64_t len)
{
uint64_t remain = len, start = iova, end = start + len - 1, mask, size;
IOMMUTLBEvent event = {
.type = IOMMU_NOTIFIER_UNMAP,
.entry = {
.target_as = &address_space_memory,
.translated_addr = 0,
.perm = IOMMU_NONE,
},
};

while (remain >= TARGET_PAGE_SIZE) {
mask = dma_aligned_pow2_mask(start, end, 64);
size = mask + 1;
event.entry.iova = start;
event.entry.addr_mask = mask;
memory_region_notify_iommu(&iommu->iommu_mr, 0, event);
start += size;
remain -= size;
}
}

int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
{
CPUS390XState *env = &cpu->env;
uint64_t iova, coalesce = 0;
uint32_t fh;
uint16_t error = 0;
S390PCIBusDevice *pbdev;
Expand Down Expand Up @@ -742,6 +773,21 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
break;
}

/*
* If this is an unmap of a PTE, let's try to coalesce multiple unmaps
* into as few notifier events as possible.
*/
if (entry.perm == IOMMU_NONE && entry.len == TARGET_PAGE_SIZE) {
if (coalesce == 0) {
iova = entry.iova;
}
coalesce += entry.len;
} else if (coalesce > 0) {
/* Unleash the coalesced unmap before processing a new map */
s390_pci_batch_unmap(iommu, iova, coalesce);
coalesce = 0;
}

start += entry.len;
while (entry.iova < start && entry.iova < end) {
if (dma_avail > 0 || entry.perm == IOMMU_NONE) {
Expand All @@ -759,6 +805,11 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
}
}
}
if (coalesce) {
/* Unleash the coalesced unmap before finishing rpcit */
s390_pci_batch_unmap(iommu, iova, coalesce);
coalesce = 0;
}
if (again && dma_avail > 0)
goto retry;
err:
Expand Down

0 comments on commit 264de3b

Please sign in to comment.