Re: [GIT]: Networking
flat view
From: David Miller <davem@davemloft.net>
Date: 2009-06-16 10:48:00
Also in:
lkml
Subsystem:
networking [general], the rest, x.25 stack · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Martin Schiller
From: Ingo Molnar <redacted> Date: Tue, 16 Jun 2009 11:15:38 +0200
hm, FYI, these bits caused widespread scheduling-while-atomic
problems on most of my test-systems:
BUG: sleeping function called from invalid context at net/core/sock.c:1851
in_atomic(): 1, irqs_disabled(): 0, pid: 544, name: rcu_torture_rea
1 lock held by rcu_torture_rea/544:
#0: (&sk->sk_timer){......}, at: [<ffffffff81060560>] run_timer_softirq+0x120/0x2e0
Pid: 544, comm: rcu_torture_rea Tainted: G W 2.6.30-tip #54067
Call Trace:
[<ffffffff810820c3>] ? __debug_show_held_locks+0x13/0x30
[<ffffffff810489e6>] __might_sleep+0xf6/0x120
[<ffffffff81b3921d>] lock_sock_nested+0x3d/0x120
[<ffffffff81c1a7d2>] x25_destroy_socket+0x22/0x180Please give this patch a try.
diff --git a/include/net/x25.h b/include/net/x25.h
index fc3f03d..2cda040 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h@@ -187,7 +187,7 @@ extern int x25_addr_ntoa(unsigned char *, struct x25_address *, extern int x25_addr_aton(unsigned char *, struct x25_address *, struct x25_address *); extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *); -extern void x25_destroy_socket(struct sock *); +extern void x25_destroy_socket_from_timer(struct sock *); extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); extern void x25_kill_by_neigh(struct x25_neigh *);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index ed80af8..c51f309 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c@@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x25_neigh *nb) /* * Deferred destroy. */ -void x25_destroy_socket(struct sock *); +static void __x25_destroy_socket(struct sock *); /* * handler for deferred kills. */ static void x25_destroy_timer(unsigned long data) { - x25_destroy_socket((struct sock *)data); + x25_destroy_socket_from_timer((struct sock *)data); } /*
@@ -349,12 +349,10 @@ static void x25_destroy_timer(unsigned long data) * will touch it and we are (fairly 8-) ) safe. * Not static as it's used by the timer */ -void x25_destroy_socket(struct sock *sk) +static void __x25_destroy_socket(struct sock *sk) { struct sk_buff *skb; - sock_hold(sk); - lock_sock(sk); x25_stop_heartbeat(sk); x25_stop_timer(sk);
@@ -385,7 +383,22 @@ void x25_destroy_socket(struct sock *sk) /* drop last reference so sock_put will free */ __sock_put(sk); } +} +void x25_destroy_socket_from_timer(struct sock *sk) +{ + sock_hold(sk); + bh_lock_sock(sk); + __x25_destroy_socket(sk); + bh_unlock_sock(sk); + sock_put(sk); +} + +static void x25_destroy_socket(struct sock *sk) +{ + sock_hold(sk); + lock_sock(sk); + __x25_destroy_socket(sk); release_sock(sk); sock_put(sk); }
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c
index d3e3e54..5c5db1a 100644
--- a/net/x25/x25_timer.c
+++ b/net/x25/x25_timer.c@@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigned long param) (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { bh_unlock_sock(sk); - x25_destroy_socket(sk); + x25_destroy_socket_from_timer(sk); return; } break;