lkml.org 
[lkml]   [2009]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 023/108] x25: Fix sleep from timer on socket destroy.
    2.6.30-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: David S. Miller <davem@davemloft.net>

    [ Upstream commit 14ebaf81e13ce66bff275380b246796fd16cbfa1 ]

    If socket destuction gets delayed to a timer, we try to
    lock_sock() from that timer which won't work.

    Use bh_lock_sock() in that case.

    Signed-off-by: David S. Miller <davem@davemloft.net>
    Tested-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    include/net/x25.h | 2 +-
    net/x25/af_x25.c | 23 ++++++++++++++++++-----
    net/x25/x25_timer.c | 2 +-
    3 files changed, 20 insertions(+), 7 deletions(-)

    --- a/include/net/x25.h
    +++ b/include/net/x25.h
    @@ -187,7 +187,7 @@ extern int x25_addr_ntoa(unsigned char
    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 *);

    --- a/net/x25/af_x25.c
    +++ b/net/x25/af_x25.c
    @@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x
    /*
    * 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 l
    * 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);
    }
    --- a/net/x25/x25_timer.c
    +++ b/net/x25/x25_timer.c
    @@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigne
    (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;



    \
     
     \ /
      Last update: 2009-07-01 03:09    [W:5.016 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site