ovs_actions is a per-CPU variable and relies on disabled BH for its locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT this data structure requires explicit locking. The data structure can be referenced recursive and there is a recursion counter to avoid too many recursions.
Add a local_lock_t to the data structure and use local_lock_nested_bh() for locking. Add an owner of the struct which is the current task and acquire the lock only if the structure is not owned by the current task. Cc: Pravin B Shelar <[email protected]> Cc: [email protected] Signed-off-by: Sebastian Andrzej Siewior <[email protected]> --- net/openvswitch/actions.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 322ca7b30c3bc..c4131e04c1284 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -82,6 +82,8 @@ struct ovs_action { struct action_fifo action_fifos; struct action_flow_keys flow_keys; int exec_level; + struct task_struct *owner; + local_lock_t bh_lock; }; static DEFINE_PER_CPU(struct ovs_action, ovs_actions); @@ -1690,8 +1692,14 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, const struct sw_flow_actions *acts, struct sw_flow_key *key) { + struct ovs_action *ovs_act = this_cpu_ptr(&ovs_actions); int err, level; + if (ovs_act->owner != current) { + local_lock_nested_bh(&ovs_actions.bh_lock); + ovs_act->owner = current; + } + level = __this_cpu_inc_return(ovs_actions.exec_level); if (unlikely(level > OVS_RECURSION_LIMIT)) { net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n", @@ -1710,5 +1718,10 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, out: __this_cpu_dec(ovs_actions.exec_level); + + if (level == 1) { + ovs_act->owner = NULL; + local_unlock_nested_bh(&ovs_actions.bh_lock); + } return err; } -- 2.47.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
