]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
msg/simple/Pipe: avoid infinite loop in Pipe::do_recv()
authorYan, Zheng <zyan@redhat.com>
Fri, 18 Dec 2015 14:04:08 +0000 (22:04 +0800)
committerBoris Ranto <branto@redhat.com>
Fri, 6 May 2016 11:44:18 +0000 (13:44 +0200)
commit63e44e32974c9bae17bb1bfd4261dcb024ad845c
treeee8452fed0038859fceda6be39ba54f2b3870542
parentf086f93bcb20ec2465ac1579b21ad1e537a3cd64
msg/simple/Pipe: avoid infinite loop in Pipe::do_recv()

I found that, sometimes an OSD thread uses 100% CPU after cutting network
between OSD and client. recv(2) in Pipe::do_recv() keeps returning -EAGAIN,
which causes infinite loop. the call trace is:

 Pipe::do_recv (...)
 Pipe::buffered_recv (...)
 Pipe::tcp_read_nonblocking (...)
 Pipe::tcp_read (...)

Pipe::tcp_read() first calls Pipe::tcp_read_wait() to check if data is
avaliable. If there are prefetched data, Pipe::tcp_read_wait() return
immediately. Pipe::buffered_recv() is called, which reads data from the
prefetched data. If prefetched data isn't enough, Pipe::buffered_recv()
calls Pipe::do_recv() to read data from socket. But it's possble that
socket has no data at this time, so Pipe::do_recv() keeps retry.

The fix is simple, just not retry when recv(2) return -EAGAIN.

Fixes: #14120
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/msg/simple/Pipe.cc