rocker: Create an ordered workqueue for FIB offload
authorIdo Schimmel <idosch@mellanox.com>
Sat, 3 Dec 2016 15:45:02 +0000 (16:45 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 4 Dec 2016 00:29:35 +0000 (19:29 -0500)
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 <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.h
drivers/net/ethernet/rocker/rocker_main.c

index 2eb9b49569d584e133a3fd1f0e0957c39926fc19..ee9675db5bf953b92cf46ead04e19f744ba36204 100644 (file)
@@ -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;
 };
 
index 67df4cf93362eaa1a7e9eeda9d3aab3dcc333f75..424be969da3f3087a54fc51b2fc0bfc78db8d5f3 100644 (file)
@@ -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);