lkml.org 
[lkml]   [2021]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 043/108] net: decnet: Fix sleeping inside in af_decnet
    Date
    From: Yajun Deng <yajun.deng@linux.dev>

    [ Upstream commit 5f119ba1d5771bbf46d57cff7417dcd84d3084ba ]

    The release_sock() is blocking function, it would change the state
    after sleeping. use wait_woken() instead.

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Signed-off-by: Yajun Deng <yajun.deng@linux.dev>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/decnet/af_decnet.c | 27 ++++++++++++---------------
    1 file changed, 12 insertions(+), 15 deletions(-)

    diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
    index 3349ea81f901..b9b847dc097c 100644
    --- a/net/decnet/af_decnet.c
    +++ b/net/decnet/af_decnet.c
    @@ -815,7 +815,7 @@ static int dn_auto_bind(struct socket *sock)
    static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
    {
    struct dn_scp *scp = DN_SK(sk);
    - DEFINE_WAIT(wait);
    + DEFINE_WAIT_FUNC(wait, woken_wake_function);
    int err;

    if (scp->state != DN_CR)
    @@ -825,11 +825,11 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
    scp->segsize_loc = dst_metric_advmss(__sk_dst_get(sk));
    dn_send_conn_conf(sk, allocation);

    - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    + add_wait_queue(sk_sleep(sk), &wait);
    for(;;) {
    release_sock(sk);
    if (scp->state == DN_CC)
    - *timeo = schedule_timeout(*timeo);
    + *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
    lock_sock(sk);
    err = 0;
    if (scp->state == DN_RUN)
    @@ -843,9 +843,8 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
    err = -EAGAIN;
    if (!*timeo)
    break;
    - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    }
    - finish_wait(sk_sleep(sk), &wait);
    + remove_wait_queue(sk_sleep(sk), &wait);
    if (err == 0) {
    sk->sk_socket->state = SS_CONNECTED;
    } else if (scp->state != DN_CC) {
    @@ -857,7 +856,7 @@ static int dn_confirm_accept(struct sock *sk, long *timeo, gfp_t allocation)
    static int dn_wait_run(struct sock *sk, long *timeo)
    {
    struct dn_scp *scp = DN_SK(sk);
    - DEFINE_WAIT(wait);
    + DEFINE_WAIT_FUNC(wait, woken_wake_function);
    int err = 0;

    if (scp->state == DN_RUN)
    @@ -866,11 +865,11 @@ static int dn_wait_run(struct sock *sk, long *timeo)
    if (!*timeo)
    return -EALREADY;

    - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    + add_wait_queue(sk_sleep(sk), &wait);
    for(;;) {
    release_sock(sk);
    if (scp->state == DN_CI || scp->state == DN_CC)
    - *timeo = schedule_timeout(*timeo);
    + *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
    lock_sock(sk);
    err = 0;
    if (scp->state == DN_RUN)
    @@ -884,9 +883,8 @@ static int dn_wait_run(struct sock *sk, long *timeo)
    err = -ETIMEDOUT;
    if (!*timeo)
    break;
    - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    }
    - finish_wait(sk_sleep(sk), &wait);
    + remove_wait_queue(sk_sleep(sk), &wait);
    out:
    if (err == 0) {
    sk->sk_socket->state = SS_CONNECTED;
    @@ -1031,16 +1029,16 @@ static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)

    static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo)
    {
    - DEFINE_WAIT(wait);
    + DEFINE_WAIT_FUNC(wait, woken_wake_function);
    struct sk_buff *skb = NULL;
    int err = 0;

    - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    + add_wait_queue(sk_sleep(sk), &wait);
    for(;;) {
    release_sock(sk);
    skb = skb_dequeue(&sk->sk_receive_queue);
    if (skb == NULL) {
    - *timeo = schedule_timeout(*timeo);
    + *timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, *timeo);
    skb = skb_dequeue(&sk->sk_receive_queue);
    }
    lock_sock(sk);
    @@ -1055,9 +1053,8 @@ static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo)
    err = -EAGAIN;
    if (!*timeo)
    break;
    - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
    }
    - finish_wait(sk_sleep(sk), &wait);
    + remove_wait_queue(sk_sleep(sk), &wait);

    return skb == NULL ? ERR_PTR(err) : skb;
    }
    --
    2.30.2


    \
     
     \ /
      Last update: 2021-07-26 18:04    [W:3.868 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site