tun: Only wake up writers
authorHerbert Xu <herbert@gondor.apana.org.au>
Thu, 4 Jun 2009 04:45:55 +0000 (21:45 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 4 Jun 2009 04:45:55 +0000 (21:45 -0700)
When I added socket accounting to tun I inadvertently introduced
spurious wake-up events that kills qemu performance.  The problem
occurs when qemu polls on the tun fd for read, and then transmits
packets.  For each packet transmitted, we will wake up qemu even
if it only cares about read events.

Now this affects all sockets, but it is only a new problem for
tun.  So this patch tries to fix it for tun first and we can then
look at the problem in general.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tun.c

index 4cda69b6b28cf1ffeb286066eea906409609df24..3f0cdc14be82a5e6353920c836962bd11c397cd1 100644 (file)
@@ -844,12 +844,12 @@ static void tun_sock_write_space(struct sock *sk)
        if (!sock_writeable(sk))
                return;
 
-       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-               wake_up_interruptible_sync(sk->sk_sleep);
-
        if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
                return;
 
+       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+               wake_up_interruptible_sync(sk->sk_sleep);
+
        tun = container_of(sk, struct tun_sock, sk)->tun;
        kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
 }