openvswitch: Fix kernel panic on ovs_flow_free
Both mega flow mask's reference counter and per flow table mask list should only be accessed when holding ovs_mutex() lock. However this is not true with ovs_flow_table_flush(). The patch fixes this bug. Reported-by: Joe Stringer <joestringer@nicira.com> Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
		
					parent
					
						
							
								aea0bb4f8e
							
						
					
				
			
			
				commit
				
					
						e80857cce8
					
				
			
		
					 3 changed files with 48 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -55,6 +55,7 @@
 | 
			
		|||
 | 
			
		||||
#include "datapath.h"
 | 
			
		||||
#include "flow.h"
 | 
			
		||||
#include "flow_table.h"
 | 
			
		||||
#include "flow_netlink.h"
 | 
			
		||||
#include "vport-internal_dev.h"
 | 
			
		||||
#include "vport-netdev.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +161,6 @@ static void destroy_dp_rcu(struct rcu_head *rcu)
 | 
			
		|||
{
 | 
			
		||||
	struct datapath *dp = container_of(rcu, struct datapath, rcu);
 | 
			
		||||
 | 
			
		||||
	ovs_flow_tbl_destroy(&dp->table);
 | 
			
		||||
	free_percpu(dp->stats_percpu);
 | 
			
		||||
	release_net(ovs_dp_get_net(dp));
 | 
			
		||||
	kfree(dp->ports);
 | 
			
		||||
| 
						 | 
				
			
			@ -1287,7 +1287,7 @@ err_destroy_ports_array:
 | 
			
		|||
err_destroy_percpu:
 | 
			
		||||
	free_percpu(dp->stats_percpu);
 | 
			
		||||
err_destroy_table:
 | 
			
		||||
	ovs_flow_tbl_destroy(&dp->table);
 | 
			
		||||
	ovs_flow_tbl_destroy(&dp->table, false);
 | 
			
		||||
err_free_dp:
 | 
			
		||||
	release_net(ovs_dp_get_net(dp));
 | 
			
		||||
	kfree(dp);
 | 
			
		||||
| 
						 | 
				
			
			@ -1314,10 +1314,13 @@ static void __dp_destroy(struct datapath *dp)
 | 
			
		|||
	list_del_rcu(&dp->list_node);
 | 
			
		||||
 | 
			
		||||
	/* OVSP_LOCAL is datapath internal port. We need to make sure that
 | 
			
		||||
	 * all port in datapath are destroyed first before freeing datapath.
 | 
			
		||||
	 * all ports in datapath are destroyed first before freeing datapath.
 | 
			
		||||
	 */
 | 
			
		||||
	ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
 | 
			
		||||
 | 
			
		||||
	/* RCU destroy the flow table */
 | 
			
		||||
	ovs_flow_tbl_destroy(&dp->table, true);
 | 
			
		||||
 | 
			
		||||
	call_rcu(&dp->rcu, destroy_dp_rcu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue