forked from MIrrors/gasket-driver
staging: gasket: cleanup extended page table map/unmap
Make sure to use dma_sync_single_for_device whenever updating the contents of an extended page table. This performs the cache flush using the correct function from the DMA-API. Also move this call outside of the inner loop to improve performance. Tested: Ran run_tests with inception, testfullyconnected with parameter caching, and rnntransducerdecoderpie107m on AT Enterprise. Change-Id: Ie3c63113dde8cafe448d515e8970810afc9564ac Signed-off-by: Nick Ewalt <nicholasewalt@google.com>
This commit is contained in:
committed by
Leonid Lobachev
parent
0dc5779dd7
commit
975c81ef1d
@@ -557,17 +557,10 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
|
|||||||
/* Make the DMA-space address available to the device. */
|
/* Make the DMA-space address available to the device. */
|
||||||
dma_addr = (ptes[i].dma_addr + offset) | GASKET_VALID_SLOT_FLAG;
|
dma_addr = (ptes[i].dma_addr + offset) | GASKET_VALID_SLOT_FLAG;
|
||||||
|
|
||||||
if (is_simple_mapping) {
|
if (is_simple_mapping)
|
||||||
writeq(dma_addr, &slots[i]);
|
writeq(dma_addr, &slots[i]);
|
||||||
} else {
|
else
|
||||||
((u64 __force *)slots)[i] = dma_addr;
|
((u64 __force *)slots)[i] = dma_addr;
|
||||||
/* Extended page table vectors are in DRAM,
|
|
||||||
* and so need to be synced each time they are updated.
|
|
||||||
*/
|
|
||||||
dma_map_single(pg_tbl->device,
|
|
||||||
(void *)&((u64 __force *)slots)[i],
|
|
||||||
sizeof(u64), DMA_TO_DEVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set PTE flags equal to flags param with STATUS=PTE_INUSE. */
|
/* Set PTE flags equal to flags param with STATUS=PTE_INUSE. */
|
||||||
ptes[i].flags = SET(FLAGS_STATUS, flags, PTE_INUSE);
|
ptes[i].flags = SET(FLAGS_STATUS, flags, PTE_INUSE);
|
||||||
@@ -639,14 +632,10 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl,
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < num_pages; i++) {
|
for (i = 0; i < num_pages; i++) {
|
||||||
/* release the address from the device, */
|
/* release the address from the device, */
|
||||||
if (is_simple_mapping ||
|
if (is_simple_mapping)
|
||||||
GET(FLAGS_STATUS, ptes[i].flags) == PTE_INUSE) {
|
|
||||||
writeq(0, &slots[i]);
|
writeq(0, &slots[i]);
|
||||||
} else {
|
else
|
||||||
((u64 __force *)slots)[i] = 0;
|
((u64 __force *)slots)[i] = 0;
|
||||||
/* sync above PTE update before updating mappings */
|
|
||||||
wmb();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release the address from the driver, */
|
/* release the address from the driver, */
|
||||||
if (GET(FLAGS_STATUS, ptes[i].flags) == PTE_INUSE) {
|
if (GET(FLAGS_STATUS, ptes[i].flags) == PTE_INUSE) {
|
||||||
@@ -702,6 +691,13 @@ static void gasket_unmap_extended_pages(struct gasket_page_table *pg_tbl,
|
|||||||
gasket_perform_unmapping(pg_tbl,
|
gasket_perform_unmapping(pg_tbl,
|
||||||
pte->sublevel + slot_idx,
|
pte->sublevel + slot_idx,
|
||||||
slot_base + slot_idx, len, 0);
|
slot_base + slot_idx, len, 0);
|
||||||
|
/*
|
||||||
|
* Extended page tables are in DRAM so they need to be
|
||||||
|
* synced each time they are updated.
|
||||||
|
*/
|
||||||
|
dma_sync_single_for_device(pg_tbl->device,
|
||||||
|
pte->dma_addr + slot_idx * sizeof(u64),
|
||||||
|
len * sizeof(u64), DMA_TO_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
remain -= len;
|
remain -= len;
|
||||||
@@ -1045,6 +1041,14 @@ static int gasket_map_extended_pages(struct gasket_page_table *pg_tbl,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended page tables are in DRAM so they need to be synced
|
||||||
|
* each time they are updated.
|
||||||
|
*/
|
||||||
|
dma_sync_single_for_device(pg_tbl->device,
|
||||||
|
pte->dma_addr + slot_idx * sizeof(u64),
|
||||||
|
len * sizeof(u64), DMA_TO_DEVICE);
|
||||||
|
|
||||||
remain -= len;
|
remain -= len;
|
||||||
slot_idx = 0;
|
slot_idx = 0;
|
||||||
pte++;
|
pte++;
|
||||||
|
|||||||
Reference in New Issue
Block a user