Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e44e0aa3 authored by Dan Williams's avatar Dan Williams
Browse files

dmatest: add dma interrupts and callbacks



Use the callback infrastructure to report driver/hardware hangs or
missed interrupts.  Since this makes the test threads much more
aggressive (from: explicit 1ms sleep to: wait_for_completion) we set the
nice value to 10 so as to not swamp legitimate tasks.

Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent b54d5cb9
Loading
Loading
Loading
Loading
+27 −10
Original line number Diff line number Diff line
@@ -196,6 +196,11 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
	return error_count;
}

static void dmatest_callback(void *completion)
{
	complete(completion);
}

/*
 * This function repeatedly tests DMA transfers of various lengths and
 * offsets for a given operation type until it is told to exit by
@@ -261,13 +266,17 @@ static int dmatest_func(void *data)
	}
	thread->dsts[i] = NULL;

	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP;
	set_user_nice(current, 10);

	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;

	while (!kthread_should_stop()) {
		struct dma_device *dev = chan->device;
		struct dma_async_tx_descriptor *tx = NULL;
		dma_addr_t dma_srcs[src_cnt];
		dma_addr_t dma_dsts[dst_cnt];
		struct completion cmp;
		unsigned long tmo = msecs_to_jiffies(3000);

		total_tests++;

@@ -318,7 +327,10 @@ static int dmatest_func(void *data)
			failed_tests++;
			continue;
		}
		tx->callback = NULL;

		init_completion(&cmp);
		tx->callback = dmatest_callback;
		tx->callback_param = &cmp;
		cookie = tx->tx_submit(tx);

		if (dma_submit_error(cookie)) {
@@ -332,18 +344,23 @@ static int dmatest_func(void *data)
		}
		dma_async_issue_pending(chan);

		do {
			msleep(1);
			status = dma_async_is_tx_complete(
					chan, cookie, NULL, NULL);
		} while (status == DMA_IN_PROGRESS);
		tmo = wait_for_completion_timeout(&cmp, tmo);
		status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);

		if (status == DMA_ERROR) {
			pr_warning("%s: #%u: error during copy\n",
		if (tmo == 0) {
			pr_warning("%s: #%u: test timed out\n",
				   thread_name, total_tests - 1);
			failed_tests++;
			continue;
		} else if (status != DMA_SUCCESS) {
			pr_warning("%s: #%u: got completion callback,"
				   " but status is \'%s\'\n",
				   thread_name, total_tests - 1,
				   status == DMA_ERROR ? "error" : "in progress");
			failed_tests++;
			continue;
		}

		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
		for (i = 0; i < dst_cnt; i++)
			dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,