diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 631a03136fa1..218703414325 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1921,6 +1921,10 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) ovs_unlock(); + /* Start periodic mask rebalancing if it wasn't already. */ + schedule_delayed_work(&ovs_net->masks_rebalance, + DP_MASKS_REBALANCE_INTERVAL); + ovs_notify(&dp_datapath_genl_family, reply, info); return 0; @@ -2598,16 +2602,20 @@ static void ovs_dp_masks_rebalance(struct work_struct *work) struct ovs_net *ovs_net = container_of(work, struct ovs_net, masks_rebalance.work); struct datapath *dp; + bool rearm; ovs_lock(); list_for_each_entry(dp, &ovs_net->dps, list_node) ovs_flow_masks_rebalance(&dp->table); + rearm = !list_empty(&ovs_net->dps); + ovs_unlock(); - schedule_delayed_work(&ovs_net->masks_rebalance, - msecs_to_jiffies(DP_MASKS_REBALANCE_INTERVAL)); + if (rearm) + schedule_delayed_work(&ovs_net->masks_rebalance, + DP_MASKS_REBALANCE_INTERVAL); } static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = { @@ -2713,8 +2721,6 @@ static int __net_init ovs_init_net(struct net *net) if (err) return err; - schedule_delayed_work(&ovs_net->masks_rebalance, - msecs_to_jiffies(DP_MASKS_REBALANCE_INTERVAL)); return 0; } diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index b2c2b8da12d4..7a7afaeceee5 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -23,7 +23,7 @@ #define DP_MAX_PORTS USHRT_MAX #define DP_VPORT_HASH_BUCKETS 1024 -#define DP_MASKS_REBALANCE_INTERVAL 4000 +#define DP_MASKS_REBALANCE_INTERVAL msecs_to_jiffies(4000) /** * struct dp_stats_percpu - per-cpu packet processing statistics for a given