/*
- * Copyright (c) 2007, 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2007, 2008, 2009, 2010, 2011 Nicira Networks.
* Distributed under the terms of the GNU GPL version 2.
*
* Significant portions of this file may be copied from parts of the Linux
#include "table.h"
#include "vport-internal_dev.h"
-#include "compat.h"
-
int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd);
EXPORT_SYMBOL(dp_ioctl_hook);
return dp;
}
-static struct tbl *get_table_protected(const struct datapath *dp)
+static struct tbl *get_table_protected(struct datapath *dp)
{
return rcu_dereference_protected(dp->table,
lockdep_is_held(&dp->mutex));
}
-static struct vport *get_vport_protected(const struct datapath *dp,
- u16 port_no)
+static struct vport *get_vport_protected(struct datapath *dp, u16 port_no)
{
return rcu_dereference_protected(dp->ports[port_no],
lockdep_is_held(&dp->mutex));
const struct vport *port,
int event, unsigned int flags)
{
- const struct datapath *dp = port->dp;
+ struct datapath *dp = port->dp;
int ifindex = vport_get_ifindex(port);
int iflink = vport_get_iflink(port);
struct ifinfomsg *hdr;
return err;
}
+static void destroy_dp_rcu(struct rcu_head *rcu)
+{
+ struct datapath *dp = container_of(rcu, struct datapath, rcu);
+ int i;
+
+ for (i = 0; i < DP_N_QUEUES; i++)
+ skb_queue_purge(&dp->queues[i]);
+
+ tbl_destroy((struct tbl __force *)dp->table, flow_free_tbl);
+ free_percpu(dp->stats_percpu);
+ kobject_put(&dp->ifobj);
+}
+
static int destroy_dp(int dp_idx)
{
struct datapath *dp;
int err = 0;
struct vport *p, *n;
- int i;
rtnl_lock();
mutex_lock(&dp_mutex);
dp_detach_port(p);
dp_sysfs_del_dp(dp);
-
rcu_assign_pointer(dps[dp->dp_idx], NULL);
-
dp_detach_port(get_vport_protected(dp, ODPP_LOCAL));
- tbl_destroy(get_table_protected(dp), flow_free_tbl);
-
- for (i = 0; i < DP_N_QUEUES; i++)
- skb_queue_purge(&dp->queues[i]);
- free_percpu(dp->stats_percpu);
mutex_unlock(&dp->mutex);
- kobject_put(&dp->ifobj);
+ call_rcu(&dp->rcu, destroy_dp_rcu);
module_put(THIS_MODULE);
out: