Fix r361037.
Reorder flag manipulations and use barrier to ensure that the program order is followed by compiler and CPU, for unlocked reader of so_state. In collaboration with: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D24842
This commit is contained in:
parent
134e17798c
commit
0532a7a2df
@ -4016,8 +4016,17 @@ soisdisconnected(struct socket *so)
|
||||
{
|
||||
|
||||
SOCK_LOCK(so);
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
|
||||
/*
|
||||
* There is at least one reader of so_state that does not
|
||||
* acquire socket lock, namely soreceive_generic(). Ensure
|
||||
* that it never sees all flags that track connection status
|
||||
* cleared, by ordering the update with a barrier semantic of
|
||||
* our release thread fence.
|
||||
*/
|
||||
so->so_state |= SS_ISDISCONNECTED;
|
||||
atomic_thread_fence_rel();
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
|
||||
if (!SOLISTENING(so)) {
|
||||
SOCK_UNLOCK(so);
|
||||
|
Loading…
Reference in New Issue
Block a user