rocker: Register FIB notifier before creating ports
authorIdo Schimmel <idosch@mellanox.com>
Sat, 3 Dec 2016 15:45:04 +0000 (16:45 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 4 Dec 2016 00:29:35 +0000 (19:29 -0500)
We can miss FIB notifications sent between the time the ports were
created and the FIB notification block registered.

Instead of receiving these notifications only when they are replayed for
the FIB notification block during registration, just register the
notification block before the ports are created.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/rocker/rocker_main.c

index 914e9e1b01ad9046db2a9a72c3de8a0412861864..8c9c90ae89627326e6ff3bd559029c6278f7e2ba 100644 (file)
@@ -2804,6 +2804,9 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto err_alloc_ordered_workqueue;
        }
 
+       rocker->fib_nb.notifier_call = rocker_router_fib_event;
+       register_fib_notifier(&rocker->fib_nb);
+
        rocker->hw.id = rocker_read64(rocker, SWITCH_ID);
 
        err = rocker_probe_ports(rocker);
@@ -2812,15 +2815,13 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto err_probe_ports;
        }
 
-       rocker->fib_nb.notifier_call = rocker_router_fib_event;
-       register_fib_notifier(&rocker->fib_nb);
-
        dev_info(&pdev->dev, "Rocker switch with id %*phN\n",
                 (int)sizeof(rocker->hw.id), &rocker->hw.id);
 
        return 0;
 
 err_probe_ports:
+       unregister_fib_notifier(&rocker->fib_nb);
        destroy_workqueue(rocker->rocker_owq);
 err_alloc_ordered_workqueue:
        free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
@@ -2848,9 +2849,9 @@ static void rocker_remove(struct pci_dev *pdev)
 {
        struct rocker *rocker = pci_get_drvdata(pdev);
 
+       rocker_remove_ports(rocker);
        unregister_fib_notifier(&rocker->fib_nb);
        rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
-       rocker_remove_ports(rocker);
        destroy_workqueue(rocker->rocker_owq);
        free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
        free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_CMD), rocker);