openvswitch: Refactor get_dp() function into multiple access APIs.
Avoid recursive read_rcu_lock() by using the lighter weight get_dp_rcu() API. Add proper locking assertions to get_dp(). Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
This commit is contained in:
parent
ca7105f278
commit
cc3a5ae6f2
|
@ -140,19 +140,30 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *,
|
||||||
static int queue_userspace_packet(struct datapath *dp, struct sk_buff *,
|
static int queue_userspace_packet(struct datapath *dp, struct sk_buff *,
|
||||||
const struct dp_upcall_info *);
|
const struct dp_upcall_info *);
|
||||||
|
|
||||||
/* Must be called with rcu_read_lock or ovs_mutex. */
|
/* Must be called with rcu_read_lock. */
|
||||||
static struct datapath *get_dp(struct net *net, int dp_ifindex)
|
static struct datapath *get_dp_rcu(struct net *net, int dp_ifindex)
|
||||||
{
|
{
|
||||||
struct datapath *dp = NULL;
|
struct net_device *dev = dev_get_by_index_rcu(net, dp_ifindex);
|
||||||
struct net_device *dev;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
dev = dev_get_by_index_rcu(net, dp_ifindex);
|
|
||||||
if (dev) {
|
if (dev) {
|
||||||
struct vport *vport = ovs_internal_dev_get_vport(dev);
|
struct vport *vport = ovs_internal_dev_get_vport(dev);
|
||||||
if (vport)
|
if (vport)
|
||||||
dp = vport->dp;
|
return vport->dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The caller must hold either ovs_mutex or rcu_read_lock to keep the
|
||||||
|
* returned dp pointer valid.
|
||||||
|
*/
|
||||||
|
static inline struct datapath *get_dp(struct net *net, int dp_ifindex)
|
||||||
|
{
|
||||||
|
struct datapath *dp;
|
||||||
|
|
||||||
|
WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_ovsl_is_held());
|
||||||
|
rcu_read_lock();
|
||||||
|
dp = get_dp_rcu(net, dp_ifindex);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
return dp;
|
return dp;
|
||||||
|
@ -573,7 +584,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
|
||||||
packet->mark = flow->key.phy.skb_mark;
|
packet->mark = flow->key.phy.skb_mark;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
|
dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
if (!dp)
|
if (!dp)
|
||||||
goto err_unlock;
|
goto err_unlock;
|
||||||
|
@ -1227,7 +1238,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
struct datapath *dp;
|
struct datapath *dp;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
|
dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
|
||||||
if (!dp) {
|
if (!dp) {
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -1989,7 +2000,7 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
|
dp = get_dp_rcu(sock_net(skb->sk), ovs_header->dp_ifindex);
|
||||||
if (!dp) {
|
if (!dp) {
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
Loading…
Reference in New Issue