aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ax25/af_ax25.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index ecb14ee00498..b4725ff317c0 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -87,10 +87,22 @@ static void ax25_kill_by_device(struct net_device *dev)
87 return; 87 return;
88 88
89 spin_lock_bh(&ax25_list_lock); 89 spin_lock_bh(&ax25_list_lock);
90again:
90 ax25_for_each(s, node, &ax25_list) { 91 ax25_for_each(s, node, &ax25_list) {
91 if (s->ax25_dev == ax25_dev) { 92 if (s->ax25_dev == ax25_dev) {
92 s->ax25_dev = NULL; 93 s->ax25_dev = NULL;
94 spin_unlock_bh(&ax25_list_lock);
93 ax25_disconnect(s, ENETUNREACH); 95 ax25_disconnect(s, ENETUNREACH);
96 spin_lock_bh(&ax25_list_lock);
97
98 /* The entry could have been deleted from the
99 * list meanwhile and thus the next pointer is
100 * no longer valid. Play it safe and restart
101 * the scan. Forward progress is ensured
102 * because we set s->ax25_dev to NULL and we
103 * are never passed a NULL 'dev' argument.
104 */
105 goto again;
94 } 106 }
95 } 107 }
96 spin_unlock_bh(&ax25_list_lock); 108 spin_unlock_bh(&ax25_list_lock);