We should use of_get_next_child() in __eeh_clear_slot() to safely
traverse the node's children.

To achieve this we need to change __eeh_clear_slot() to take the parent
node, not the child. This is also safer, as passing anything other than
node->child to the existing routine will not traverse all peers, only
those deeper in the sibling list.

Signed-off-by: Michael Ellerman <[EMAIL PROTECTED]>
---
 arch/powerpc/platforms/pseries/eeh.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/eeh.c 
b/arch/powerpc/platforms/pseries/eeh.c
index d06ab36..1537597 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -412,16 +412,17 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
        __eeh_mark_slot(dn, mode_flag);
 }
 
-static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
+static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
 {
-       while (dn) {
+       struct device_node *dn;
+
+       for (dn = NULL; (dn = of_get_next_child(parent, dn));) {
                if (PCI_DN(dn)) {
                        PCI_DN(dn)->eeh_mode &= ~mode_flag;
                        PCI_DN(dn)->eeh_check_count = 0;
                        if (dn->child)
-                               __eeh_clear_slot (dn->child, mode_flag);
+                               __eeh_clear_slot(dn, mode_flag);
                }
-               dn = dn->sibling;
        }
 }
 
@@ -438,7 +439,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
 
        PCI_DN(dn)->eeh_mode &= ~mode_flag;
        PCI_DN(dn)->eeh_check_count = 0;
-       __eeh_clear_slot (dn->child, mode_flag);
+       __eeh_clear_slot(dn, mode_flag);
        spin_unlock_irqrestore(&confirm_error_lock, flags);
 }
 
-- 
1.5.2.rc1.1884.g59b20

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to