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

Reply via email to