Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 182fac26 authored by Jim Schutt's avatar Jim Schutt Committed by Alex Elder
Browse files

net/ceph: Only clear SOCK_NOSPACE when there is sufficient space in the socket buffer



The Ceph messenger would sometimes queue multiple work items to write
data to a socket when the socket buffer was full.

Fix this problem by making ceph_write_space() use SOCK_NOSPACE in the
same way that net/core/stream.c:sk_stream_write_space() does, i.e.,
clearing it only when sufficient space is available in the socket buffer.

Signed-off-by: default avatarJim Schutt <jaschut@sandia.gov>
Reviewed-by: default avatarAlex Elder <elder@dreamhost.com>
parent c16fa4f2
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -143,16 +143,22 @@ static void ceph_write_space(struct sock *sk)
	struct ceph_connection *con =
		(struct ceph_connection *)sk->sk_user_data;

	/* only queue to workqueue if there is data we want to write. */
	/* only queue to workqueue if there is data we want to write,
	 * and there is sufficient space in the socket buffer to accept
	 * more data.  clear SOCK_NOSPACE so that ceph_write_space()
	 * doesn't get called again until try_write() fills the socket
	 * buffer. See net/ipv4/tcp_input.c:tcp_check_space()
	 * and net/core/stream.c:sk_stream_write_space().
	 */
	if (test_bit(WRITE_PENDING, &con->state)) {
		if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
			dout("ceph_write_space %p queueing write work\n", con);
			clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
			queue_con(con);
		}
	} else {
		dout("ceph_write_space %p nothing to write\n", con);
	}

	/* since we have our own write_space, clear the SOCK_NOSPACE flag */
	clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
}

/* socket's state has changed */