diff options
author | meem <none@none> | 2006-08-20 10:20:53 -0700 |
---|---|---|
committer | meem <none@none> | 2006-08-20 10:20:53 -0700 |
commit | a2036d4dec789d6fcf6f71ae43cc38d40c4786cc (patch) | |
tree | 78cee26f1c36d603dbc2292d88c42209af3a2042 /usr/src/uts/common/inet/tcp_impl.h | |
parent | 70ab954a5d6c4d36858fd6e7e3dd4498d06d2c40 (diff) | |
download | illumos-gate-a2036d4dec789d6fcf6f71ae43cc38d40c4786cc.tar.gz |
6440123 TCP Fusion loopback connections may hang due to flow control logic error
6458410 read() may spuriously return EAGAIN while unfusing a TCP connection
Diffstat (limited to 'usr/src/uts/common/inet/tcp_impl.h')
-rw-r--r-- | usr/src/uts/common/inet/tcp_impl.h | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/usr/src/uts/common/inet/tcp_impl.h b/usr/src/uts/common/inet/tcp_impl.h index 93c08cb144..1348d2f6cd 100644 --- a/usr/src/uts/common/inet/tcp_impl.h +++ b/usr/src/uts/common/inet/tcp_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -73,7 +72,7 @@ extern "C" { /* * This stops synchronous streams for a fused tcp endpoint - * and prevents tcp_rrw() from pulling data from it. + * and prevents tcp_fuse_rrw() from pulling data from it. */ #define TCP_FUSE_SYNCSTR_STOP(tcp) { \ if ((tcp)->tcp_direct_sockfs) { \ @@ -84,13 +83,27 @@ extern "C" { } /* - * This resumes synchronous streams for this fused tcp endpoint - * and allows tcp_rrw() to pull data from it again. + * This causes all calls to tcp_fuse_rrw() to block until + * TCP_FUSE_SYNCSTR_UNPLUG_DRAIN() is called. */ -#define TCP_FUSE_SYNCSTR_RESUME(tcp) { \ +#define TCP_FUSE_SYNCSTR_PLUG_DRAIN(tcp) { \ if ((tcp)->tcp_direct_sockfs) { \ mutex_enter(&(tcp)->tcp_fuse_lock); \ - (tcp)->tcp_fuse_syncstr_stopped = B_FALSE; \ + ASSERT(!(tcp)->tcp_fuse_syncstr_plugged); \ + (tcp)->tcp_fuse_syncstr_plugged = B_TRUE; \ + mutex_exit(&(tcp)->tcp_fuse_lock); \ + } \ +} + +/* + * This unplugs the draining of data through tcp_fuse_rrw(); see + * the comments in tcp_fuse_rrw() for how we preserve ordering. + */ +#define TCP_FUSE_SYNCSTR_UNPLUG_DRAIN(tcp) { \ + if ((tcp)->tcp_direct_sockfs) { \ + mutex_enter(&(tcp)->tcp_fuse_lock); \ + (tcp)->tcp_fuse_syncstr_plugged = B_FALSE; \ + (void) cv_broadcast(&(tcp)->tcp_fuse_plugcv); \ mutex_exit(&(tcp)->tcp_fuse_lock); \ } \ } @@ -291,6 +304,7 @@ typedef struct tcp_stat { kstat_named_t tcp_fusion_unqualified; kstat_named_t tcp_fusion_rrw_busy; kstat_named_t tcp_fusion_rrw_msgcnt; + kstat_named_t tcp_fusion_rrw_plugged; kstat_named_t tcp_in_ack_unsent_drop; kstat_named_t tcp_sock_fallback; } tcp_stat_t; |