Skip to content

Commit 4076e75

Browse files
committed
dmatest: convert to dmaengine_unmap_data
Remove the open coded unmap and add coverage for this core functionality to dmatest. Also fixes up a couple places where we leaked dma mappings. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 2d88ce7 commit 4076e75

File tree

1 file changed

+44
-42
lines changed

1 file changed

+44
-42
lines changed

drivers/dma/dmatest.c

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -326,20 +326,6 @@ static void dmatest_callback(void *arg)
326326
wake_up_all(done->wait);
327327
}
328328

329-
static inline void unmap_src(struct device *dev, dma_addr_t *addr, size_t len,
330-
unsigned int count)
331-
{
332-
while (count--)
333-
dma_unmap_single(dev, addr[count], len, DMA_TO_DEVICE);
334-
}
335-
336-
static inline void unmap_dst(struct device *dev, dma_addr_t *addr, size_t len,
337-
unsigned int count)
338-
{
339-
while (count--)
340-
dma_unmap_single(dev, addr[count], len, DMA_BIDIRECTIONAL);
341-
}
342-
343329
static unsigned int min_odd(unsigned int x, unsigned int y)
344330
{
345331
unsigned int val = min(x, y);
@@ -484,8 +470,9 @@ static int dmatest_func(void *data)
484470
while (!kthread_should_stop()
485471
&& !(params->iterations && total_tests >= params->iterations)) {
486472
struct dma_async_tx_descriptor *tx = NULL;
487-
dma_addr_t dma_srcs[src_cnt];
488-
dma_addr_t dma_dsts[dst_cnt];
473+
struct dmaengine_unmap_data *um;
474+
dma_addr_t srcs[src_cnt];
475+
dma_addr_t *dsts;
489476
u8 align = 0;
490477

491478
total_tests++;
@@ -530,61 +517,75 @@ static int dmatest_func(void *data)
530517
len = 1 << align;
531518
total_len += len;
532519

533-
for (i = 0; i < src_cnt; i++) {
534-
u8 *buf = thread->srcs[i] + src_off;
520+
um = dmaengine_get_unmap_data(dev->dev, src_cnt+dst_cnt,
521+
GFP_KERNEL);
522+
if (!um) {
523+
failed_tests++;
524+
result("unmap data NULL", total_tests,
525+
src_off, dst_off, len, ret);
526+
continue;
527+
}
535528

536-
dma_srcs[i] = dma_map_single(dev->dev, buf, len,
537-
DMA_TO_DEVICE);
538-
ret = dma_mapping_error(dev->dev, dma_srcs[i]);
529+
um->len = params->buf_size;
530+
for (i = 0; i < src_cnt; i++) {
531+
unsigned long buf = (unsigned long) thread->srcs[i];
532+
struct page *pg = virt_to_page(buf);
533+
unsigned pg_off = buf & ~PAGE_MASK;
534+
535+
um->addr[i] = dma_map_page(dev->dev, pg, pg_off,
536+
um->len, DMA_TO_DEVICE);
537+
srcs[i] = um->addr[i] + src_off;
538+
ret = dma_mapping_error(dev->dev, um->addr[i]);
539539
if (ret) {
540-
unmap_src(dev->dev, dma_srcs, len, i);
540+
dmaengine_unmap_put(um);
541541
result("src mapping error", total_tests,
542542
src_off, dst_off, len, ret);
543543
failed_tests++;
544544
continue;
545545
}
546+
um->to_cnt++;
546547
}
547548
/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
549+
dsts = &um->addr[src_cnt];
548550
for (i = 0; i < dst_cnt; i++) {
549-
dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
550-
params->buf_size,
551-
DMA_BIDIRECTIONAL);
552-
ret = dma_mapping_error(dev->dev, dma_dsts[i]);
551+
unsigned long buf = (unsigned long) thread->dsts[i];
552+
struct page *pg = virt_to_page(buf);
553+
unsigned pg_off = buf & ~PAGE_MASK;
554+
555+
dsts[i] = dma_map_page(dev->dev, pg, pg_off, um->len,
556+
DMA_BIDIRECTIONAL);
557+
ret = dma_mapping_error(dev->dev, dsts[i]);
553558
if (ret) {
554-
unmap_src(dev->dev, dma_srcs, len, src_cnt);
555-
unmap_dst(dev->dev, dma_dsts, params->buf_size,
556-
i);
559+
dmaengine_unmap_put(um);
557560
result("dst mapping error", total_tests,
558561
src_off, dst_off, len, ret);
559562
failed_tests++;
560563
continue;
561564
}
565+
um->bidi_cnt++;
562566
}
563567

564568
if (thread->type == DMA_MEMCPY)
565569
tx = dev->device_prep_dma_memcpy(chan,
566-
dma_dsts[0] + dst_off,
567-
dma_srcs[0], len,
568-
flags);
570+
dsts[0] + dst_off,
571+
srcs[0], len, flags);
569572
else if (thread->type == DMA_XOR)
570573
tx = dev->device_prep_dma_xor(chan,
571-
dma_dsts[0] + dst_off,
572-
dma_srcs, src_cnt,
574+
dsts[0] + dst_off,
575+
srcs, src_cnt,
573576
len, flags);
574577
else if (thread->type == DMA_PQ) {
575578
dma_addr_t dma_pq[dst_cnt];
576579

577580
for (i = 0; i < dst_cnt; i++)
578-
dma_pq[i] = dma_dsts[i] + dst_off;
579-
tx = dev->device_prep_dma_pq(chan, dma_pq, dma_srcs,
581+
dma_pq[i] = dsts[i] + dst_off;
582+
tx = dev->device_prep_dma_pq(chan, dma_pq, srcs,
580583
src_cnt, pq_coefs,
581584
len, flags);
582585
}
583586

584587
if (!tx) {
585-
unmap_src(dev->dev, dma_srcs, len, src_cnt);
586-
unmap_dst(dev->dev, dma_dsts, params->buf_size,
587-
dst_cnt);
588+
dmaengine_unmap_put(um);
588589
result("prep error", total_tests, src_off,
589590
dst_off, len, ret);
590591
msleep(100);
@@ -598,6 +599,7 @@ static int dmatest_func(void *data)
598599
cookie = tx->tx_submit(tx);
599600

600601
if (dma_submit_error(cookie)) {
602+
dmaengine_unmap_put(um);
601603
result("submit error", total_tests, src_off,
602604
dst_off, len, ret);
603605
msleep(100);
@@ -620,11 +622,13 @@ static int dmatest_func(void *data)
620622
* free it this time?" dancing. For now, just
621623
* leave it dangling.
622624
*/
625+
dmaengine_unmap_put(um);
623626
result("test timed out", total_tests, src_off, dst_off,
624627
len, 0);
625628
failed_tests++;
626629
continue;
627630
} else if (status != DMA_SUCCESS) {
631+
dmaengine_unmap_put(um);
628632
result(status == DMA_ERROR ?
629633
"completion error status" :
630634
"completion busy status", total_tests, src_off,
@@ -633,9 +637,7 @@ static int dmatest_func(void *data)
633637
continue;
634638
}
635639

636-
/* Unmap by myself */
637-
unmap_src(dev->dev, dma_srcs, len, src_cnt);
638-
unmap_dst(dev->dev, dma_dsts, params->buf_size, dst_cnt);
640+
dmaengine_unmap_put(um);
639641

640642
if (params->noverify) {
641643
dbg_result("test passed", total_tests, src_off, dst_off,

0 commit comments

Comments
 (0)