diff options
author | Ido Schimmel <idosch@mellanox.com> | 2016-12-03 16:45:02 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-12-03 19:29:35 -0500 |
commit | c1bb279cfa9d079bdee35402f5d13210f25f5c80 (patch) | |
tree | 2f234ed7d730ebc0306c9d729dabd4e51bd8796f /drivers/net/ethernet/rocker | |
parent | 3057224e014c14921de5ab534d5147eb109fd12b (diff) | |
download | linux-c1bb279cfa9d079bdee35402f5d13210f25f5c80.tar.bz2 |
rocker: Create an ordered workqueue for FIB offload
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>
Diffstat (limited to 'drivers/net/ethernet/rocker')
-rw-r--r-- | drivers/net/ethernet/rocker/rocker.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/rocker/rocker_main.c | 11 |
2 files changed, 12 insertions, 0 deletions
diff --git a/drivers/net/ethernet/rocker/rocker.h b/drivers/net/ethernet/rocker/rocker.h index 2eb9b49569d5..ee9675db5bf9 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 67df4cf93362..424be969da3f 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); |