Commit 70f008fb authored by Amelie Delaunay's avatar Amelie Delaunay Committed by Vinod Koul

dmaengine: dmatest: prevent using swiotlb buffer with nobounce parameter

Source and destination data buffers are allocated with GPF_KERNEL flag.
It means that, if the DDR is more than 2GB, buffers can be allocated above
the 32-bit addressable space. In this case, and if the dma controller is
only 32-bit compatible, swiotlb bounce buffer, located in the 32-bit
addressable space, is used and introduces a memcpy.

To prevent this extra memcpy, due to swiotlb bounce buffer use because
source or destination data buffer is allocated above the 32-bit addressable
space, force source and destination data buffers allocation with GPF_DMA
instead, when nobounce parameter is true.
Signed-off-by: default avatarAmelie Delaunay <amelie.delaunay@foss.st.com>
Link: https://lore.kernel.org/r/20231124160235.2459326-1-amelie.delaunay@foss.st.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 25b63622
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/wait.h> #include <linux/wait.h>
static bool nobounce;
module_param(nobounce, bool, 0644);
MODULE_PARM_DESC(nobounce, "Prevent using swiotlb buffer (default: use swiotlb buffer)");
static unsigned int test_buf_size = 16384; static unsigned int test_buf_size = 16384;
module_param(test_buf_size, uint, 0644); module_param(test_buf_size, uint, 0644);
MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
...@@ -90,6 +94,7 @@ MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts"); ...@@ -90,6 +94,7 @@ MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts");
/** /**
* struct dmatest_params - test parameters. * struct dmatest_params - test parameters.
* @nobounce: prevent using swiotlb buffer
* @buf_size: size of the memcpy test buffer * @buf_size: size of the memcpy test buffer
* @channel: bus ID of the channel to test * @channel: bus ID of the channel to test
* @device: bus ID of the DMA Engine to test * @device: bus ID of the DMA Engine to test
...@@ -106,6 +111,7 @@ MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts"); ...@@ -106,6 +111,7 @@ MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts");
* @polled: use polling for completion instead of interrupts * @polled: use polling for completion instead of interrupts
*/ */
struct dmatest_params { struct dmatest_params {
bool nobounce;
unsigned int buf_size; unsigned int buf_size;
char channel[20]; char channel[20];
char device[32]; char device[32];
...@@ -215,6 +221,7 @@ struct dmatest_done { ...@@ -215,6 +221,7 @@ struct dmatest_done {
struct dmatest_data { struct dmatest_data {
u8 **raw; u8 **raw;
u8 **aligned; u8 **aligned;
gfp_t gfp_flags;
unsigned int cnt; unsigned int cnt;
unsigned int off; unsigned int off;
}; };
...@@ -533,7 +540,7 @@ static int dmatest_alloc_test_data(struct dmatest_data *d, ...@@ -533,7 +540,7 @@ static int dmatest_alloc_test_data(struct dmatest_data *d,
goto err; goto err;
for (i = 0; i < d->cnt; i++) { for (i = 0; i < d->cnt; i++) {
d->raw[i] = kmalloc(buf_size + align, GFP_KERNEL); d->raw[i] = kmalloc(buf_size + align, d->gfp_flags);
if (!d->raw[i]) if (!d->raw[i])
goto err; goto err;
...@@ -655,6 +662,13 @@ static int dmatest_func(void *data) ...@@ -655,6 +662,13 @@ static int dmatest_func(void *data)
goto err_free_coefs; goto err_free_coefs;
} }
src->gfp_flags = GFP_KERNEL;
dst->gfp_flags = GFP_KERNEL;
if (params->nobounce) {
src->gfp_flags = GFP_DMA;
dst->gfp_flags = GFP_DMA;
}
if (dmatest_alloc_test_data(src, buf_size, align) < 0) if (dmatest_alloc_test_data(src, buf_size, align) < 0)
goto err_free_coefs; goto err_free_coefs;
...@@ -1093,6 +1107,7 @@ static void add_threaded_test(struct dmatest_info *info) ...@@ -1093,6 +1107,7 @@ static void add_threaded_test(struct dmatest_info *info)
struct dmatest_params *params = &info->params; struct dmatest_params *params = &info->params;
/* Copy test parameters */ /* Copy test parameters */
params->nobounce = nobounce;
params->buf_size = test_buf_size; params->buf_size = test_buf_size;
strscpy(params->channel, strim(test_channel), sizeof(params->channel)); strscpy(params->channel, strim(test_channel), sizeof(params->channel));
strscpy(params->device, strim(test_device), sizeof(params->device)); strscpy(params->device, strim(test_device), sizeof(params->device));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment