diff options
Diffstat (limited to 'net/openvswitch/vport.c')
| -rw-r--r-- | net/openvswitch/vport.c | 18 | 
1 files changed, 16 insertions, 2 deletions
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 7e0f5c45b512..972ae01a70f7 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -124,6 +124,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,  {  	struct vport *vport;  	size_t alloc_size; +	int err;  	alloc_size = sizeof(struct vport);  	if (priv_size) { @@ -135,17 +136,29 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,  	if (!vport)  		return ERR_PTR(-ENOMEM); +	vport->upcall_stats = netdev_alloc_pcpu_stats(struct vport_upcall_stats_percpu); +	if (!vport->upcall_stats) { +		err = -ENOMEM; +		goto err_kfree_vport; +	} +  	vport->dp = parms->dp;  	vport->port_no = parms->port_no;  	vport->ops = ops;  	INIT_HLIST_NODE(&vport->dp_hash_node);  	if (ovs_vport_set_upcall_portids(vport, parms->upcall_portids)) { -		kfree(vport); -		return ERR_PTR(-EINVAL); +		err = -EINVAL; +		goto err_free_percpu;  	}  	return vport; + +err_free_percpu: +	free_percpu(vport->upcall_stats); +err_kfree_vport: +	kfree(vport); +	return ERR_PTR(err);  }  EXPORT_SYMBOL_GPL(ovs_vport_alloc); @@ -165,6 +178,7 @@ void ovs_vport_free(struct vport *vport)  	 * it is safe to use raw dereference.  	 */  	kfree(rcu_dereference_raw(vport->upcall_portids)); +	free_percpu(vport->upcall_stats);  	kfree(vport);  }  EXPORT_SYMBOL_GPL(ovs_vport_free);  | 
