netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/3] netlink: wake up netlink listeners sooner
@ 2011-12-21 21:49 Stephen Hemminger
  2011-12-21 23:00 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Stephen Hemminger @ 2011-12-21 21:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

A netlink listening task (such as Quagga/zebra) can easily get overrun
when lots of events happen such as a link state transition with full BGP route
table. This happens because the sender does not yield to the receiver
(unless socket queue is full). The problem is exacerbated because it is
typical for listeners to set large receive buffer to attempt to keep up.

This patch changes it to yield sooner at halfway instead. Still not a cure-all
for listener overrun if listener is slow, but works much reliably.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/net/netlink/af_netlink.c	2011-12-20 10:25:19.364247598 -0800
+++ b/net/netlink/af_netlink.c	2011-12-20 10:25:46.756570010 -0800
@@ -960,7 +960,7 @@ static int netlink_broadcast_deliver(str
 		skb_set_owner_r(skb, sk);
 		skb_queue_tail(&sk->sk_receive_queue, skb);
 		sk->sk_data_ready(sk, skb->len);
-		return atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf;
+		return atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf / 2;
 	}
 	return -1;
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 3/3] netlink: wake up netlink listeners sooner
  2011-12-21 21:49 [PATCH 3/3] netlink: wake up netlink listeners sooner Stephen Hemminger
@ 2011-12-21 23:00 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2011-12-21 23:00 UTC (permalink / raw)
  To: shemminger; +Cc: netdev

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 21 Dec 2011 13:49:44 -0800

> @@ -960,7 +960,7 @@ static int netlink_broadcast_deliver(str
>  		skb_set_owner_r(skb, sk);
>  		skb_queue_tail(&sk->sk_receive_queue, skb);
>  		sk->sk_data_ready(sk, skb->len);
> -		return atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf;
> +		return atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf / 2;
>  	}

Please mirror the logic we use in the generic socket code to do this
on the send side, namely use something like:

		return (atomic_read(&sk->sk_rmem_alloc) << 1) > sk->sk_rcvbuf;

because sk_rcvbuf is an int and this "/ 2" expression will generate a
really silly sequence of multiple shifts, adds, and comparisons in
order to handle negative values correctly.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-12-21 23:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-21 21:49 [PATCH 3/3] netlink: wake up netlink listeners sooner Stephen Hemminger
2011-12-21 23:00 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).