aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.h
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2013-04-15 16:23:03 -0400
committerJesse Gross <jesse@nicira.com>2013-04-15 17:38:40 -0400
commit8e4e1713e4978447c5f799aa668dcc6d2cb0dee9 (patch)
treedc0c2e05b677183d617d74020fa9d1ed28691102 /net/openvswitch/datapath.h
parentb4f9e8cdc82e4a07c3ca50395af5800a6229363e (diff)
openvswitch: Simplify datapath locking.
Currently OVS uses combination of genl and rtnl lock to protect datapath state. This was done due to networking stack locking. But this has complicated locking and there are few lock ordering issues with new tunneling protocols. Following patch simplifies locking by introducing new ovs mutex and now this lock is used to protect entire ovs state. Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch/datapath.h')
-rw-r--r--net/openvswitch/datapath.h69
1 files changed, 47 insertions, 22 deletions
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 655beb1fe078..16b840695216 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -57,9 +57,9 @@ struct dp_stats_percpu {
57 * struct datapath - datapath for flow-based packet switching 57 * struct datapath - datapath for flow-based packet switching
58 * @rcu: RCU callback head for deferred destruction. 58 * @rcu: RCU callback head for deferred destruction.
59 * @list_node: Element in global 'dps' list. 59 * @list_node: Element in global 'dps' list.
60 * @table: Current flow table. Protected by genl_lock and RCU. 60 * @table: Current flow table. Protected by ovs_mutex and RCU.
61 * @ports: Hash table for ports. %OVSP_LOCAL port always exists. Protected by 61 * @ports: Hash table for ports. %OVSP_LOCAL port always exists. Protected by
62 * RTNL and RCU. 62 * ovs_mutex and RCU.
63 * @stats_percpu: Per-CPU datapath statistics. 63 * @stats_percpu: Per-CPU datapath statistics.
64 * @net: Reference to net namespace. 64 * @net: Reference to net namespace.
65 * 65 *
@@ -85,26 +85,6 @@ struct datapath {
85#endif 85#endif
86}; 86};
87 87
88struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no);
89
90static inline struct vport *ovs_vport_rcu(const struct datapath *dp, int port_no)
91{
92 WARN_ON_ONCE(!rcu_read_lock_held());
93 return ovs_lookup_vport(dp, port_no);
94}
95
96static inline struct vport *ovs_vport_rtnl_rcu(const struct datapath *dp, int port_no)
97{
98 WARN_ON_ONCE(!rcu_read_lock_held() && !rtnl_is_locked());
99 return ovs_lookup_vport(dp, port_no);
100}
101
102static inline struct vport *ovs_vport_rtnl(const struct datapath *dp, int port_no)
103{
104 ASSERT_RTNL();
105 return ovs_lookup_vport(dp, port_no);
106}
107
108/** 88/**
109 * struct ovs_skb_cb - OVS data in skb CB 89 * struct ovs_skb_cb - OVS data in skb CB
110 * @flow: The flow associated with this packet. May be %NULL if no flow. 90 * @flow: The flow associated with this packet. May be %NULL if no flow.
@@ -131,6 +111,30 @@ struct dp_upcall_info {
131 u32 portid; 111 u32 portid;
132}; 112};
133 113
114/**
115 * struct ovs_net - Per net-namespace data for ovs.
116 * @dps: List of datapaths to enable dumping them all out.
117 * Protected by genl_mutex.
118 */
119struct ovs_net {
120 struct list_head dps;
121 struct work_struct dp_notify_work;
122};
123
124extern int ovs_net_id;
125void ovs_lock(void);
126void ovs_unlock(void);
127
128#ifdef CONFIG_LOCKDEP
129int lockdep_ovsl_is_held(void);
130#else
131#define lockdep_ovsl_is_held() 1
132#endif
133
134#define ASSERT_OVSL() WARN_ON(unlikely(!lockdep_ovsl_is_held()))
135#define ovsl_dereference(p) \
136 rcu_dereference_protected(p, lockdep_ovsl_is_held())
137
134static inline struct net *ovs_dp_get_net(struct datapath *dp) 138static inline struct net *ovs_dp_get_net(struct datapath *dp)
135{ 139{
136 return read_pnet(&dp->net); 140 return read_pnet(&dp->net);
@@ -141,6 +145,26 @@ static inline void ovs_dp_set_net(struct datapath *dp, struct net *net)
141 write_pnet(&dp->net, net); 145 write_pnet(&dp->net, net);
142} 146}
143 147
148struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no);
149
150static inline struct vport *ovs_vport_rcu(const struct datapath *dp, int port_no)
151{
152 WARN_ON_ONCE(!rcu_read_lock_held());
153 return ovs_lookup_vport(dp, port_no);
154}
155
156static inline struct vport *ovs_vport_ovsl_rcu(const struct datapath *dp, int port_no)
157{
158 WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_ovsl_is_held());
159 return ovs_lookup_vport(dp, port_no);
160}
161
162static inline struct vport *ovs_vport_ovsl(const struct datapath *dp, int port_no)
163{
164 ASSERT_OVSL();
165 return ovs_lookup_vport(dp, port_no);
166}
167
144extern struct notifier_block ovs_dp_device_notifier; 168extern struct notifier_block ovs_dp_device_notifier;
145extern struct genl_multicast_group ovs_dp_vport_multicast_group; 169extern struct genl_multicast_group ovs_dp_vport_multicast_group;
146 170
@@ -154,4 +178,5 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq,
154 u8 cmd); 178 u8 cmd);
155 179
156int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb); 180int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb);
181void ovs_dp_notify_wq(struct work_struct *work);
157#endif /* datapath.h */ 182#endif /* datapath.h */