diff options
author | Kishon Vijay Abraham I <kishon@ti.com> | 2020-03-16 12:24:21 +0100 |
---|---|---|
committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2020-04-02 18:57:10 +0200 |
commit | 5893c2e5353bb9a723d862d8b6ba8028a8f6a6eb (patch) | |
tree | 2c613f4660419996da446c1c2445be435344f505 /drivers/pci | |
parent | PCI: endpoint: functions/pci-epf-test: Add DMA support to transfer data (diff) | |
download | linux-5893c2e5353bb9a723d862d8b6ba8028a8f6a6eb.tar.xz linux-5893c2e5353bb9a723d862d8b6ba8028a8f6a6eb.zip |
PCI: endpoint: functions/pci-epf-test: Print throughput information
Print throughput information in KB/s after every completed transfer,
including information on whether DMA is used or not.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tested-by: Alan Mikhak <alan.mikhak@sifive.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/endpoint/functions/pci-epf-test.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 737e15d9e5dc..0a5019ce7540 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -190,6 +190,36 @@ static void pci_epf_test_clean_dma_chan(struct pci_epf_test *epf_test) epf_test->dma_chan = NULL; } +static void pci_epf_test_print_rate(const char *ops, u64 size, + struct timespec64 *start, + struct timespec64 *end, bool dma) +{ + struct timespec64 ts; + u64 rate, ns; + + ts = timespec64_sub(*end, *start); + + /* convert both size (stored in 'rate') and time in terms of 'ns' */ + ns = timespec64_to_ns(&ts); + rate = size * NSEC_PER_SEC; + + /* Divide both size (stored in 'rate') and ns by a common factor */ + while (ns > UINT_MAX) { + rate >>= 1; + ns >>= 1; + } + + if (!ns) + return; + + /* calculate the rate */ + do_div(rate, (uint32_t)ns); + + pr_info("\n%s => Size: %llu bytes\t DMA: %s\t Time: %llu.%09u seconds\t" + "Rate: %llu KB/s\n", ops, size, dma ? "YES" : "NO", + (u64)ts.tv_sec, (u32)ts.tv_nsec, rate / 1024); +} + static int pci_epf_test_copy(struct pci_epf_test *epf_test) { int ret; @@ -198,6 +228,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) void __iomem *dst_addr; phys_addr_t src_phys_addr; phys_addr_t dst_phys_addr; + struct timespec64 start, end; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; @@ -236,6 +267,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_dst_addr; } + ktime_get_ts64(&start); use_dma = !!(reg->flags & FLAG_USE_DMA); if (use_dma) { if (!epf_test->dma_supported) { @@ -251,6 +283,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) } else { memcpy(dst_addr, src_addr, reg->size); } + ktime_get_ts64(&end); + pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma); err_map_addr: pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr); @@ -277,6 +311,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) bool use_dma; phys_addr_t phys_addr; phys_addr_t dst_phys_addr; + struct timespec64 start, end; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; @@ -322,17 +357,23 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) goto err_dma_map; } + ktime_get_ts64(&start); ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr, phys_addr, reg->size); if (ret) dev_err(dev, "Data transfer failed\n"); + ktime_get_ts64(&end); dma_unmap_single(dma_dev, dst_phys_addr, reg->size, DMA_FROM_DEVICE); } else { + ktime_get_ts64(&start); memcpy_fromio(buf, src_addr, reg->size); + ktime_get_ts64(&end); } + pci_epf_test_print_rate("READ", reg->size, &start, &end, use_dma); + crc32 = crc32_le(~0, buf, reg->size); if (crc32 != reg->checksum) ret = -EIO; @@ -358,6 +399,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) bool use_dma; phys_addr_t phys_addr; phys_addr_t src_phys_addr; + struct timespec64 start, end; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; @@ -406,17 +448,23 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) goto err_dma_map; } + ktime_get_ts64(&start); ret = pci_epf_test_data_transfer(epf_test, phys_addr, src_phys_addr, reg->size); if (ret) dev_err(dev, "Data transfer failed\n"); + ktime_get_ts64(&end); dma_unmap_single(dma_dev, src_phys_addr, reg->size, DMA_TO_DEVICE); } else { + ktime_get_ts64(&start); memcpy_toio(dst_addr, buf, reg->size); + ktime_get_ts64(&end); } + pci_epf_test_print_rate("WRITE", reg->size, &start, &end, use_dma); + /* * wait 1ms inorder for the write to complete. Without this delay L3 * error in observed in the host system. |