diff options
| author | Jason Baron <[email protected]> | 2018-08-03 17:24:53 -0400 |
|---|---|---|
| committer | David S. Miller <[email protected]> | 2018-08-03 16:44:19 -0700 |
| commit | 51f7e95187f127d5eadf50541943813ff57f12ba (patch) | |
| tree | bc23c743b9cf6bed86cd611cdc16e31b4bb4fb70 /tools/perf/scripts/python/intel-pt-events.py | |
| parent | a394b3af206c211b80b02e47c19aab763fd33b3d (diff) | |
af_unix: ensure POLLOUT on remote close() for connected dgram socket
Applications use -ECONNREFUSED as returned from write() in order to
determine that a socket should be closed. However, when using connected
dgram unix sockets in a poll/write loop, a final POLLOUT event can be
missed when the remote end closes. Thus, the poll is stuck forever:
thread 1 (client) thread 2 (server)
connect() to server
write() returns -EAGAIN
unix_dgram_poll()
-> unix_recvq_full() is true
close()
->unix_release_sock()
->wake_up_interruptible_all()
unix_dgram_poll() (due to the
wake_up_interruptible_all)
-> unix_recvq_full() still is true
->free all skbs
Now thread 1 is stuck and will not receive anymore wakeups. In this
case, when thread 1 gets the -EAGAIN, it has not queued any skbs
otherwise the 'free all skbs' step would in fact cause a wakeup and
a POLLOUT return. So the race here is probably fairly rare because
it means there are no skbs that thread 1 queued and that thread 1
schedules before the 'free all skbs' step.
This issue was reported as a hang when /dev/log is closed.
The fix is to signal POLLOUT if the socket is marked as SOCK_DEAD, which
means a subsequent write() will get -ECONNREFUSED.
Reported-by: Ian Lance Taylor <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Rainer Weikusat <[email protected]>
Cc: Eric Dumazet <[email protected]>
Signed-off-by: Jason Baron <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'tools/perf/scripts/python/intel-pt-events.py')
0 files changed, 0 insertions, 0 deletions