usr/src/uts/common/inet/tcp/tcp_fusion.c
author masputra
Sat, 22 Oct 2005 22:50:14 -0700
changeset 741 40027a3621ac
child 2024 444fb85b9dd5
permissions -rw-r--r--
PSARC 2005/082 Yosemite: UDP Performance Enhancement 4796051 Solaris needs a more complete HW checksumming support 4905227 duplicate macros in ipclassifier.h and ip.h 4915681 need hardware checksum offload for the case of IP/UDP reassembly 6201076 outbound flow-control dysfunctional, ip to ce using mdt 6223331 ipv6 flow control may corrupt UDP packets 6223809 16-bit aligned IP header should be allowed for all x86 platforms 6275398 Galaxy hangs when running lmbench 6281836 Yosemite project integration into Solaris 6281885 xge needs to support IPv6 checksum offload 6282776 IPv6 NCE fast path is not created for incoming solicitation 6304890 IP transmit-side checksum logic needs to be tightened 6304902 IP6_IN_NOCKSUM is obsolete and should be torched 6304904 UDP should reject TI_GETPEERNAME for non-connected endpoint 6306768 IP and UDP device and module definitions need to be centralized
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     1
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     2
 * CDDL HEADER START
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     3
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     7
 * with the License.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     8
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    12
 * and limitations under the License.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    13
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    19
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    20
 * CDDL HEADER END
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    21
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    22
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    24
 * Use is subject to license terms.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    25
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    26
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    28
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    29
#include <sys/types.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    30
#include <sys/stream.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    31
#include <sys/strsun.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    32
#include <sys/strsubr.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    33
#include <sys/debug.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    34
#include <sys/cmn_err.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    35
#include <sys/tihdr.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    36
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    37
#include <inet/common.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    38
#include <inet/ip.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    39
#include <inet/ip_impl.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    40
#include <inet/tcp.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    41
#include <inet/tcp_impl.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    42
#include <inet/ipsec_impl.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    43
#include <inet/ipclassifier.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    44
#include <inet/ipp_common.h>
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    45
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    46
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    47
 * This file implements TCP fusion - a protocol-less data path for TCP
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    48
 * loopback connections.  The fusion of two local TCP endpoints occurs
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    49
 * at connection establishment time.  Various conditions (see details
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    50
 * in tcp_fuse()) need to be met for fusion to be successful.  If it
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    51
 * fails, we fall back to the regular TCP data path; if it succeeds,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    52
 * both endpoints proceed to use tcp_fuse_output() as the transmit path.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    53
 * tcp_fuse_output() enqueues application data directly onto the peer's
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    54
 * receive queue; no protocol processing is involved.  After enqueueing
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    55
 * the data, the sender can either push (putnext) data up the receiver's
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    56
 * read queue; or the sender can simply return and let the receiver
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    57
 * retrieve the enqueued data via the synchronous streams entry point
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    58
 * tcp_fuse_rrw().  The latter path is taken if synchronous streams is
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    59
 * enabled (the default).  It is disabled if sockfs no longer resides
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    60
 * directly on top of tcp module due to a module insertion or removal.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    61
 * It also needs to be temporarily disabled when sending urgent data
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    62
 * because the tcp_fuse_rrw() path bypasses the M_PROTO processing done
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    63
 * by strsock_proto() hook.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    64
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    65
 * Sychronization is handled by squeue and the mutex tcp_fuse_lock.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    66
 * One of the requirements for fusion to succeed is that both endpoints
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    67
 * need to be using the same squeue.  This ensures that neither side
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    68
 * can disappear while the other side is still sending data.  By itself,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    69
 * squeue is not sufficient for guaranteeing safety when synchronous
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    70
 * streams is enabled.  The reason is that tcp_fuse_rrw() doesn't enter
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    71
 * the squeue and its access to tcp_rcv_list and other fusion-related
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    72
 * fields needs to be sychronized with the sender.  tcp_fuse_lock is
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    73
 * used for this purpose.  When there is urgent data, the sender needs
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    74
 * to push the data up the receiver's streams read queue.  In order to
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    75
 * avoid holding the tcp_fuse_lock across putnext(), the sender sets
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    76
 * the peer tcp's tcp_fuse_syncstr_stopped bit and releases tcp_fuse_lock
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    77
 * (see macro TCP_FUSE_SYNCSTR_STOP()).  If tcp_fuse_rrw() enters after
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    78
 * this point, it will see that synchronous streams is temporarily
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    79
 * stopped and it will immediately return EBUSY without accessing the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    80
 * tcp_rcv_list or other fields protected by the tcp_fuse_lock.  This
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    81
 * will result in strget() calling getq_noenab() to dequeue data from
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    82
 * the stream head instead.  After the sender has finished pushing up
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    83
 * all urgent data, it will clear the tcp_fuse_syncstr_stopped bit using
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    84
 * TCP_FUSE_SYNCSTR_RESUME and the receiver may then resume using
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    85
 * tcp_fuse_rrw() to retrieve data from tcp_rcv_list.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    86
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    87
 * The following note applies only to the synchronous streams mode.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    88
 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    89
 * Flow control is done by checking the size of receive buffer and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    90
 * the number of data blocks, both set to different limits.  This is
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    91
 * different than regular streams flow control where cumulative size
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    92
 * check dominates block count check -- streams queue high water mark
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    93
 * typically represents bytes.  Each enqueue triggers notifications
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    94
 * to the receiving process; a build up of data blocks indicates a
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    95
 * slow receiver and the sender should be blocked or informed at the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    96
 * earliest moment instead of further wasting system resources.  In
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    97
 * effect, this is equivalent to limiting the number of outstanding
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    98
 * segments in flight.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
    99
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   100
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   101
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   102
 * Macros that determine whether or not IP processing is needed for TCP.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   103
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   104
#define	TCP_IPOPT_POLICY_V4(tcp)					\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   105
	((tcp)->tcp_ipversion == IPV4_VERSION &&			\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   106
	((tcp)->tcp_ip_hdr_len != IP_SIMPLE_HDR_LENGTH ||		\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   107
	CONN_OUTBOUND_POLICY_PRESENT((tcp)->tcp_connp) ||		\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   108
	CONN_INBOUND_POLICY_PRESENT((tcp)->tcp_connp)))
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   109
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   110
#define	TCP_IPOPT_POLICY_V6(tcp)					\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   111
	((tcp)->tcp_ipversion == IPV6_VERSION &&			\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   112
	((tcp)->tcp_ip_hdr_len != IPV6_HDR_LEN ||			\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   113
	CONN_OUTBOUND_POLICY_PRESENT_V6((tcp)->tcp_connp) ||		\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   114
	CONN_INBOUND_POLICY_PRESENT_V6((tcp)->tcp_connp)))
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   115
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   116
#define	TCP_LOOPBACK_IP(tcp)						\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   117
	(TCP_IPOPT_POLICY_V4(tcp) || TCP_IPOPT_POLICY_V6(tcp) ||	\
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   118
	!CONN_IS_MD_FASTPATH((tcp)->tcp_connp))
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   119
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   120
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   121
 * Setting this to false means we disable fusion altogether and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   122
 * loopback connections would go through the protocol paths.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   123
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   124
boolean_t do_tcp_fusion = B_TRUE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   125
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   126
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   127
 * Enabling this flag allows sockfs to retrieve data directly
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   128
 * from a fused tcp endpoint using synchronous streams interface.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   129
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   130
boolean_t do_tcp_direct_sockfs = B_TRUE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   131
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   132
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   133
 * This is the minimum amount of outstanding writes allowed on
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   134
 * a synchronous streams-enabled receiving endpoint before the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   135
 * sender gets flow-controlled.  Setting this value to 0 means
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   136
 * that the data block limit is equivalent to the byte count
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   137
 * limit, which essentially disables the check.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   138
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   139
#define	TCP_FUSION_RCV_UNREAD_MIN	8
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   140
uint_t tcp_fusion_rcv_unread_min = TCP_FUSION_RCV_UNREAD_MIN;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   141
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   142
static void	tcp_fuse_syncstr_enable(tcp_t *);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   143
static void	tcp_fuse_syncstr_disable(tcp_t *);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   144
static void	strrput_sig(queue_t *, boolean_t);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   145
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   146
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   147
 * This routine gets called by the eager tcp upon changing state from
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   148
 * SYN_RCVD to ESTABLISHED.  It fuses a direct path between itself
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   149
 * and the active connect tcp such that the regular tcp processings
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   150
 * may be bypassed under allowable circumstances.  Because the fusion
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   151
 * requires both endpoints to be in the same squeue, it does not work
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   152
 * for simultaneous active connects because there is no easy way to
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   153
 * switch from one squeue to another once the connection is created.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   154
 * This is different from the eager tcp case where we assign it the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   155
 * same squeue as the one given to the active connect tcp during open.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   156
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   157
void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   158
tcp_fuse(tcp_t *tcp, uchar_t *iphdr, tcph_t *tcph)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   159
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   160
	conn_t *peer_connp, *connp = tcp->tcp_connp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   161
	tcp_t *peer_tcp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   162
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   163
	ASSERT(!tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   164
	ASSERT(tcp->tcp_loopback);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   165
	ASSERT(tcp->tcp_loopback_peer == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   166
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   167
	 * We need to inherit q_hiwat of the listener tcp, but we can't
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   168
	 * really use tcp_listener since we get here after sending up
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   169
	 * T_CONN_IND and tcp_wput_accept() may be called independently,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   170
	 * at which point tcp_listener is cleared; this is why we use
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   171
	 * tcp_saved_listener.  The listener itself is guaranteed to be
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   172
	 * around until tcp_accept_finish() is called on this eager --
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   173
	 * this won't happen until we're done since we're inside the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   174
	 * eager's perimeter now.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   175
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   176
	ASSERT(tcp->tcp_saved_listener != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   177
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   178
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   179
	 * Lookup peer endpoint; search for the remote endpoint having
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   180
	 * the reversed address-port quadruplet in ESTABLISHED state,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   181
	 * which is guaranteed to be unique in the system.  Zone check
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   182
	 * is applied accordingly for loopback address, but not for
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   183
	 * local address since we want fusion to happen across Zones.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   184
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   185
	if (tcp->tcp_ipversion == IPV4_VERSION) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   186
		peer_connp = ipcl_conn_tcp_lookup_reversed_ipv4(connp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   187
		    (ipha_t *)iphdr, tcph);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   188
	} else {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   189
		peer_connp = ipcl_conn_tcp_lookup_reversed_ipv6(connp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   190
		    (ip6_t *)iphdr, tcph);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   191
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   192
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   193
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   194
	 * We can only proceed if peer exists, resides in the same squeue
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   195
	 * as our conn and is not raw-socket.  The squeue assignment of
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   196
	 * this eager tcp was done earlier at the time of SYN processing
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   197
	 * in ip_fanout_tcp{_v6}.  Note that similar squeues by itself
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   198
	 * doesn't guarantee a safe condition to fuse, hence we perform
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   199
	 * additional tests below.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   200
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   201
	ASSERT(peer_connp == NULL || peer_connp != connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   202
	if (peer_connp == NULL || peer_connp->conn_sqp != connp->conn_sqp ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   203
	    !IPCL_IS_TCP(peer_connp)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   204
		if (peer_connp != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   205
			TCP_STAT(tcp_fusion_unqualified);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   206
			CONN_DEC_REF(peer_connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   207
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   208
		return;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   209
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   210
	peer_tcp = peer_connp->conn_tcp;	/* active connect tcp */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   211
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   212
	ASSERT(peer_tcp != NULL && peer_tcp != tcp && !peer_tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   213
	ASSERT(peer_tcp->tcp_loopback && peer_tcp->tcp_loopback_peer == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   214
	ASSERT(peer_connp->conn_sqp == connp->conn_sqp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   215
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   216
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   217
	 * Fuse the endpoints; we perform further checks against both
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   218
	 * tcp endpoints to ensure that a fusion is allowed to happen.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   219
	 * In particular we bail out for non-simple TCP/IP or if IPsec/
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   220
	 * IPQoS policy exists.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   221
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   222
	if (!tcp->tcp_unfusable && !peer_tcp->tcp_unfusable &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   223
	    !TCP_LOOPBACK_IP(tcp) && !TCP_LOOPBACK_IP(peer_tcp) &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   224
	    !IPP_ENABLED(IPP_LOCAL_OUT|IPP_LOCAL_IN)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   225
		mblk_t *mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   226
		struct stroptions *stropt;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   227
		queue_t *peer_rq = peer_tcp->tcp_rq;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   228
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   229
		ASSERT(!TCP_IS_DETACHED(peer_tcp) && peer_rq != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   230
		ASSERT(tcp->tcp_fused_sigurg_mp == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   231
		ASSERT(peer_tcp->tcp_fused_sigurg_mp == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   232
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   233
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   234
		 * We need to drain data on both endpoints during unfuse.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   235
		 * If we need to send up SIGURG at the time of draining,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   236
		 * we want to be sure that an mblk is readily available.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   237
		 * This is why we pre-allocate the M_PCSIG mblks for both
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   238
		 * endpoints which will only be used during/after unfuse.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   239
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   240
		if ((mp = allocb(1, BPRI_HI)) == NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   241
			goto failed;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   242
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   243
		tcp->tcp_fused_sigurg_mp = mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   244
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   245
		if ((mp = allocb(1, BPRI_HI)) == NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   246
			goto failed;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   247
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   248
		peer_tcp->tcp_fused_sigurg_mp = mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   249
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   250
		/* Allocate M_SETOPTS mblk */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   251
		if ((mp = allocb(sizeof (*stropt), BPRI_HI)) == NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   252
			goto failed;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   253
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   254
		/* Fuse both endpoints */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   255
		peer_tcp->tcp_loopback_peer = tcp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   256
		tcp->tcp_loopback_peer = peer_tcp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   257
		peer_tcp->tcp_fused = tcp->tcp_fused = B_TRUE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   258
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   259
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   260
		 * We never use regular tcp paths in fusion and should
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   261
		 * therefore clear tcp_unsent on both endpoints.  Having
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   262
		 * them set to non-zero values means asking for trouble
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   263
		 * especially after unfuse, where we may end up sending
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   264
		 * through regular tcp paths which expect xmit_list and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   265
		 * friends to be correctly setup.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   266
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   267
		peer_tcp->tcp_unsent = tcp->tcp_unsent = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   268
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   269
		tcp_timers_stop(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   270
		tcp_timers_stop(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   271
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   272
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   273
		 * At this point we are a detached eager tcp and therefore
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   274
		 * don't have a queue assigned to us until accept happens.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   275
		 * In the mean time the peer endpoint may immediately send
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   276
		 * us data as soon as fusion is finished, and we need to be
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   277
		 * able to flow control it in case it sends down huge amount
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   278
		 * of data while we're still detached.  To prevent that we
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   279
		 * inherit the listener's q_hiwat value; this is temporary
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   280
		 * since we'll repeat the process in tcp_accept_finish().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   281
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   282
		(void) tcp_fuse_set_rcv_hiwat(tcp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   283
		    tcp->tcp_saved_listener->tcp_rq->q_hiwat);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   284
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   285
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   286
		 * Set the stream head's write offset value to zero since we
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   287
		 * won't be needing any room for TCP/IP headers; tell it to
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   288
		 * not break up the writes (this would reduce the amount of
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   289
		 * work done by kmem); and configure our receive buffer.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   290
		 * Note that we can only do this for the active connect tcp
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   291
		 * since our eager is still detached; it will be dealt with
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   292
		 * later in tcp_accept_finish().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   293
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   294
		DB_TYPE(mp) = M_SETOPTS;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   295
		mp->b_wptr += sizeof (*stropt);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   296
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   297
		stropt = (struct stroptions *)mp->b_rptr;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   298
		stropt->so_flags = SO_MAXBLK | SO_WROFF | SO_HIWAT;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   299
		stropt->so_maxblk = tcp_maxpsz_set(peer_tcp, B_FALSE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   300
		stropt->so_wroff = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   301
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   302
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   303
		 * Record the stream head's high water mark for
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   304
		 * peer endpoint; this is used for flow-control
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   305
		 * purposes in tcp_fuse_output().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   306
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   307
		stropt->so_hiwat = tcp_fuse_set_rcv_hiwat(peer_tcp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   308
		    peer_rq->q_hiwat);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   309
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   310
		/* Send the options up */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   311
		putnext(peer_rq, mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   312
	} else {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   313
		TCP_STAT(tcp_fusion_unqualified);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   314
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   315
	CONN_DEC_REF(peer_connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   316
	return;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   317
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   318
failed:
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   319
	if (tcp->tcp_fused_sigurg_mp != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   320
		freeb(tcp->tcp_fused_sigurg_mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   321
		tcp->tcp_fused_sigurg_mp = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   322
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   323
	if (peer_tcp->tcp_fused_sigurg_mp != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   324
		freeb(peer_tcp->tcp_fused_sigurg_mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   325
		peer_tcp->tcp_fused_sigurg_mp = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   326
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   327
	CONN_DEC_REF(peer_connp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   328
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   329
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   330
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   331
 * Unfuse a previously-fused pair of tcp loopback endpoints.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   332
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   333
void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   334
tcp_unfuse(tcp_t *tcp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   335
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   336
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   337
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   338
	ASSERT(tcp->tcp_fused && peer_tcp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   339
	ASSERT(peer_tcp->tcp_fused && peer_tcp->tcp_loopback_peer == tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   340
	ASSERT(tcp->tcp_connp->conn_sqp == peer_tcp->tcp_connp->conn_sqp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   341
	ASSERT(tcp->tcp_unsent == 0 && peer_tcp->tcp_unsent == 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   342
	ASSERT(tcp->tcp_fused_sigurg_mp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   343
	ASSERT(peer_tcp->tcp_fused_sigurg_mp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   344
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   345
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   346
	 * We disable synchronous streams, drain any queued data and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   347
	 * clear tcp_direct_sockfs.  The synchronous streams entry
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   348
	 * points will become no-ops after this point.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   349
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   350
	tcp_fuse_disable_pair(tcp, B_TRUE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   351
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   352
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   353
	 * Update th_seq and th_ack in the header template
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   354
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   355
	U32_TO_ABE32(tcp->tcp_snxt, tcp->tcp_tcph->th_seq);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   356
	U32_TO_ABE32(tcp->tcp_rnxt, tcp->tcp_tcph->th_ack);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   357
	U32_TO_ABE32(peer_tcp->tcp_snxt, peer_tcp->tcp_tcph->th_seq);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   358
	U32_TO_ABE32(peer_tcp->tcp_rnxt, peer_tcp->tcp_tcph->th_ack);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   359
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   360
	/* Unfuse the endpoints */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   361
	peer_tcp->tcp_fused = tcp->tcp_fused = B_FALSE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   362
	peer_tcp->tcp_loopback_peer = tcp->tcp_loopback_peer = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   363
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   364
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   365
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   366
 * Fusion output routine for urgent data.  This routine is called by
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   367
 * tcp_fuse_output() for handling non-M_DATA mblks.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   368
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   369
void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   370
tcp_fuse_output_urg(tcp_t *tcp, mblk_t *mp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   371
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   372
	mblk_t *mp1;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   373
	struct T_exdata_ind *tei;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   374
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   375
	mblk_t *head, *prev_head = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   376
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   377
	ASSERT(tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   378
	ASSERT(peer_tcp != NULL && peer_tcp->tcp_loopback_peer == tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   379
	ASSERT(DB_TYPE(mp) == M_PROTO || DB_TYPE(mp) == M_PCPROTO);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   380
	ASSERT(mp->b_cont != NULL && DB_TYPE(mp->b_cont) == M_DATA);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   381
	ASSERT(MBLKL(mp) >= sizeof (*tei) && MBLKL(mp->b_cont) > 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   382
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   383
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   384
	 * Urgent data arrives in the form of T_EXDATA_REQ from above.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   385
	 * Each occurence denotes a new urgent pointer.  For each new
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   386
	 * urgent pointer we signal (SIGURG) the receiving app to indicate
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   387
	 * that it needs to go into urgent mode.  This is similar to the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   388
	 * urgent data handling in the regular tcp.  We don't need to keep
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   389
	 * track of where the urgent pointer is, because each T_EXDATA_REQ
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   390
	 * "advances" the urgent pointer for us.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   391
	 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   392
	 * The actual urgent data carried by T_EXDATA_REQ is then prepended
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   393
	 * by a T_EXDATA_IND before being enqueued behind any existing data
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   394
	 * destined for the receiving app.  There is only a single urgent
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   395
	 * pointer (out-of-band mark) for a given tcp.  If the new urgent
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   396
	 * data arrives before the receiving app reads some existing urgent
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   397
	 * data, the previous marker is lost.  This behavior is emulated
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   398
	 * accordingly below, by removing any existing T_EXDATA_IND messages
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   399
	 * and essentially converting old urgent data into non-urgent.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   400
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   401
	ASSERT(tcp->tcp_valid_bits & TCP_URG_VALID);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   402
	/* Let sender get out of urgent mode */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   403
	tcp->tcp_valid_bits &= ~TCP_URG_VALID;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   404
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   405
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   406
	 * This flag indicates that a signal needs to be sent up.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   407
	 * This flag will only get cleared once SIGURG is delivered and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   408
	 * is not affected by the tcp_fused flag -- delivery will still
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   409
	 * happen even after an endpoint is unfused, to handle the case
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   410
	 * where the sending endpoint immediately closes/unfuses after
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   411
	 * sending urgent data and the accept is not yet finished.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   412
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   413
	peer_tcp->tcp_fused_sigurg = B_TRUE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   414
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   415
	/* Reuse T_EXDATA_REQ mblk for T_EXDATA_IND */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   416
	DB_TYPE(mp) = M_PROTO;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   417
	tei = (struct T_exdata_ind *)mp->b_rptr;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   418
	tei->PRIM_type = T_EXDATA_IND;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   419
	tei->MORE_flag = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   420
	mp->b_wptr = (uchar_t *)&tei[1];
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   421
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   422
	TCP_STAT(tcp_fusion_urg);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   423
	BUMP_MIB(&tcp_mib, tcpOutUrg);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   424
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   425
	head = peer_tcp->tcp_rcv_list;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   426
	while (head != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   427
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   428
		 * Remove existing T_EXDATA_IND, keep the data which follows
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   429
		 * it and relink our list.  Note that we don't modify the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   430
		 * tcp_rcv_last_tail since it never points to T_EXDATA_IND.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   431
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   432
		if (DB_TYPE(head) != M_DATA) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   433
			mp1 = head;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   434
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   435
			ASSERT(DB_TYPE(mp1->b_cont) == M_DATA);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   436
			head = mp1->b_cont;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   437
			mp1->b_cont = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   438
			head->b_next = mp1->b_next;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   439
			mp1->b_next = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   440
			if (prev_head != NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   441
				prev_head->b_next = head;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   442
			if (peer_tcp->tcp_rcv_list == mp1)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   443
				peer_tcp->tcp_rcv_list = head;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   444
			if (peer_tcp->tcp_rcv_last_head == mp1)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   445
				peer_tcp->tcp_rcv_last_head = head;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   446
			freeb(mp1);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   447
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   448
		prev_head = head;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   449
		head = head->b_next;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   450
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   451
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   452
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   453
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   454
 * Fusion output routine, called by tcp_output() and tcp_wput_proto().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   455
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   456
boolean_t
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   457
tcp_fuse_output(tcp_t *tcp, mblk_t *mp, uint32_t send_size)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   458
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   459
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   460
	queue_t *peer_rq;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   461
	uint_t max_unread;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   462
	boolean_t flow_stopped;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   463
	boolean_t urgent = (DB_TYPE(mp) != M_DATA);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   464
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   465
	ASSERT(tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   466
	ASSERT(peer_tcp != NULL && peer_tcp->tcp_loopback_peer == tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   467
	ASSERT(tcp->tcp_connp->conn_sqp == peer_tcp->tcp_connp->conn_sqp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   468
	ASSERT(DB_TYPE(mp) == M_DATA || DB_TYPE(mp) == M_PROTO ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   469
	    DB_TYPE(mp) == M_PCPROTO);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   470
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   471
	peer_rq = peer_tcp->tcp_rq;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   472
	max_unread = peer_tcp->tcp_fuse_rcv_unread_hiwater;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   473
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   474
	/* If this connection requires IP, unfuse and use regular path */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   475
	if (TCP_LOOPBACK_IP(tcp) || TCP_LOOPBACK_IP(peer_tcp) ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   476
	    IPP_ENABLED(IPP_LOCAL_OUT|IPP_LOCAL_IN)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   477
		TCP_STAT(tcp_fusion_aborted);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   478
		tcp_unfuse(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   479
		return (B_FALSE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   480
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   481
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   482
	if (send_size == 0) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   483
		freemsg(mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   484
		return (B_TRUE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   485
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   486
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   487
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   488
	 * Handle urgent data; we either send up SIGURG to the peer now
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   489
	 * or do it later when we drain, in case the peer is detached
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   490
	 * or if we're short of memory for M_PCSIG mblk.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   491
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   492
	if (urgent) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   493
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   494
		 * We stop synchronous streams when we have urgent data
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   495
		 * queued to prevent tcp_fuse_rrw() from pulling it.  If
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   496
		 * for some reasons the urgent data can't be delivered
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   497
		 * below, synchronous streams will remain stopped until
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   498
		 * someone drains the tcp_rcv_list.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   499
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   500
		TCP_FUSE_SYNCSTR_STOP(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   501
		tcp_fuse_output_urg(tcp, mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   502
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   503
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   504
	mutex_enter(&peer_tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   505
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   506
	 * Wake up and signal the peer; it is okay to do this before
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   507
	 * enqueueing because we are holding the lock.  One of the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   508
	 * advantages of synchronous streams is the ability for us to
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   509
	 * find out when the application performs a read on the socket,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   510
	 * by way of tcp_fuse_rrw() entry point being called.  Every
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   511
	 * data that gets enqueued onto the receiver is treated as if
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   512
	 * it has arrived at the receiving endpoint, thus generating
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   513
	 * SIGPOLL/SIGIO for asynchronous socket just as in the strrput()
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   514
	 * case.  However, we only wake up the application when necessary,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   515
	 * i.e. during the first enqueue.  When tcp_fuse_rrw() is called
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   516
	 * it will send everything upstream.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   517
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   518
	if (peer_tcp->tcp_direct_sockfs && !urgent &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   519
	    !TCP_IS_DETACHED(peer_tcp)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   520
		if (peer_tcp->tcp_rcv_list == NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   521
			STR_WAKEUP_SET(STREAM(peer_tcp->tcp_rq));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   522
		/* Update poll events and send SIGPOLL/SIGIO if necessary */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   523
		STR_SENDSIG(STREAM(peer_tcp->tcp_rq));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   524
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   525
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   526
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   527
	 * Enqueue data into the peer's receive list; we may or may not
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   528
	 * drain the contents depending on the conditions below.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   529
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   530
	tcp_rcv_enqueue(peer_tcp, mp, send_size);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   531
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   532
	/* In case it wrapped around and also to keep it constant */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   533
	peer_tcp->tcp_rwnd += send_size;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   534
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   535
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   536
	 * Exercise flow-control when needed; we will get back-enabled
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   537
	 * in either tcp_accept_finish(), tcp_unfuse(), or tcp_fuse_rrw().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   538
	 * If tcp_direct_sockfs is on or if the peer endpoint is detached,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   539
	 * we emulate streams flow control by checking the peer's queue
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   540
	 * size and high water mark; otherwise we simply use canputnext()
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   541
	 * to decide if we need to stop our flow.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   542
	 *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   543
	 * The outstanding unread data block check does not apply for a
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   544
	 * detached receiver; this is to avoid unnecessary blocking of the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   545
	 * sender while the accept is currently in progress and is quite
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   546
	 * similar to the regular tcp.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   547
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   548
	if (TCP_IS_DETACHED(peer_tcp) || max_unread == 0)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   549
		max_unread = UINT_MAX;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   550
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   551
	flow_stopped = tcp->tcp_flow_stopped;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   552
	if (!flow_stopped &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   553
	    (((peer_tcp->tcp_direct_sockfs || TCP_IS_DETACHED(peer_tcp)) &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   554
	    (peer_tcp->tcp_rcv_cnt >= peer_tcp->tcp_fuse_rcv_hiwater ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   555
	    ++peer_tcp->tcp_fuse_rcv_unread_cnt >= max_unread)) ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   556
	    (!peer_tcp->tcp_direct_sockfs &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   557
	    !TCP_IS_DETACHED(peer_tcp) && !canputnext(peer_tcp->tcp_rq)))) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   558
		tcp_setqfull(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   559
		flow_stopped = B_TRUE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   560
		TCP_STAT(tcp_fusion_flowctl);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   561
		DTRACE_PROBE4(tcp__fuse__output__flowctl, tcp_t *, tcp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   562
		    uint_t, send_size, uint_t, peer_tcp->tcp_rcv_cnt,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   563
		    uint_t, peer_tcp->tcp_fuse_rcv_unread_cnt);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   564
	} else if (flow_stopped &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   565
	    TCP_UNSENT_BYTES(tcp) <= tcp->tcp_xmit_lowater) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   566
		tcp_clrqfull(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   567
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   568
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   569
	loopback_packets++;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   570
	tcp->tcp_last_sent_len = send_size;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   571
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   572
	/* Need to adjust the following SNMP MIB-related variables */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   573
	tcp->tcp_snxt += send_size;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   574
	tcp->tcp_suna = tcp->tcp_snxt;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   575
	peer_tcp->tcp_rnxt += send_size;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   576
	peer_tcp->tcp_rack = peer_tcp->tcp_rnxt;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   577
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   578
	BUMP_MIB(&tcp_mib, tcpOutDataSegs);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   579
	UPDATE_MIB(&tcp_mib, tcpOutDataBytes, send_size);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   580
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   581
	BUMP_MIB(&tcp_mib, tcpInSegs);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   582
	BUMP_MIB(&tcp_mib, tcpInDataInorderSegs);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   583
	UPDATE_MIB(&tcp_mib, tcpInDataInorderBytes, send_size);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   584
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   585
	BUMP_LOCAL(tcp->tcp_obsegs);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   586
	BUMP_LOCAL(peer_tcp->tcp_ibsegs);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   587
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   588
	mutex_exit(&peer_tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   589
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   590
	DTRACE_PROBE2(tcp__fuse__output, tcp_t *, tcp, uint_t, send_size);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   591
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   592
	if (!TCP_IS_DETACHED(peer_tcp)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   593
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   594
		 * Drain the peer's receive queue it has urgent data or if
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   595
		 * we're not flow-controlled.  There is no need for draining
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   596
		 * normal data when tcp_direct_sockfs is on because the peer
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   597
		 * will pull the data via tcp_fuse_rrw().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   598
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   599
		if (urgent || (!flow_stopped && !peer_tcp->tcp_direct_sockfs)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   600
			ASSERT(peer_tcp->tcp_rcv_list != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   601
			(void) tcp_fuse_rcv_drain(peer_rq, peer_tcp, NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   602
			/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   603
			 * If synchronous streams was stopped above due
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   604
			 * to the presence of urgent data, re-enable it.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   605
			 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   606
			if (urgent)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   607
				TCP_FUSE_SYNCSTR_RESUME(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   608
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   609
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   610
	return (B_TRUE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   611
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   612
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   613
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   614
 * This routine gets called to deliver data upstream on a fused or
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   615
 * previously fused tcp loopback endpoint; the latter happens only
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   616
 * when there is a pending SIGURG signal plus urgent data that can't
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   617
 * be sent upstream in the past.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   618
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   619
boolean_t
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   620
tcp_fuse_rcv_drain(queue_t *q, tcp_t *tcp, mblk_t **sigurg_mpp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   621
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   622
	mblk_t *mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   623
#ifdef DEBUG
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   624
	uint_t cnt = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   625
#endif
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   626
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   627
	ASSERT(tcp->tcp_loopback);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   628
	ASSERT(tcp->tcp_fused || tcp->tcp_fused_sigurg);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   629
	ASSERT(!tcp->tcp_fused || tcp->tcp_loopback_peer != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   630
	ASSERT(sigurg_mpp != NULL || tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   631
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   632
	/* No need for the push timer now, in case it was scheduled */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   633
	if (tcp->tcp_push_tid != 0) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   634
		(void) TCP_TIMER_CANCEL(tcp, tcp->tcp_push_tid);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   635
		tcp->tcp_push_tid = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   636
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   637
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   638
	 * If there's urgent data sitting in receive list and we didn't
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   639
	 * get a chance to send up a SIGURG signal, make sure we send
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   640
	 * it first before draining in order to ensure that SIOCATMARK
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   641
	 * works properly.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   642
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   643
	if (tcp->tcp_fused_sigurg) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   644
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   645
		 * sigurg_mpp is normally NULL, i.e. when we're still
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   646
		 * fused and didn't get here because of tcp_unfuse().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   647
		 * In this case try hard to allocate the M_PCSIG mblk.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   648
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   649
		if (sigurg_mpp == NULL &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   650
		    (mp = allocb(1, BPRI_HI)) == NULL &&
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   651
		    (mp = allocb_tryhard(1)) == NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   652
			/* Alloc failed; try again next time */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   653
			tcp->tcp_push_tid = TCP_TIMER(tcp, tcp_push_timer,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   654
			    MSEC_TO_TICK(tcp_push_timer_interval));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   655
			return (B_TRUE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   656
		} else if (sigurg_mpp != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   657
			/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   658
			 * Use the supplied M_PCSIG mblk; it means we're
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   659
			 * either unfused or in the process of unfusing,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   660
			 * and the drain must happen now.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   661
			 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   662
			mp = *sigurg_mpp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   663
			*sigurg_mpp = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   664
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   665
		ASSERT(mp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   666
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   667
		tcp->tcp_fused_sigurg = B_FALSE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   668
		/* Send up the signal */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   669
		DB_TYPE(mp) = M_PCSIG;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   670
		*mp->b_wptr++ = (uchar_t)SIGURG;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   671
		putnext(q, mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   672
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   673
		 * Let the regular tcp_rcv_drain() path handle
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   674
		 * draining the data if we're no longer fused.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   675
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   676
		if (!tcp->tcp_fused)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   677
			return (B_FALSE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   678
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   679
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   680
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   681
	 * In the synchronous streams case, we generate SIGPOLL/SIGIO for
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   682
	 * each M_DATA that gets enqueued onto the receiver.  At this point
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   683
	 * we are about to drain any queued data via putnext().  In order
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   684
	 * to avoid extraneous signal generation from strrput(), we set
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   685
	 * STRGETINPROG flag at the stream head prior to the draining and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   686
	 * restore it afterwards.  This masks out signal generation only
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   687
	 * for M_DATA messages and does not affect urgent data.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   688
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   689
	if (tcp->tcp_direct_sockfs)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   690
		strrput_sig(q, B_FALSE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   691
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   692
	/* Drain the data */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   693
	while ((mp = tcp->tcp_rcv_list) != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   694
		tcp->tcp_rcv_list = mp->b_next;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   695
		mp->b_next = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   696
#ifdef DEBUG
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   697
		cnt += msgdsize(mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   698
#endif
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   699
		putnext(q, mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   700
		TCP_STAT(tcp_fusion_putnext);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   701
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   702
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   703
	if (tcp->tcp_direct_sockfs)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   704
		strrput_sig(q, B_TRUE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   705
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   706
	ASSERT(cnt == tcp->tcp_rcv_cnt);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   707
	tcp->tcp_rcv_last_head = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   708
	tcp->tcp_rcv_last_tail = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   709
	tcp->tcp_rcv_cnt = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   710
	tcp->tcp_fuse_rcv_unread_cnt = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   711
	tcp->tcp_rwnd = q->q_hiwat;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   712
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   713
	return (B_TRUE);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   714
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   715
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   716
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   717
 * Synchronous stream entry point for sockfs to retrieve
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   718
 * data directly from tcp_rcv_list.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   719
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   720
int
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   721
tcp_fuse_rrw(queue_t *q, struiod_t *dp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   722
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   723
	tcp_t *tcp = Q_TO_CONN(q)->conn_tcp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   724
	mblk_t *mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   725
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   726
	mutex_enter(&tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   727
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   728
	 * If someone had turned off tcp_direct_sockfs or if synchronous
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   729
	 * streams is temporarily disabled, we return EBUSY.  This causes
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   730
	 * strget() to dequeue data from the stream head instead.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   731
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   732
	if (!tcp->tcp_direct_sockfs || tcp->tcp_fuse_syncstr_stopped) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   733
		mutex_exit(&tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   734
		TCP_STAT(tcp_fusion_rrw_busy);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   735
		return (EBUSY);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   736
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   737
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   738
	if ((mp = tcp->tcp_rcv_list) != NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   739
		tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   740
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   741
		DTRACE_PROBE3(tcp__fuse__rrw, tcp_t *, tcp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   742
		    uint32_t, tcp->tcp_rcv_cnt, ssize_t, dp->d_uio.uio_resid);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   743
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   744
		tcp->tcp_rcv_list = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   745
		TCP_STAT(tcp_fusion_rrw_msgcnt);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   746
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   747
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   748
		 * At this point nothing should be left in tcp_rcv_list.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   749
		 * The only possible case where we would have a chain of
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   750
		 * b_next-linked messages is urgent data, but we wouldn't
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   751
		 * be here if that's true since urgent data is delivered
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   752
		 * via putnext() and synchronous streams is stopped until
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   753
		 * tcp_fuse_rcv_drain() is finished.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   754
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   755
		ASSERT(DB_TYPE(mp) == M_DATA && mp->b_next == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   756
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   757
		tcp->tcp_rcv_last_head = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   758
		tcp->tcp_rcv_last_tail = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   759
		tcp->tcp_rcv_cnt = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   760
		tcp->tcp_fuse_rcv_unread_cnt = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   761
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   762
		if (peer_tcp->tcp_flow_stopped) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   763
			tcp_clrqfull(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   764
			TCP_STAT(tcp_fusion_backenabled);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   765
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   766
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   767
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   768
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   769
	 * Either we just dequeued everything or we get here from sockfs
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   770
	 * and have nothing to return; in this case clear RSLEEP.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   771
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   772
	ASSERT(tcp->tcp_rcv_last_head == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   773
	ASSERT(tcp->tcp_rcv_last_tail == NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   774
	ASSERT(tcp->tcp_rcv_cnt == 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   775
	ASSERT(tcp->tcp_fuse_rcv_unread_cnt == 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   776
	STR_WAKEUP_CLEAR(STREAM(q));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   777
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   778
	mutex_exit(&tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   779
	dp->d_mp = mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   780
	return (0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   781
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   782
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   783
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   784
 * Synchronous stream entry point used by certain ioctls to retrieve
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   785
 * information about or peek into the tcp_rcv_list.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   786
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   787
int
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   788
tcp_fuse_rinfop(queue_t *q, infod_t *dp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   789
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   790
	tcp_t	*tcp = Q_TO_CONN(q)->conn_tcp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   791
	mblk_t	*mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   792
	uint_t	cmd = dp->d_cmd;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   793
	int	res = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   794
	int	error = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   795
	struct stdata *stp = STREAM(q);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   796
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   797
	mutex_enter(&tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   798
	/* If shutdown on read has happened, return nothing */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   799
	mutex_enter(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   800
	if (stp->sd_flag & STREOF) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   801
		mutex_exit(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   802
		goto done;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   803
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   804
	mutex_exit(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   805
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   806
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   807
	 * It is OK not to return an answer if tcp_rcv_list is
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   808
	 * currently not accessible.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   809
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   810
	if (!tcp->tcp_direct_sockfs || tcp->tcp_fuse_syncstr_stopped ||
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   811
	    (mp = tcp->tcp_rcv_list) == NULL)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   812
		goto done;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   813
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   814
	if (cmd & INFOD_COUNT) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   815
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   816
		 * We have at least one message and
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   817
		 * could return only one at a time.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   818
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   819
		dp->d_count++;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   820
		res |= INFOD_COUNT;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   821
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   822
	if (cmd & INFOD_BYTES) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   823
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   824
		 * Return size of all data messages.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   825
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   826
		dp->d_bytes += tcp->tcp_rcv_cnt;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   827
		res |= INFOD_BYTES;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   828
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   829
	if (cmd & INFOD_FIRSTBYTES) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   830
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   831
		 * Return size of first data message.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   832
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   833
		dp->d_bytes = msgdsize(mp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   834
		res |= INFOD_FIRSTBYTES;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   835
		dp->d_cmd &= ~INFOD_FIRSTBYTES;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   836
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   837
	if (cmd & INFOD_COPYOUT) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   838
		mblk_t *mp1;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   839
		int n;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   840
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   841
		if (DB_TYPE(mp) == M_DATA) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   842
			mp1 = mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   843
		} else {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   844
			mp1 = mp->b_cont;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   845
			ASSERT(mp1 != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   846
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   847
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   848
		/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   849
		 * Return data contents of first message.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   850
		 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   851
		ASSERT(DB_TYPE(mp1) == M_DATA);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   852
		while (mp1 != NULL && dp->d_uiop->uio_resid > 0) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   853
			n = MIN(dp->d_uiop->uio_resid, MBLKL(mp1));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   854
			if (n != 0 && (error = uiomove((char *)mp1->b_rptr, n,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   855
			    UIO_READ, dp->d_uiop)) != 0) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   856
				goto done;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   857
			}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   858
			mp1 = mp1->b_cont;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   859
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   860
		res |= INFOD_COPYOUT;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   861
		dp->d_cmd &= ~INFOD_COPYOUT;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   862
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   863
done:
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   864
	mutex_exit(&tcp->tcp_fuse_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   865
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   866
	dp->d_res |= res;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   867
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   868
	return (error);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   869
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   870
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   871
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   872
 * Enable synchronous streams on a fused tcp loopback endpoint.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   873
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   874
static void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   875
tcp_fuse_syncstr_enable(tcp_t *tcp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   876
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   877
	queue_t *rq = tcp->tcp_rq;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   878
	struct stdata *stp = STREAM(rq);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   879
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   880
	/* We can only enable synchronous streams for sockfs mode */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   881
	tcp->tcp_direct_sockfs = tcp->tcp_issocket && do_tcp_direct_sockfs;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   882
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   883
	if (!tcp->tcp_direct_sockfs)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   884
		return;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   885
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   886
	mutex_enter(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   887
	mutex_enter(QLOCK(rq));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   888
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   889
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   890
	 * We replace our q_qinfo with one that has the qi_rwp entry point.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   891
	 * Clear SR_SIGALLDATA because we generate the equivalent signal(s)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   892
	 * for every enqueued data in tcp_fuse_output().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   893
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   894
	rq->q_qinfo = &tcp_loopback_rinit;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   895
	rq->q_struiot = tcp_loopback_rinit.qi_struiot;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   896
	stp->sd_struiordq = rq;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   897
	stp->sd_rput_opt &= ~SR_SIGALLDATA;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   898
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   899
	mutex_exit(QLOCK(rq));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   900
	mutex_exit(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   901
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   902
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   903
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   904
 * Disable synchronous streams on a fused tcp loopback endpoint.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   905
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   906
static void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   907
tcp_fuse_syncstr_disable(tcp_t *tcp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   908
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   909
	queue_t *rq = tcp->tcp_rq;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   910
	struct stdata *stp = STREAM(rq);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   911
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   912
	if (!tcp->tcp_direct_sockfs)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   913
		return;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   914
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   915
	mutex_enter(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   916
	mutex_enter(QLOCK(rq));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   917
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   918
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   919
	 * Reset q_qinfo to point to the default tcp entry points.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   920
	 * Also restore SR_SIGALLDATA so that strrput() can generate
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   921
	 * the signals again for future M_DATA messages.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   922
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   923
	rq->q_qinfo = &tcp_rinit;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   924
	rq->q_struiot = tcp_rinit.qi_struiot;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   925
	stp->sd_struiordq = NULL;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   926
	stp->sd_rput_opt |= SR_SIGALLDATA;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   927
	tcp->tcp_direct_sockfs = B_FALSE;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   928
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   929
	mutex_exit(QLOCK(rq));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   930
	mutex_exit(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   931
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   932
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   933
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   934
 * Enable synchronous streams on a pair of fused tcp endpoints.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   935
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   936
void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   937
tcp_fuse_syncstr_enable_pair(tcp_t *tcp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   938
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   939
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   940
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   941
	ASSERT(tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   942
	ASSERT(peer_tcp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   943
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   944
	tcp_fuse_syncstr_enable(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   945
	tcp_fuse_syncstr_enable(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   946
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   947
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   948
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   949
 * Allow or disallow signals to be generated by strrput().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   950
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   951
static void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   952
strrput_sig(queue_t *q, boolean_t on)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   953
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   954
	struct stdata *stp = STREAM(q);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   955
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   956
	mutex_enter(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   957
	if (on)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   958
		stp->sd_flag &= ~STRGETINPROG;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   959
	else
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   960
		stp->sd_flag |= STRGETINPROG;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   961
	mutex_exit(&stp->sd_lock);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   962
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   963
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   964
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   965
 * Disable synchronous streams on a pair of fused tcp endpoints and drain
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   966
 * any queued data; called either during unfuse or upon transitioning from
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   967
 * a socket to a stream endpoint due to _SIOCSOCKFALLBACK.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   968
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   969
void
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   970
tcp_fuse_disable_pair(tcp_t *tcp, boolean_t unfusing)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   971
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   972
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   973
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   974
	ASSERT(tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   975
	ASSERT(peer_tcp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   976
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   977
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   978
	 * We need to prevent tcp_fuse_rrw() from entering before
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   979
	 * we can disable synchronous streams.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   980
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   981
	TCP_FUSE_SYNCSTR_STOP(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   982
	TCP_FUSE_SYNCSTR_STOP(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   983
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   984
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   985
	 * Drain any pending data; the detached check is needed because
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   986
	 * we may be called as a result of a tcp_unfuse() triggered by
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   987
	 * tcp_fuse_output().  Note that in case of a detached tcp, the
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   988
	 * draining will happen later after the tcp is unfused.  For non-
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   989
	 * urgent data, this can be handled by the regular tcp_rcv_drain().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   990
	 * If we have urgent data sitting in the receive list, we will
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   991
	 * need to send up a SIGURG signal first before draining the data.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   992
	 * All of these will be handled by the code in tcp_fuse_rcv_drain()
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   993
	 * when called from tcp_rcv_drain().
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   994
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   995
	if (!TCP_IS_DETACHED(tcp)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   996
		(void) tcp_fuse_rcv_drain(tcp->tcp_rq, tcp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   997
		    (unfusing ? &tcp->tcp_fused_sigurg_mp : NULL));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   998
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
   999
	if (!TCP_IS_DETACHED(peer_tcp)) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1000
		(void) tcp_fuse_rcv_drain(peer_tcp->tcp_rq, peer_tcp,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1001
		    (unfusing ? &peer_tcp->tcp_fused_sigurg_mp : NULL));
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1002
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1003
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1004
	/* Lift up any flow-control conditions */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1005
	if (tcp->tcp_flow_stopped) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1006
		tcp_clrqfull(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1007
		TCP_STAT(tcp_fusion_backenabled);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1008
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1009
	if (peer_tcp->tcp_flow_stopped) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1010
		tcp_clrqfull(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1011
		TCP_STAT(tcp_fusion_backenabled);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1012
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1013
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1014
	/* Disable synchronous streams */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1015
	tcp_fuse_syncstr_disable(tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1016
	tcp_fuse_syncstr_disable(peer_tcp);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1017
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1018
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1019
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1020
 * Calculate the size of receive buffer for a fused tcp endpoint.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1021
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1022
size_t
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1023
tcp_fuse_set_rcv_hiwat(tcp_t *tcp, size_t rwnd)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1024
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1025
	ASSERT(tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1026
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1027
	/* Ensure that value is within the maximum upper bound */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1028
	if (rwnd > tcp_max_buf)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1029
		rwnd = tcp_max_buf;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1030
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1031
	/* Obey the absolute minimum tcp receive high water mark */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1032
	if (rwnd < tcp_sth_rcv_hiwat)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1033
		rwnd = tcp_sth_rcv_hiwat;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1034
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1035
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1036
	 * Round up to system page size in case SO_RCVBUF is modified
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1037
	 * after SO_SNDBUF; the latter is also similarly rounded up.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1038
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1039
	rwnd = P2ROUNDUP_TYPED(rwnd, PAGESIZE, size_t);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1040
	tcp->tcp_fuse_rcv_hiwater = rwnd;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1041
	return (rwnd);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1042
}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1043
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1044
/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1045
 * Calculate the maximum outstanding unread data block for a fused tcp endpoint.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1046
 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1047
int
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1048
tcp_fuse_maxpsz_set(tcp_t *tcp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1049
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1050
	tcp_t *peer_tcp = tcp->tcp_loopback_peer;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1051
	uint_t sndbuf = tcp->tcp_xmit_hiwater;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1052
	uint_t maxpsz = sndbuf;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1053
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1054
	ASSERT(tcp->tcp_fused);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1055
	ASSERT(peer_tcp != NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1056
	ASSERT(peer_tcp->tcp_fuse_rcv_hiwater != 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1057
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1058
	 * In the fused loopback case, we want the stream head to split
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1059
	 * up larger writes into smaller chunks for a more accurate flow-
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1060
	 * control accounting.  Our maxpsz is half of the sender's send
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1061
	 * buffer or the receiver's receive buffer, whichever is smaller.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1062
	 * We round up the buffer to system page size due to the lack of
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1063
	 * TCP MSS concept in Fusion.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1064
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1065
	if (maxpsz > peer_tcp->tcp_fuse_rcv_hiwater)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1066
		maxpsz = peer_tcp->tcp_fuse_rcv_hiwater;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1067
	maxpsz = P2ROUNDUP_TYPED(maxpsz, PAGESIZE, uint_t) >> 1;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1068
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1069
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1070
	 * Calculate the peer's limit for the number of outstanding unread
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1071
	 * data block.  This is the amount of data blocks that are allowed
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1072
	 * to reside in the receiver's queue before the sender gets flow
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1073
	 * controlled.  It is used only in the synchronous streams mode as
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1074
	 * a way to throttle the sender when it performs consecutive writes
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1075
	 * faster than can be read.  The value is derived from SO_SNDBUF in
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1076
	 * order to give the sender some control; we divide it with a large
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1077
	 * value (16KB) to produce a fairly low initial limit.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1078
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1079
	if (tcp_fusion_rcv_unread_min == 0) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1080
		/* A value of 0 means that we disable the check */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1081
		peer_tcp->tcp_fuse_rcv_unread_hiwater = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1082
	} else {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1083
		peer_tcp->tcp_fuse_rcv_unread_hiwater =
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1084
		    MAX(sndbuf >> 14, tcp_fusion_rcv_unread_min);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1085
	}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1086
	return (maxpsz);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents:
diff changeset
  1087
}