lkml.org 
[lkml]   [2013]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[BUG] zynq | CCF | SRCU
Hi,

we recently encountered some kernel panics when we compiled one of our
drivers as module and tested inserting/removing the module.
Trying to debug this issue, I could reproduce it on the mainline kernel
with a dummy module.

What happens is, that when on driver remove clk_notifier_unregister() is
called and no other notifier for that clock is registered, the kernel
panics.
I'm not sure what is going wrong here. If there is a bug (and if where)
or I'm just using the infrastructure the wrong way,... So, any hint is
appreciated.

I attach the output from the crashing system. The stacktrace indicates a
crash in 'srcu_readers_seq_idx()'.
I also attach the module I used to trigger the issue and a patch on top
of mainline commit a93cb29acaa8f75618c3f202d1cf43c231984644 which has
the DT modifications I need to make the module find its clock and boot
with my initramfs.


Thanks,
Sören

#include <linux/init.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/notifier.h>

static struct clk *clk;
static struct notifier_block nb;

static int clk_notif_dbg_cb(struct notifier_block *nb,
unsigned long event, void *data)
{
pr_info("clk_notif_dbg_cb\n");

return NOTIFY_OK;
}

static int clk_notif_dbg_probe(struct platform_device *pdev)
{
nb.next = NULL;
nb.notifier_call = clk_notif_dbg_cb;

dev_info(&pdev->dev, "clk_get()\n");
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "clk_get failed\n");
return PTR_ERR(clk);
}
dev_info(&pdev->dev, "clk_prepare()\n");
if (clk_prepare(clk))
dev_warn(&pdev->dev, "clk_prepare failed\n");
dev_info(&pdev->dev, "clk_enable()\n");
if (clk_enable(clk))
dev_warn(&pdev->dev, "clk_enable failed\n");
dev_info(&pdev->dev, "clk_notifier_register()\n");
if (clk_notifier_register(clk, &nb))
dev_warn(&pdev->dev, "clk_notifier_register failed\n");

dev_info(&pdev->dev, "probe done\n");

return 0;
}

static int clk_notif_dbg_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev, "clk_notifier_unregister()\n");
clk_notifier_unregister(clk, &nb);
dev_info(&pdev->dev, "clk_disable()\n");
clk_disable(clk);
dev_info(&pdev->dev, "clk_unprepare()\n");
clk_unprepare(clk);
dev_info(&pdev->dev, "clk_put()\n");
clk_put(clk);

dev_info(&pdev->dev, "remove done\n");

return 0;
}

/* Match table for device tree binding */
static const struct of_device_id clk_notif_dbg_of_match[] = {
{.compatible = "clk_notif_dbg"},
{ },
};
MODULE_DEVICE_TABLE(of, clk_notif_dbg_of_match);

static struct platform_driver clk_notif_dbg_driver = {
.probe = clk_notif_dbg_probe,
.remove = clk_notif_dbg_remove,
.driver = {
.name = "clk_notif_dbg",
.owner = THIS_MODULE,
.of_match_table = clk_notif_dbg_of_match,
},
};
module_platform_driver(clk_notif_dbg_driver);

MODULE_AUTHOR("Xilinx, Inc.");
MODULE_DESCRIPTION("Clock notifier debug");
MODULE_LICENSE("GPL");

From c8beabc1ee2b3107ef045de744ccf5ab1458e5b0 Mon Sep 17 00:00:00 2001
From: Soren Brinkmann <soren.brinkmann@xilinx.com>
Date: Fri, 31 May 2013 11:56:51 -0700
Subject: [PATCH] zynq: Clock notify debug on zc702

Changes to make the kernel boot with my initramfs + the DT fragment for
the debugging module.

Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
---
arch/arm/boot/dts/zynq-7000.dtsi | 6 ++++++
arch/arm/boot/dts/zynq-zc702.dts | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index 14fb2e6..b22651a 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -38,6 +38,11 @@
<0xF8F00100 0x100>;
};

+ clk_notif_dbg: clk_notif_dbg {
+ compatible = "clk_notif_dbg";
+ clocks = <&uart_clk 0>;
+ };
+
L2: cache-controller {
compatible = "arm,pl310-cache";
reg = <0xF8F02000 0x1000>;
@@ -48,6 +53,7 @@
};

uart0: uart@e0000000 {
+ status = "disabled";
compatible = "xlnx,xuartps";
reg = <0xE0000000 0x1000>;
interrupts = <0 27 4>;
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index 86f44d5..33df5cd 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -24,7 +24,7 @@
};

chosen {
- bootargs = "console=ttyPS1,115200 earlyprintk";
+ bootargs = "console=ttyPS0,115200 earlyprintk";
};

};
--
1.8.3
\
 
 \ /
  Last update: 2013-05-31 22:01    [W:0.082 / U:0.144 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site