From 8be9e32b310cd8c4302991c8ff6692689c7d9d76 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 28 Oct 2012 00:49:32 +0900 Subject: dmatest: adjust invalid module parameters for number of source buffers DMA Engine test module has module parameters to set the number of source buffers for xor and pq operations. We can set these values larger than the maximum number of sources that the device can support. These values are not adjusted and the unsupported number of source buffers are passed to the device. But most drivers don't check it, so unexpected results will happen. This makes an appropriate adjustment for these module parameters before use. Signed-off-by: Akinobu Mita Cc: Vinod Koul Cc: Dan Williams Signed-off-by: Vinod Koul --- drivers/dma/dmatest.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/dma/dmatest.c') diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 64b048d..3a8047b 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -242,6 +242,13 @@ static inline void unmap_dst(struct device *dev, dma_addr_t *addr, size_t len, dma_unmap_single(dev, addr[count], len, DMA_BIDIRECTIONAL); } +static unsigned int min_odd(unsigned int x, unsigned int y) +{ + unsigned int val = min(x, y); + + return val % 2 ? val : val - 1; +} + /* * This function repeatedly tests DMA transfers of various lengths and * offsets for a given operation type until it is told to exit by @@ -262,6 +269,7 @@ static int dmatest_func(void *data) struct dmatest_thread *thread = data; struct dmatest_done done = { .wait = &done_wait }; struct dma_chan *chan; + struct dma_device *dev; const char *thread_name; unsigned int src_off, dst_off, len; unsigned int error_count; @@ -283,13 +291,16 @@ static int dmatest_func(void *data) smp_rmb(); chan = thread->chan; + dev = chan->device; if (thread->type == DMA_MEMCPY) src_cnt = dst_cnt = 1; else if (thread->type == DMA_XOR) { - src_cnt = xor_sources | 1; /* force odd to ensure dst = src */ + /* force odd to ensure dst = src */ + src_cnt = min_odd(xor_sources | 1, dev->max_xor); dst_cnt = 1; } else if (thread->type == DMA_PQ) { - src_cnt = pq_sources | 1; /* force odd to ensure dst = src */ + /* force odd to ensure dst = src */ + src_cnt = min_odd(pq_sources | 1, dma_maxpq(dev, 0)); dst_cnt = 2; for (i = 0; i < src_cnt; i++) pq_coefs[i] = 1; @@ -327,7 +338,6 @@ static int dmatest_func(void *data) while (!kthread_should_stop() && !(iterations && total_tests >= iterations)) { - 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]; -- cgit v1.1 From 944ea4dd38b8575e30a5699633c81945bff1864d Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Sun, 11 Nov 2012 23:03:20 +0000 Subject: dmatest: Fix NULL pointer dereference on ioat device_control is an optional and not implemented in all DMA drivers. Any calls to these will result in a NULL pointer dereference. dmatest makes two of these calls when completing the kernel thread and removing the module. These are corrected by calling the dmaengine_device_control wrapper and checking for a non-existant device_control function pointer there. Signed-off-by: Jon Mason CC: Vinod Koul CC: Dan Williams Reviewed-by: Viresh Kumar Signed-off-by: Vinod Koul --- drivers/dma/dmatest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma/dmatest.c') diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 3a8047b..99a75e5 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -536,7 +536,7 @@ err_srcs: thread_name, total_tests, failed_tests, ret); /* terminate all transfers on specified channels */ - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(chan); if (iterations > 0) while (!kthread_should_stop()) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit); @@ -561,7 +561,7 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc) } /* terminate all transfers on specified channels */ - dtc->chan->device->device_control(dtc->chan, DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(dtc->chan); kfree(dtc); } -- cgit v1.1 From 5e034f7b659be9d94e64aaaa985ab530dd847fdb Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Fri, 9 Nov 2012 15:26:29 +0000 Subject: dmaengine/dmatest: terminate transfers only in case of errors dmatest erroneously terminated transfers in normal cases also leading to test failures for multiple threads over a channel. Fix this and terminate transfers only in case of errors. Signed-off-by: Shiraz Hashim Signed-off-by: Deepak Sikri Signed-off-by: Vinod Koul --- drivers/dma/dmatest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/dma/dmatest.c') diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 99a75e5..a2c8904 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -536,7 +536,9 @@ err_srcs: thread_name, total_tests, failed_tests, ret); /* terminate all transfers on specified channels */ - dmaengine_terminate_all(chan); + if (ret) + dmaengine_terminate_all(chan); + if (iterations > 0) while (!kthread_should_stop()) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit); -- cgit v1.1