Ejemplo n.º 1
0
/**
 *	ovs_vport_set_upcall_portids - set upcall portids of @vport.
 *
 * @vport: vport to modify.
 * @ids: new configuration, an array of port ids.
 *
 * Sets the vport's upcall_portids to @ids.
 *
 * Returns 0 if successful, -EINVAL if @ids is zero length or cannot be parsed
 * as an array of U32.
 *
 * Must be called with ovs_mutex.
 */
int ovs_vport_set_upcall_portids(struct vport *vport, const struct nlattr *ids)
{
	struct vport_portids *old, *vport_portids;

	if (!nla_len(ids) || nla_len(ids) % sizeof(u32))
		return -EINVAL;

    //读保护, rcu_dereference_protected
	old = ovsl_dereference(vport->upcall_portids);

	vport_portids = kmalloc(sizeof *vport_portids + nla_len(ids),
				GFP_KERNEL);
	if (!vport_portids)
		return -ENOMEM;

	vport_portids->n_ids = nla_len(ids) / sizeof(u32);
	vport_portids->rn_ids = reciprocal_value(vport_portids->n_ids);
	nla_memcpy(vport_portids->ids, ids, nla_len(ids));

	rcu_assign_pointer(vport->upcall_portids, vport_portids);

	if (old)
        //等待 old 的所有读者都完成后, 是否 old 指向的内存
		call_rcu(&old->rcu, vport_portids_destroy_rcu_cb);

	return 0;
}
Ejemplo n.º 2
0
/* Called with ovs_mutex. */
void ovs_flow_stats_clear(struct sw_flow *flow)
{
	int node;

	for_each_node(node) {
		struct flow_stats *stats = ovsl_dereference(flow->stats[node]);

		if (stats) {
			spin_lock_bh(&stats->lock);
			stats->used = 0;
			stats->packet_count = 0;
			stats->byte_count = 0;
			stats->tcp_flags = 0;
			spin_unlock_bh(&stats->lock);
		}
	}
}
Ejemplo n.º 3
0
/* Called with ovs_mutex. */
void bpf_dp_disconnect_port(struct vport *p)
{
	struct datapath *dp = p->dp;
	struct plum *plum, *dest_plum;
	u32 dest;

	if (p->port_no == OVSP_LOCAL || p->port_no >= PLUM_MAX_PORTS)
		return;

	plum = ovsl_dereference(dp->plums[0]);

	dest = atomic_read(&plum->ports[p->port_no]);
	if (dest) {
		dest_plum = ovsl_dereference(dp->plums[dest >> 16]);
		atomic_set(&dest_plum->ports[dest & 0xffff], 0);
	}
	atomic_set(&plum->ports[p->port_no], 0);
	smp_wmb();

	/* leave the stats allocated until plum is freed */
}
Ejemplo n.º 4
0
Archivo: vport.c Proyecto: JunoZhu/ovs
/**
 *	ovs_vport_set_upcall_portids - set upcall portids of @vport.
 *
 * @vport: vport to modify.
 * @ids: new configuration, an array of port ids.
 *
 * Sets the vport's upcall_portids to @ids.
 *
 * Returns 0 if successful, -EINVAL if @ids is zero length or cannot be parsed
 * as an array of U32.
 *
 * Must be called with ovs_mutex.
 */
int ovs_vport_set_upcall_portids(struct vport *vport, const struct nlattr *ids)
{
	struct vport_portids *old, *vport_portids;

	if (!nla_len(ids) || nla_len(ids) % sizeof(u32))
		return -EINVAL;

	old = ovsl_dereference(vport->upcall_portids);

	vport_portids = kmalloc(sizeof(*vport_portids) + nla_len(ids),
				GFP_KERNEL);
	if (!vport_portids)
		return -ENOMEM;

	vport_portids->n_ids = nla_len(ids) / sizeof(u32);
	vport_portids->rn_ids = reciprocal_value(vport_portids->n_ids);
	nla_memcpy(vport_portids->ids, ids, nla_len(ids));

	rcu_assign_pointer(vport->upcall_portids, vport_portids);

	if (old)
		kfree_rcu(old, rcu);
	return 0;
}
Ejemplo n.º 5
0
void ovs_flow_tbl_destroy(struct flow_table *table)
{
	struct table_instance *ti = ovsl_dereference(table->ti);

	table_instance_destroy(ti, false);
}