The scatterlist is used uninitialized in kfifo_dma_in_prepare(). This triggers the following bug if CONFIG_DEBUG_SG=y: ------------[ cut here ]------------ kernel BUG at include/linux/scatterlist.h:65! invalid opcode: 0000 [#1] PREEMPT SMP ... Call Trace: [<ffffffff810a1eab>] setup_sgl+0x6b/0xe0 [<ffffffffa03d7000>] ? example_init+0x0/0x265 [dma_example] [<ffffffff810a2021>] __kfifo_dma_in_prepare+0x21/0x30 [<ffffffffa03d7124>] example_init+0x124/0x265 [dma_example] [<ffffffff810f9c55>] ? trace_module_notify+0x25/0x370 [<ffffffff81110c6e>] ? free_pages_prepare+0x11e/0x1e0 [<ffffffff8106f2b1>] ? get_parent_ip+0x11/0x50 [<ffffffff810f9c55>] ? trace_module_notify+0x25/0x370 [<ffffffff810b65fd>] ? trace_hardirqs_on+0xd/0x10 [<ffffffff814beade>] ? mutex_unlock+0xe/0x10 [<ffffffff810f9c71>] ? trace_module_notify+0x41/0x370 [<ffffffff810a77d5>] ? __blocking_notifier_call_chain+0x45/0x80 [<ffffffff81137b7a>] ? vfree+0x2a/0x30 [<ffffffff810a6ac3>] ? up_read+0x23/0x40 [<ffffffff810a77f5>] ? __blocking_notifier_call_chain+0x65/0x80 [<ffffffff810001e3>] do_one_initcall+0x43/0x180 [<ffffffff810c577a>] sys_init_module+0xba/0x200 [<ffffffff8103819b>] system_call_fastpath+0x16/0x1b RIP [<ffffffff810a1e31>] setup_sgl_buf+0x1a1/0x1b0 RSP <ffff88006720dc98> ---[ end trace a72b979fd3c1d3a5 ]--- Add the proper initialization to avoid the bug. Signed-off-by: Andrea Righi <arighi@develer.com> --- samples/kfifo/dma-example.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index b9482c2..03433ca 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c @@ -45,6 +45,7 @@ static int __init example_init(void) printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); + sg_init_table(sg, ARRAY_SIZE(sg)); ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); printk(KERN_INFO "DMA sgl entries: %d\n", ...
We use a dynamically allocated kfifo in the dma example, so we need to
free it when unloading the module.
Signed-off-by: Andrea Righi <arighi@develer.com>
---
samples/kfifo/dma-example.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c
index 03433ca..3682278 100644
--- a/samples/kfifo/dma-example.c
+++ b/samples/kfifo/dma-example.c
@@ -105,9 +105,7 @@ static int __init example_init(void)
static void __exit example_exit(void)
{
-#ifdef DYNAMIC
- kfifo_free(&test);
-#endif
+ kfifo_free(&fifo);
}
module_init(example_init);
--
1.7.0.4
--
We use a dynamically allocated kfifo in the dma example, so we need to
free it when unloading the module.
Signed-off-by: Andrea Righi <arighi@develer.com>
Acked-by: Stefani Seibold <stefani@seibold.net>
---
samples/kfifo/dma-example.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c
index 03433ca..3682278 100644
--- a/samples/kfifo/dma-example.c
+++ b/samples/kfifo/dma-example.c
@@ -105,9 +105,7 @@ static int __init example_init(void)
static void __exit example_exit(void)
{
-#ifdef DYNAMIC
- kfifo_free(&test);
-#endif
+ kfifo_free(&fifo);
}
module_init(example_init);
--
Provide a check in all the kfifo examples to validate the correct
execution of each testcase.
[ Andrew: this depends on kfifo-add-explicit-error-checking-in-byte-stream-example.patch ]
Signed-off-by: Andrea Righi <arighi@develer.com>
---
samples/kfifo/bytestream-example.c | 7 ++-
samples/kfifo/dma-example.c | 106 +++++++++++++++++++++++-------------
samples/kfifo/inttype-example.c | 43 ++++++++++++---
samples/kfifo/record-example.c | 39 ++++++++++++-
4 files changed, 144 insertions(+), 51 deletions(-)
diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c
index a94e694..178061e 100644
--- a/samples/kfifo/bytestream-example.c
+++ b/samples/kfifo/bytestream-example.c
@@ -44,7 +44,7 @@ static struct kfifo test;
static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE);
#endif
-static unsigned char expected_result[FIFO_SIZE] = {
+static const unsigned char expected_result[FIFO_SIZE] = {
3, 4, 5, 6, 7, 8, 9, 0,
1, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34,
@@ -90,9 +90,14 @@ static int __init testfunc(void)
printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
+ /* show the first value without removing from the fifo */
+ if (kfifo_peek(&test, &i))
+ printk(KERN_INFO "%d\n", i);
+
/* check the correctness of all values in the fifo */
j = 0;
while (kfifo_get(&test, &i)) {
+ printk(KERN_INFO "item = %d\n", i);
if (i != expected_result[j++]) {
printk(KERN_WARNING "value mismatch: test failed\n");
return -EIO;
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c
index 3682278..ee03a4f 100644
--- a/samples/kfifo/dma-example.c
+++ b/samples/kfifo/dma-example.c
@@ -29,8 +29,8 @@ static int __init example_init(void)
printk(KERN_INFO "DMA fifo test start\n");
if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
- printk(KERN_ERR "error kfifo_alloc\n");
- return 1;
+ printk(KERN_WARNING "error kfifo_alloc\n");
+ return -ENOMEM;
}
...Provide a check in all the kfifo examples to validate the correct
execution of each testcase.
[ Andrew: this depends on kfifo-add-explicit-error-checking-in-byte-stream-example.patch ]
Signed-off-by: Andrea Righi <arighi@develer.com>
Acked-by: Stefani Seibold <stefani@seibold.net>
---
samples/kfifo/bytestream-example.c | 7 ++-
samples/kfifo/dma-example.c | 106 +++++++++++++++++++++++-------------
samples/kfifo/inttype-example.c | 43 ++++++++++++---
samples/kfifo/record-example.c | 39 ++++++++++++-
4 files changed, 144 insertions(+), 51 deletions(-)
diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c
index a94e694..178061e 100644
--- a/samples/kfifo/bytestream-example.c
+++ b/samples/kfifo/bytestream-example.c
@@ -44,7 +44,7 @@ static struct kfifo test;
static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE);
#endif
-static unsigned char expected_result[FIFO_SIZE] = {
+static const unsigned char expected_result[FIFO_SIZE] = {
3, 4, 5, 6, 7, 8, 9, 0,
1, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34,
@@ -90,9 +90,14 @@ static int __init testfunc(void)
printk(KERN_INFO "queue len: %u\n", kfifo_len(&test));
+ /* show the first value without removing from the fifo */
+ if (kfifo_peek(&test, &i))
+ printk(KERN_INFO "%d\n", i);
+
/* check the correctness of all values in the fifo */
j = 0;
while (kfifo_get(&test, &i)) {
+ printk(KERN_INFO "item = %d\n", i);
if (i != expected_result[j++]) {
printk(KERN_WARNING "value mismatch: test failed\n");
return -EIO;
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c
index 3682278..ee03a4f 100644
--- a/samples/kfifo/dma-example.c
+++ b/samples/kfifo/dma-example.c
@@ -29,8 +29,8 @@ static int __init example_init(void)
printk(KERN_INFO "DMA fifo test start\n");
if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) {
- printk(KERN_ERR "error kfifo_alloc\n");
- return 1;
+ printk(KERN_WARNING ...The scatterlist is used uninitialized in kfifo_dma_in_prepare(). This triggers the following bug if CONFIG_DEBUG_SG=y: ------------[ cut here ]------------ kernel BUG at include/linux/scatterlist.h:65! invalid opcode: 0000 [#1] PREEMPT SMP ... Call Trace: [<ffffffff810a1eab>] setup_sgl+0x6b/0xe0 [<ffffffffa03d7000>] ? example_init+0x0/0x265 [dma_example] [<ffffffff810a2021>] __kfifo_dma_in_prepare+0x21/0x30 [<ffffffffa03d7124>] example_init+0x124/0x265 [dma_example] [<ffffffff810f9c55>] ? trace_module_notify+0x25/0x370 [<ffffffff81110c6e>] ? free_pages_prepare+0x11e/0x1e0 [<ffffffff8106f2b1>] ? get_parent_ip+0x11/0x50 [<ffffffff810f9c55>] ? trace_module_notify+0x25/0x370 [<ffffffff810b65fd>] ? trace_hardirqs_on+0xd/0x10 [<ffffffff814beade>] ? mutex_unlock+0xe/0x10 [<ffffffff810f9c71>] ? trace_module_notify+0x41/0x370 [<ffffffff810a77d5>] ? __blocking_notifier_call_chain+0x45/0x80 [<ffffffff81137b7a>] ? vfree+0x2a/0x30 [<ffffffff810a6ac3>] ? up_read+0x23/0x40 [<ffffffff810a77f5>] ? __blocking_notifier_call_chain+0x65/0x80 [<ffffffff810001e3>] do_one_initcall+0x43/0x180 [<ffffffff810c577a>] sys_init_module+0xba/0x200 [<ffffffff8103819b>] system_call_fastpath+0x16/0x1b RIP [<ffffffff810a1e31>] setup_sgl_buf+0x1a1/0x1b0 RSP <ffff88006720dc98> ---[ end trace a72b979fd3c1d3a5 ]--- Add the proper initialization to avoid the bug. Signed-off-by: Andrea Righi <arighi@develer.com> Acked-by: Stefani Seibold <stefani@seibold.net> --- samples/kfifo/dma-example.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index b9482c2..03433ca 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c @@ -45,6 +45,7 @@ static int __init example_init(void) printk(KERN_INFO "queue len: %u\n", kfifo_len(&fifo)); + sg_init_table(sg, ARRAY_SIZE(sg)); ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), ...
