From: Ido Schimmel <ido...@mellanox.com>

As explained in the previous commits, we need to process FIB entries
addition / deletion events in FIFO order or otherwise we can have a
mismatch between the kernel's FIB table and the device's.

Create an ordered workqueue for rocker to which these work items will be
submitted to.

Signed-off-by: Ido Schimmel <ido...@mellanox.com>
Signed-off-by: Jiri Pirko <j...@mellanox.com>
---
 drivers/net/ethernet/rocker/rocker.h      |  1 +
 drivers/net/ethernet/rocker/rocker_main.c | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/rocker/rocker.h 
b/drivers/net/ethernet/rocker/rocker.h
index 2eb9b49..ee9675d 100644
--- a/drivers/net/ethernet/rocker/rocker.h
+++ b/drivers/net/ethernet/rocker/rocker.h
@@ -72,6 +72,7 @@ struct rocker {
        struct rocker_dma_ring_info event_ring;
        struct notifier_block fib_nb;
        struct rocker_world_ops *wops;
+       struct workqueue_struct *rocker_owq;
        void *wpriv;
 };
 
diff --git a/drivers/net/ethernet/rocker/rocker_main.c 
b/drivers/net/ethernet/rocker/rocker_main.c
index 67df4cf..424be96 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -28,6 +28,7 @@
 #include <linux/if_bridge.h>
 #include <linux/bitops.h>
 #include <linux/ctype.h>
+#include <linux/workqueue.h>
 #include <net/switchdev.h>
 #include <net/rtnetlink.h>
 #include <net/netevent.h>
@@ -2754,6 +2755,13 @@ static int rocker_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
                goto err_request_event_irq;
        }
 
+       rocker->rocker_owq = alloc_ordered_workqueue(rocker_driver_name,
+                                                    WQ_MEM_RECLAIM);
+       if (!rocker->rocker_owq) {
+               err = -ENOMEM;
+               goto err_alloc_ordered_workqueue;
+       }
+
        rocker->hw.id = rocker_read64(rocker, SWITCH_ID);
 
        err = rocker_probe_ports(rocker);
@@ -2771,6 +2779,8 @@ static int rocker_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
        return 0;
 
 err_probe_ports:
+       destroy_workqueue(rocker->rocker_owq);
+err_alloc_ordered_workqueue:
        free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
 err_request_event_irq:
        free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_CMD), rocker);
@@ -2799,6 +2809,7 @@ static void rocker_remove(struct pci_dev *pdev)
        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);
        rocker_dma_rings_fini(rocker);
-- 
2.7.4

Reply via email to