From 6787fab28f8d498f8952013e6d5242caecf4c9ea Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 5 Jun 2008 13:38:03 -0700 Subject: [PATCH] Fix "waiting for of0 to become free" message on deldp. Thanks to Murphy for help debugging this. --- datapath/datapath.c | 5 +++++ datapath/forward.c | 18 ++++++++++++++---- datapath/forward.h | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index ed9c557c..20d41cf9 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -415,6 +415,11 @@ static void del_dp(struct datapath *dp) del_switch_port(p); rcu_assign_pointer(dps[dp->dp_idx], NULL); + /* Kill off local_port dev references from buffered packets that have + * associated dst entries. */ + synchronize_rcu(); + fwd_discard_all(); + /* Destroy dp->netdev. (Must follow deleting switch ports since * dp->local_port has a reference to it.) */ dp_dev_destroy(dp); diff --git a/datapath/forward.c b/datapath/forward.c index 2c5410ea..44967203 100644 --- a/datapath/forward.c +++ b/datapath/forward.c @@ -556,6 +556,19 @@ static struct sk_buff *retrieve_skb(uint32_t id) return skb; } +void fwd_discard_all(void) +{ + unsigned long int flags; + int i; + + spin_lock_irqsave(&buffer_lock, flags); + for (i = 0; i < N_PKT_BUFFERS; i++) { + kfree_skb(buffers[i].skb); + buffers[i].skb = NULL; + } + spin_unlock_irqrestore(&buffer_lock, flags); +} + static void discard_skb(uint32_t id) { unsigned long int flags; @@ -572,10 +585,7 @@ static void discard_skb(uint32_t id) void fwd_exit(void) { - int i; - - for (i = 0; i < N_PKT_BUFFERS; i++) - kfree_skb(buffers[i].skb); + fwd_discard_all(); } /* Utility functions. */ diff --git a/datapath/forward.h b/datapath/forward.h index ce4d3b14..05e5ac98 100644 --- a/datapath/forward.h +++ b/datapath/forward.h @@ -27,6 +27,7 @@ int fwd_control_input(struct sw_chain *, const struct sender *, const void *, size_t); uint32_t fwd_save_skb(struct sk_buff *skb); +void fwd_discard_all(void); void fwd_exit(void); -- 2.30.2