diff options
| author | Jon Maloy <jon.maloy@ericsson.com> | 2018-01-08 23:03:31 +0300 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-01-09 20:35:58 +0300 | 
| commit | eb929a91b213d2a72c5a8b4af9a1acf63bfb8287 (patch) | |
| tree | 9562eb2a8fc216296ce455d4b124ada6b13ca965 /net/tipc/socket.c | |
| parent | 232d07b74a33b9f5d48516dc1d8ce41723ada593 (diff) | |
| download | linux-eb929a91b213d2a72c5a8b4af9a1acf63bfb8287.tar.xz | |
tipc: improve poll() for group member socket
The current criteria for returning POLLOUT from a group member socket is
too simplistic. It basically returns POLLOUT as soon as the group has
external destinations, something obviously leading to a lot of spinning
during destination congestion situations. At the same time, the internal
congestion handling is unnecessarily complex.
We now change this as follows.
- We introduce an 'open' flag in  struct tipc_group. This flag is used
  only to help poll() get the setting of POLLOUT right, and *not* for
  congeston handling as such. This means that a user can choose to
  ignore an  EAGAIN for a destination and go on sending messages to
  other destinations in the group if he wants to.
- The flag is set to false every time we return EAGAIN on a send call.
- The flag is set to true every time any member, i.e., not necessarily
  the member that caused EAGAIN, is removed from the small_win list.
- We remove the group member 'usr_pending' flag. The size of the send
  window and presence in the 'small_win' list is sufficient criteria
  for recognizing congestion.
This solution seems to be a reasonable compromise between 'anycast',
which is normally not waiting for POLLOUT for a specific destination,
and the other three send modes, which are.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 8 | 
1 files changed, 4 insertions, 4 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b24dab3996c9..1f236271766c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -715,7 +715,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,  {  	struct sock *sk = sock->sk;  	struct tipc_sock *tsk = tipc_sk(sk); -	struct tipc_group *grp = tsk->group; +	struct tipc_group *grp;  	u32 revents = 0;  	sock_poll_wait(file, sk_sleep(sk), wait); @@ -736,9 +736,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,  			revents |= POLLIN | POLLRDNORM;  		break;  	case TIPC_OPEN: -		if (!grp || tipc_group_size(grp)) -			if (!tsk->cong_link_cnt) -				revents |= POLLOUT; +		grp = tsk->group; +		if ((!grp || tipc_group_is_open(grp)) && !tsk->cong_link_cnt) +			revents |= POLLOUT;  		if (!tipc_sk_type_connectionless(sk))  			break;  		if (skb_queue_empty(&sk->sk_receive_queue))  | 
