diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h index 2b7c947ff4f2..bd4399758ed4 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.h +++ b/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -94,6 +94,7 @@ struct nfp_fl_stats_id { * @ipv6_off_lock: Lock for the IPv6 address list * @mac_off_ids: IDA to manage id assignment for offloaded MACs * @neigh_nb: Notifier to monitor neighbour state + * @neigh_wq: Workqueue for neighbour updates */ struct nfp_fl_tunnel_offloads { struct rhashtable offloaded_macs; @@ -103,6 +104,7 @@ struct nfp_fl_tunnel_offloads { struct mutex ipv6_off_lock; struct ida mac_off_ids; struct notifier_block neigh_nb; + struct workqueue_struct *neigh_wq; }; /** diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index 3b47e9fe64e1..46b6cda7f3d3 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -736,7 +736,7 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, if (!update_work) return NOTIFY_DONE; - queue_work(system_highpri_wq, &update_work->work); + queue_work(app_priv->tun.neigh_wq, &update_work->work); return NOTIFY_DONE; } @@ -1509,6 +1509,13 @@ int nfp_tunnel_config_start(struct nfp_app *app) if (err) return err; + priv->tun.neigh_wq = alloc_workqueue("nfp-flower-neigh", + WQ_HIGHPRI | WQ_PERCPU, 0); + if (!priv->tun.neigh_wq) { + err = -ENOMEM; + goto err_free_macs; + } + ida_init(&priv->tun.mac_off_ids); /* Initialise priv data for IPv4/v6 offloading. */ @@ -1521,13 +1528,17 @@ int nfp_tunnel_config_start(struct nfp_app *app) priv->tun.neigh_nb.notifier_call = nfp_tun_neigh_event_handler; err = register_netevent_notifier(&priv->tun.neigh_nb); - if (err) { - rhashtable_free_and_destroy(&priv->tun.offloaded_macs, - nfp_check_rhashtable_empty, NULL); - return err; - } + if (err) + goto err_destroy_neigh_wq; return 0; + +err_destroy_neigh_wq: + destroy_workqueue(priv->tun.neigh_wq); +err_free_macs: + rhashtable_free_and_destroy(&priv->tun.offloaded_macs, + nfp_check_rhashtable_empty, NULL); + return err; } void nfp_tunnel_config_stop(struct nfp_app *app) @@ -1537,6 +1548,7 @@ void nfp_tunnel_config_stop(struct nfp_app *app) struct list_head *ptr, *storage; unregister_netevent_notifier(&priv->tun.neigh_nb); + destroy_workqueue(priv->tun.neigh_wq); ida_destroy(&priv->tun.mac_off_ids);