From f339d751dba7687d76a40eb327a9f40748725d9b Mon Sep 17 00:00:00 2001 From: Ratheesh Kannoth Date: Mon, 13 Jul 2020 10:35:07 +0530 Subject: [PATCH] net: openvswitch: Use sleepable rcu Change-Id: Iab03855cb7f9cd2a7b584fa22780adf6772b92f1 Signed-off-by: Pavithra R --- net/openvswitch/datapath.c | 44 +++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e43916893b14..47c86f23479d 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -49,7 +49,8 @@ #include "vport-netdev.h" unsigned int ovs_net_id __read_mostly; -static struct ovs_accel_callback *ovs_accel_cb; +static struct ovs_accel_callback __rcu *ovs_accel_cb; +static struct srcu_struct ovs_accel_cb_sp_rcu; static struct genl_family dp_packet_genl_family; static struct genl_family dp_flow_genl_family; @@ -225,12 +226,11 @@ void ovs_dp_detach_port(struct vport *p) static void ovs_dp_add_notify(struct datapath *dp, struct vport *vp) { struct ovs_accel_callback *ovs_cb; - - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_add) ovs_cb->ovs_accel_dp_add((void *)dp, vp->dev); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath delete event to acceleration callback */ @@ -238,11 +238,11 @@ static void ovs_dp_del_notify(struct datapath *dp, struct vport *vp) { struct ovs_accel_callback *ovs_cb; - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_del) ovs_cb->ovs_accel_dp_del((void *)dp, vp->dev); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath port add event to acceleration callback */ @@ -251,17 +251,18 @@ static void ovs_dp_port_add_notify(struct datapath *dp, struct vport *vp, { struct ovs_accel_callback *ovs_cb; const char *master = NULL; + int idx; if (a[OVS_VPORT_ATTR_MASTER]) master = nla_data(a[OVS_VPORT_ATTR_MASTER]); - rcu_read_lock(); + idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_port_add) ovs_cb->ovs_accel_dp_port_add((void *)dp, (void *)vp, vp->port_no, vp->ops->type, master, vp->dev); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath port delete event to acceleration callback */ @@ -269,11 +270,11 @@ static void ovs_dp_port_del_notify(struct datapath *dp, struct vport *vp) { struct ovs_accel_callback *ovs_cb; - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_port_del) ovs_cb->ovs_accel_dp_port_del((void *)dp, (void *)vp, vp->dev); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath flow add event to acceleration callback */ @@ -281,11 +282,11 @@ static void ovs_dp_flow_add_notify(struct datapath *dp, struct sw_flow *sf) { struct ovs_accel_callback *ovs_cb; - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_flow_add) ovs_cb->ovs_accel_dp_flow_add((void *)dp, sf); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath flow delete event to acceleration callback */ @@ -293,11 +294,11 @@ static void ovs_dp_flow_del_notify(struct datapath *dp, struct sw_flow *sf) { struct ovs_accel_callback *ovs_cb; - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_flow_del) ovs_cb->ovs_accel_dp_flow_del((void *)dp, sf); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath flow table flush event to acceleration callback */ @@ -305,11 +306,11 @@ static void ovs_dp_flow_tbl_flush_notify(struct datapath *dp) { struct ovs_accel_callback *ovs_cb; - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_flow_tbl_flush) ovs_cb->ovs_accel_dp_flow_tbl_flush((void *)dp); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Notify datapath flow set/change event to acceleration callback */ @@ -318,11 +319,11 @@ static void ovs_dp_flow_set_notify(struct datapath *dp, struct sw_flow *sf, { struct ovs_accel_callback *ovs_cb; - rcu_read_lock(); + int idx = srcu_read_lock(&ovs_accel_cb_sp_rcu); ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_flow_set) ovs_cb->ovs_accel_dp_flow_set((void *)dp, sf, new_sfa); - rcu_read_unlock(); + srcu_read_unlock(&ovs_accel_cb_sp_rcu, idx); } /* Forward datapath packet to acceleration callback @@ -334,8 +335,6 @@ static void ovs_dp_pkt_process_notify(struct datapath *dp, struct sk_buff *skb, { struct ovs_accel_callback *ovs_cb; - WARN_ON(!rcu_read_lock_held()); - ovs_cb = rcu_dereference(ovs_accel_cb); if (ovs_cb && ovs_cb->ovs_accel_dp_pkt_process) ovs_cb->ovs_accel_dp_pkt_process((void *)dp, skb, key, sf, sfa); @@ -2558,6 +2557,7 @@ int ovs_register_accelerator(struct ovs_accel_callback *oac) rcu_assign_pointer(ovs_accel_cb, oac); ovs_unlock(); + synchronize_srcu(&ovs_accel_cb_sp_rcu); return 0; } EXPORT_SYMBOL(ovs_register_accelerator); @@ -2568,6 +2568,7 @@ void ovs_unregister_accelerator(struct ovs_accel_callback *oac) ovs_lock(); rcu_assign_pointer(ovs_accel_cb, NULL); ovs_unlock(); + synchronize_srcu(&ovs_accel_cb_sp_rcu); } EXPORT_SYMBOL(ovs_unregister_accelerator); @@ -2973,6 +2974,8 @@ static int __init dp_init(void) pr_info("Open vSwitch switching datapath\n"); + init_srcu_struct(&ovs_accel_cb_sp_rcu); + err = action_fifos_init(); if (err) goto error; @@ -3022,6 +3025,7 @@ static int __init dp_init(void) error_action_fifos_exit: action_fifos_exit(); error: + cleanup_srcu_struct(&ovs_accel_cb_sp_rcu); return err; } -- 2.34.1