aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorJim Schutt <jaschut@sandia.gov>2012-02-29 10:30:58 -0500
committerAlex Elder <elder@dreamhost.com>2012-03-22 11:47:45 -0400
commit182fac2689b769a96e7fc9defcd560c5cca92b1e (patch)
tree1944b5db730a3157cd8f3d2e50fa88db263c5114 /net/ceph
parentc16fa4f2ad19908a47c63d8fa436a1178438c7e7 (diff)
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: Jim Schutt <jaschut@sandia.gov> Reviewed-by: Alex Elder <elder@dreamhost.com>
Diffstat (limited to 'net/ceph')
-rw-r--r--net/ceph/messenger.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index ad5b70801f37..d11f91b05452 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -143,16 +143,22 @@ static void ceph_write_space(struct sock *sk)
143 struct ceph_connection *con = 143 struct ceph_connection *con =
144 (struct ceph_connection *)sk->sk_user_data; 144 (struct ceph_connection *)sk->sk_user_data;
145 145
146 /* only queue to workqueue if there is data we want to write. */ 146 /* only queue to workqueue if there is data we want to write,
147 * and there is sufficient space in the socket buffer to accept
148 * more data. clear SOCK_NOSPACE so that ceph_write_space()
149 * doesn't get called again until try_write() fills the socket
150 * buffer. See net/ipv4/tcp_input.c:tcp_check_space()
151 * and net/core/stream.c:sk_stream_write_space().
152 */
147 if (test_bit(WRITE_PENDING, &con->state)) { 153 if (test_bit(WRITE_PENDING, &con->state)) {
148 dout("ceph_write_space %p queueing write work\n", con); 154 if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
149 queue_con(con); 155 dout("ceph_write_space %p queueing write work\n", con);
156 clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
157 queue_con(con);
158 }
150 } else { 159 } else {
151 dout("ceph_write_space %p nothing to write\n", con); 160 dout("ceph_write_space %p nothing to write\n", con);
152 } 161 }
153
154 /* since we have our own write_space, clear the SOCK_NOSPACE flag */
155 clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
156} 162}
157 163
158/* socket's state has changed */ 164/* socket's state has changed */