From 2848cb494620a13a64a3f862380d709c5977cecb Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Wed, 14 Jul 2010 18:35:58 -0700 Subject: [PATCH] gre: Wait for an RCU grace period before freeing port. We currently remove ports from the GRE hash table and then immediately free the ports. Since received packets could be using that port this can lead to a crash (the port has already been detached from the datapath so this can't happen for transmitted packets). As a result we need to wait for an RCU grace period to elapse before actually freeing the port. In an ideal world we would actually remove the port from the hash table in a hypothetical gre_detach() function since this is one of the purposes of detaching. However, we also use the hash table to look for collisions in the lookup criteria and don't want to allow two identical ports to exist. It doesn't matter though because we aren't blocking on the freeing of resources. --- datapath/vport-gre.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index 883e5dc29..33966db4d 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -55,6 +55,7 @@ struct mutable_config { }; struct gre_vport { + struct rcu_head rcu; struct tbl_node tbl_node; char name[IFNAMSIZ]; @@ -1296,6 +1297,14 @@ error: return err; } +static void free_port(struct rcu_head *rcu) +{ + struct gre_vport *gre_vport = container_of(rcu, struct gre_vport, rcu); + + kfree(gre_vport->mutable); + vport_free(gre_vport_to_vport(gre_vport)); +} + static int gre_destroy(struct vport *vport) { struct gre_vport *gre_vport = gre_vport_priv(vport); @@ -1314,8 +1323,7 @@ static int gre_destroy(struct vport *vport) gre_vport->mutable->port_config.in_key, port_type, &old_mutable)) del_port(vport); - kfree(gre_vport->mutable); - vport_free(vport); + call_rcu(&gre_vport->rcu, free_port); return 0; } -- 2.43.0