提交 6a281856 编写于 作者: M Michael Ellerman 提交者: Paul Mackerras

[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: NMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: NPaul Mackerras <paulus@samba.org>
上级 d3b814bb
...@@ -1375,8 +1375,17 @@ static void of_node_release(struct kref *kref) ...@@ -1375,8 +1375,17 @@ static void of_node_release(struct kref *kref)
struct device_node *node = kref_to_device_node(kref); struct device_node *node = kref_to_device_node(kref);
struct property *prop = node->properties; 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)) if (!of_node_check_flag(node, OF_DYNAMIC))
return; return;
while (prop) { while (prop) {
struct property *next = prop->next; struct property *next = prop->next;
kfree(prop->name); kfree(prop->name);
...@@ -1457,6 +1466,8 @@ void of_detach_node(const struct device_node *np) ...@@ -1457,6 +1466,8 @@ void of_detach_node(const struct device_node *np)
prevsib->sibling = np->sibling; prevsib->sibling = np->sibling;
} }
of_node_set_flag(np, OF_DETACHED);
out_unlock: out_unlock:
write_unlock(&devtree_lock); write_unlock(&devtree_lock);
} }
......
...@@ -99,6 +99,7 @@ extern struct device_node *of_chosen; ...@@ -99,6 +99,7 @@ extern struct device_node *of_chosen;
/* flag descriptions */ /* flag descriptions */
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
#define OF_DETACHED 2 /* node has been detached from the device tree */
static inline int of_node_check_flag(struct device_node *n, unsigned long flag) static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册