From: Andrew Morton <[EMAIL PROTECTED]>
Date: Sun, 11 Dec 2005 18:39:32 -0800

> Odd net behaviour with Dave's net-2.6.16 tree.
 ...
> - i cannot login with xdm, as soon as i login, the X server restarts.
>   Login with startx works (.xinitrc is a symlink to .xsession)
>   It works fine with 2.6.15-rc5-mm1.
>   If you need any log please ask.
> 
> - there is a warning when pinging an inexistent ip
>   (it works fine with 2.6.15-rc5-mm1 too)

32-bit x86 ping binary running on an x86_64 system?  That might be a
clue for the second bug.

The first one is mysterious without some more info.

Can you retest for the ping bug after reverting the following patch?

Thanks.

diff-tree 07dda0399dded840d4d1fde39d1cbb0b37123606 (from 
2fbe0a2c52cafa9e6533d0a1747617a46bf8bac6)
Author: Benjamin LaHaise <[EMAIL PROTECTED]>
Date:   Sun Dec 11 17:28:15 2005 -0800

    [NET]: Avoid atomic xchg() for non-error case
    
    It also looks like there were 2 places where the test on sk_err was 
    missing from the event wait logic (in sk_stream_wait_connect and 
    sk_stream_wait_memory), while the rest of the sock_error() users look 
    to be doing the right thing.  This version of the patch fixes those, 
    and cleans up a few places that were testing ->sk_err directly.
    
    Signed-off-by: Benjamin LaHaise <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>

diff --git a/include/net/sock.h b/include/net/sock.h
index 982b4ec..6036340 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1166,8 +1166,11 @@ static inline int sock_queue_err_skb(str
  
 static inline int sock_error(struct sock *sk)
 {
-       int err = xchg(&sk->sk_err, 0);
-       return -err;
+       int err;
+       if (likely(!sk->sk_err))
+               return 0;
+       err = xchg(&sk->sk_err, 0);
+       return unlikely(-err);
 }
 
 static inline unsigned long sock_wspace(struct sock *sk)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ea616e3..fb031fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -287,10 +287,9 @@ int bt_sock_wait_state(struct sock *sk, 
                timeo = schedule_timeout(timeo);
                lock_sock(sk);
 
-               if (sk->sk_err) {
-                       err = sock_error(sk);
+               err = sock_error(sk);
+               if (err)
                        break;
-               }
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(sk->sk_sleep, &wait);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e3bb11c..95f33cc 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -767,8 +767,9 @@ static int l2cap_sock_sendmsg(struct kio
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (sk->sk_err)
-               return sock_error(sk);
+       err = sock_error(sk);
+       if (err)
+               return err;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 9cb00dc..6481814 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -637,8 +637,9 @@ static int sco_sock_sendmsg(struct kiocb
 
        BT_DBG("sock %p, sk %p", sock, sk);
 
-       if (sk->sk_err)
-               return sock_error(sk);
+       err = sock_error(sk);
+       if (err)
+               return err;
 
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
diff --git a/net/core/stream.c b/net/core/stream.c
index 15bfd03..35e2525 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -55,8 +55,9 @@ int sk_stream_wait_connect(struct sock *
        int done;
 
        do {
-               if (sk->sk_err)
-                       return sock_error(sk);
+               int err = sock_error(sk);
+               if (err)
+                       return err;
                if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
                        return -EPIPE;
                if (!*timeo_p)
@@ -67,6 +68,7 @@ int sk_stream_wait_connect(struct sock *
                prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
                sk->sk_write_pending++;
                done = sk_wait_event(sk, timeo_p,
+                                    !sk->sk_err &&
                                     !((1 << sk->sk_state) & 
                                       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
                finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@ int sk_stream_wait_memory(struct sock *s
 
                set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
                sk->sk_write_pending++;
-               sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
+               sk_wait_event(sk, &current_timeo, !sk->sk_err && 
+                                                 !(sk->sk_shutdown & 
SEND_SHUTDOWN) &&
+                                                 sk_stream_memory_free(sk) &&
                                                  vm_wait);
                sk->sk_write_pending--;
 
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 6f92f9c..f121f7d 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1438,8 +1438,9 @@ static int irda_recvmsg_stream(struct ki
                        /*
                         *      POSIX 1003.1g mandates this order.
                         */
-                       if (sk->sk_err)
-                               ret = sock_error(sk);
+                       ret = sock_error(sk);
+                       if (ret)
+                               break;
                        else if (sk->sk_shutdown & RCV_SHUTDOWN)
                                ;
                        else if (noblock)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c3f0b07..b6d3df5 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -566,10 +566,9 @@ static int llc_wait_data(struct sock *sk
                /*
                 * POSIX 1003.1g mandates this order.
                 */
-               if (sk->sk_err) {
-                       rc = sock_error(sk);
+               rc = sock_error(sk);
+               if (rc)
                        break;
-               }
                rc = 0;
                if (sk->sk_shutdown & RCV_SHUTDOWN)
                        break;
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to