From 6a281856c02d2291df2f7d9df5bfdee2e7bdd747 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 19 Jun 2007 16:08:00 +1000 Subject: [POWERPC] Add a warning to help trackdown device_node refcounting bugs When the refcount for a device node goes to 0, we call the destructor - of_node_release(). This should only happen if we've already detached the node from the device tree. So add a flag OF_DETACHED which tracks detached-ness, and if we find ourselves in of_node_release() without it set, issue a warning and don't free the device_node. To avoid warning continuously reinitialise the kref to a sane value. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/powerpc/kernel/prom.c') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index bcd1c5ed44a3..6d5e601097a0 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1375,8 +1375,17 @@ static void of_node_release(struct kref *kref) struct device_node *node = kref_to_device_node(kref); struct property *prop = node->properties; + /* We should never be releasing nodes that haven't been detached. */ + if (!of_node_check_flag(node, OF_DETACHED)) { + printk("WARNING: Bad of_node_put() on %s\n", node->full_name); + dump_stack(); + kref_init(&node->kref); + return; + } + if (!of_node_check_flag(node, OF_DYNAMIC)) return; + while (prop) { struct property *next = prop->next; kfree(prop->name); @@ -1457,6 +1466,8 @@ void of_detach_node(const struct device_node *np) prevsib->sibling = np->sibling; } + of_node_set_flag(np, OF_DETACHED); + out_unlock: write_unlock(&devtree_lock); } -- cgit v1.2.3-59-g8ed1b