summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/tcp/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/inet/tcp/tcp.c')
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c537
1 files changed, 38 insertions, 499 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index a729e2d066..12b781c0bc 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -66,8 +66,6 @@ const char tcp_version[] = "%Z%%M% %I% %E% SMI";
#include <sys/isa_defs.h>
#include <sys/md5.h>
#include <sys/random.h>
-#include <sys/sodirect.h>
-#include <sys/uio.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/ip6.h>
@@ -218,23 +216,6 @@ const char tcp_version[] = "%Z%%M% %I% %E% SMI";
* behaviour. Once tcp_issocket is unset, its never set for the
* life of that connection.
*
- * In support of on-board asynchronous DMA hardware (e.g. Intel I/OAT)
- * two consoldiation private KAPIs are used to enqueue M_DATA mblk_t's
- * directly to the socket (sodirect) and start an asynchronous copyout
- * to a user-land receive-side buffer (uioa) when a blocking socket read
- * (e.g. read, recv, ...) is pending.
- *
- * This is accomplished when tcp_issocket is set and tcp_sodirect is not
- * NULL so points to an sodirect_t and if marked enabled then we enqueue
- * all mblk_t's directly to the socket.
- *
- * Further, if the sodirect_t sod_uioa and if marked enabled (due to a
- * blocking socket read, e.g. user-land read, recv, ...) then an asynchronous
- * copyout will be started directly to the user-land uio buffer. Also, as we
- * have a pending read, TCP's push logic can take into account the number of
- * bytes to be received and only awake the blocked read()er when the uioa_t
- * byte count has been satisfied.
- *
* IPsec notes :
*
* Since a packet is always executed on the correct TCP perimeter
@@ -265,37 +246,6 @@ squeue_func_t tcp_squeue_close_proc;
squeue_func_t tcp_squeue_wput_proc;
/*
- * Macros for sodirect:
- *
- * SOD_PTR_ENTER(tcp, sodp) - for the tcp_t pointer "tcp" set the
- * sodirect_t pointer "sodp" to the socket/tcp shared sodirect_t
- * if it exists and is enabled, else to NULL. Note, in the current
- * sodirect implementation the sod_lock must not be held across any
- * STREAMS call (e.g. putnext) else a "recursive mutex_enter" PANIC
- * will result as sod_lock is the streamhead stdata.sd_lock.
- *
- * SOD_NOT_ENABLED(tcp) - return true if not a sodirect tcp_t or the
- * sodirect_t isn't enabled, usefull for ASSERT()ing that a recieve
- * side tcp code path dealing with a tcp_rcv_list or putnext() isn't
- * being used when sodirect code paths should be.
- */
-
-#define SOD_PTR_ENTER(tcp, sodp) \
- (sodp) = (tcp)->tcp_sodirect; \
- \
- if ((sodp) != NULL) { \
- mutex_enter((sodp)->sod_lock); \
- if (!((sodp)->sod_state & SOD_ENABLED)) { \
- mutex_exit((sodp)->sod_lock); \
- (sodp) = NULL; \
- } \
- }
-
-#define SOD_NOT_ENABLED(tcp) \
- ((tcp)->tcp_sodirect == NULL || \
- !((tcp)->tcp_sodirect->sod_state & SOD_ENABLED))
-
-/*
* This controls how tiny a write must be before we try to copy it
* into the the mblk on the tail of the transmit queue. Not much
* speedup is observed for values larger than sixteen. Zero will
@@ -3858,7 +3808,6 @@ tcp_clean_death(tcp_t *tcp, int err, uint8_t tag)
mblk_t *mp;
queue_t *q;
tcp_stack_t *tcps = tcp->tcp_tcps;
- sodirect_t *sodp;
TCP_CLD_STAT(tag);
@@ -3923,13 +3872,6 @@ tcp_clean_death(tcp_t *tcp, int err, uint8_t tag)
return (-1);
}
- /* If sodirect, not anymore */
- SOD_PTR_ENTER(tcp, sodp);
- if (sodp != NULL) {
- tcp->tcp_sodirect = NULL;
- mutex_exit(sodp->sod_lock);
- }
-
q = tcp->tcp_rq;
/* Trash all inbound data */
@@ -4294,11 +4236,6 @@ tcp_close_output(void *arg, mblk_t *mp, void *arg2)
*/
/* FALLTHRU */
default:
- if (tcp->tcp_sodirect != NULL) {
- /* Ok, no more sodirect */
- tcp->tcp_sodirect = NULL;
- }
-
if (tcp->tcp_fused)
tcp_unfuse(tcp);
@@ -6444,15 +6381,6 @@ tcp_connect(tcp_t *tcp, mblk_t *mp)
*(uint16_t *)tcp->tcp_tcph->th_lport = tcp->tcp_lport;
}
- if (tcp->tcp_issocket) {
- /*
- * TCP is _D_SODIRECT and sockfs is directly above so save
- * the shared sonode sodirect_t pointer (if any) to enable
- * TCP sodirect.
- */
- tcp->tcp_sodirect = SOD_QTOSODP(tcp->tcp_rq);
- }
-
switch (tcp->tcp_state) {
case TCPS_IDLE:
/*
@@ -8262,9 +8190,6 @@ tcp_reinit_values(tcp)
ASSERT(!tcp->tcp_kssl_pending);
PRESERVE(tcp->tcp_kssl_ent);
- /* Sodirect */
- tcp->tcp_sodirect = NULL;
-
tcp->tcp_closemp_used = B_FALSE;
#ifdef DEBUG
@@ -8357,9 +8282,6 @@ tcp_init_values(tcp_t *tcp)
tcp->tcp_fuse_rcv_unread_hiwater = 0;
tcp->tcp_fuse_rcv_unread_cnt = 0;
- /* Sodirect */
- tcp->tcp_sodirect = NULL;
-
/* Initialize the header template */
if (tcp->tcp_ipversion == IPV4_VERSION) {
err = tcp_header_init_ipv4(tcp);
@@ -11769,9 +11691,6 @@ tcp_rcv_drain(queue_t *q, tcp_t *tcp)
if (tcp->tcp_listener != NULL)
return (ret);
- /* Can't be sodirect enabled */
- ASSERT(SOD_NOT_ENABLED(tcp));
-
/*
* Handle two cases here: we are currently fused or we were
* previously fused and have some urgent data to be delivered
@@ -11851,9 +11770,6 @@ tcp_rcv_enqueue(tcp_t *tcp, mblk_t *mp, uint_t seg_len)
ASSERT(seg_len == msgdsize(mp));
ASSERT(tcp->tcp_rcv_list == NULL || tcp->tcp_rcv_last_head != NULL);
- /* Can't be sodirect enabled */
- ASSERT(SOD_NOT_ENABLED(tcp));
-
if (tcp->tcp_rcv_list == NULL) {
ASSERT(tcp->tcp_rcv_last_head == NULL);
tcp->tcp_rcv_list = mp;
@@ -11874,216 +11790,6 @@ tcp_rcv_enqueue(tcp_t *tcp, mblk_t *mp, uint_t seg_len)
}
/*
- * The tcp_rcv_sod_XXX() functions enqueue data directly to the socket
- * above, in addition when uioa is enabled schedule an asynchronous uio
- * prior to enqueuing. They implement the combinhed semantics of the
- * tcp_rcv_XXX() functions, tcp_rcv_list push logic, and STREAMS putnext()
- * canputnext(), i.e. flow-control with backenable.
- *
- * tcp_sod_wakeup() is called where tcp_rcv_drain() would be called in the
- * non sodirect connection but as there are no tcp_tcv_list mblk_t's we deal
- * with the rcv_wnd and push timer and call the sodirect wakeup function.
- *
- * Must be called with sodp->sod_lock held and will return with the lock
- * released.
- */
-static uint_t
-tcp_rcv_sod_wakeup(tcp_t *tcp, sodirect_t *sodp)
-{
- queue_t *q = tcp->tcp_rq;
- uint_t thwin;
- tcp_stack_t *tcps = tcp->tcp_tcps;
- uint_t ret = 0;
-
- /* Can't be an eager connection */
- ASSERT(tcp->tcp_listener == NULL);
-
- /* Caller must have lock held */
- ASSERT(MUTEX_HELD(sodp->sod_lock));
-
- /* Sodirect mode so must not be a tcp_rcv_list */
- ASSERT(tcp->tcp_rcv_list == NULL);
-
- if (SOD_QFULL(sodp)) {
- /* Q is full, mark Q for need backenable */
- SOD_QSETBE(sodp);
- }
- /* Last advertised rwnd, i.e. rwnd last sent in a packet */
- thwin = ((uint_t)BE16_TO_U16(tcp->tcp_tcph->th_win))
- << tcp->tcp_rcv_ws;
- /* This is peer's calculated send window (our available rwnd). */
- thwin -= tcp->tcp_rnxt - tcp->tcp_rack;
- /*
- * Increase the receive window to max. But we need to do receiver
- * SWS avoidance. This means that we need to check the increase of
- * of receive window is at least 1 MSS.
- */
- if (!SOD_QFULL(sodp) && (q->q_hiwat - thwin >= tcp->tcp_mss)) {
- /*
- * If the window that the other side knows is less than max
- * deferred acks segments, send an update immediately.
- */
- if (thwin < tcp->tcp_rack_cur_max * tcp->tcp_mss) {
- BUMP_MIB(&tcps->tcps_mib, tcpOutWinUpdate);
- ret = TH_ACK_NEEDED;
- }
- tcp->tcp_rwnd = q->q_hiwat;
- }
-
- if (!SOD_QEMPTY(sodp)) {
- /* Wakeup to socket */
- sodp->sod_state &= SOD_WAKE_CLR;
- sodp->sod_state |= SOD_WAKE_DONE;
- (sodp->sod_wakeup)(sodp);
- /* wakeup() does the mutex_ext() */
- } else {
- /* Q is empty, no need to wake */
- sodp->sod_state &= SOD_WAKE_CLR;
- sodp->sod_state |= SOD_WAKE_NOT;
- mutex_exit(sodp->sod_lock);
- }
-
- /* No need for the push timer now. */
- if (tcp->tcp_push_tid != 0) {
- (void) TCP_TIMER_CANCEL(tcp, tcp->tcp_push_tid);
- tcp->tcp_push_tid = 0;
- }
-
- return (ret);
-}
-
-/*
- * Called where tcp_rcv_enqueue()/putnext(RD(q)) would be. For M_DATA
- * mblk_t's if uioa enabled then start a uioa asynchronous copy directly
- * to the user-land buffer and flag the mblk_t as such.
- *
- * Also, handle tcp_rwnd.
- */
-uint_t
-tcp_rcv_sod_enqueue(tcp_t *tcp, sodirect_t *sodp, mblk_t *mp, uint_t seg_len)
-{
- uioa_t *uioap = &sodp->sod_uioa;
- boolean_t qfull;
- uint_t thwin;
-
- /* Can't be an eager connection */
- ASSERT(tcp->tcp_listener == NULL);
-
- /* Caller must have lock held */
- ASSERT(MUTEX_HELD(sodp->sod_lock));
-
- /* Sodirect mode so must not be a tcp_rcv_list */
- ASSERT(tcp->tcp_rcv_list == NULL);
-
- /* Passed in segment length must be equal to mblk_t chain data size */
- ASSERT(seg_len == msgdsize(mp));
-
- if (DB_TYPE(mp) != M_DATA) {
- /* Only process M_DATA mblk_t's */
- goto enq;
- }
- if (uioap->uioa_state & UIOA_ENABLED) {
- /* Uioa is enabled */
- mblk_t *mp1 = mp;
-
- if (seg_len > uioap->uio_resid) {
- /*
- * There isn't enough uio space for the mblk_t chain
- * so disable uioa such that this and any additional
- * mblk_t data is handled by the socket and schedule
- * the socket for wakeup to finish this uioa.
- */
- uioap->uioa_state &= UIOA_CLR;
- uioap->uioa_state |= UIOA_FINI;
- if (sodp->sod_state & SOD_WAKE_NOT) {
- sodp->sod_state &= SOD_WAKE_CLR;
- sodp->sod_state |= SOD_WAKE_NEED;
- }
- goto enq;
- }
- do {
- uint32_t len = MBLKL(mp1);
-
- if (!uioamove(mp1->b_rptr, len, UIO_READ, uioap)) {
- /* Scheduled, mark dblk_t as such */
- DB_FLAGS(mp1) |= DBLK_UIOA;
- } else {
- /* Error, turn off async processing */
- uioap->uioa_state &= UIOA_CLR;
- uioap->uioa_state |= UIOA_FINI;
- break;
- }
- } while ((mp1 = mp1->b_cont) != NULL);
-
- if (mp1 != NULL || uioap->uio_resid == 0) {
- /*
- * Not all mblk_t(s) uioamoved (error) or all uio
- * space has been consumed so schedule the socket
- * for wakeup to finish this uio.
- */
- sodp->sod_state &= SOD_WAKE_CLR;
- sodp->sod_state |= SOD_WAKE_NEED;
- }
- } else if (uioap->uioa_state & UIOA_FINI) {
- /*
- * Post UIO_ENABLED waiting for socket to finish processing
- * so just enqueue and update tcp_rwnd.
- */
- if (SOD_QFULL(sodp))
- tcp->tcp_rwnd -= seg_len;
- } else if (sodp->sod_want > 0) {
- /*
- * Uioa isn't enabled but sodirect has a pending read().
- */
- if (SOD_QCNT(sodp) + seg_len >= sodp->sod_want) {
- if (sodp->sod_state & SOD_WAKE_NOT) {
- /* Schedule socket for wakeup */
- sodp->sod_state &= SOD_WAKE_CLR;
- sodp->sod_state |= SOD_WAKE_NEED;
- }
- tcp->tcp_rwnd -= seg_len;
- }
- } else if (SOD_QCNT(sodp) + seg_len >= tcp->tcp_rq->q_hiwat >> 3) {
- /*
- * No pending sodirect read() so used the default
- * TCP push logic to guess that a push is needed.
- */
- if (sodp->sod_state & SOD_WAKE_NOT) {
- /* Schedule socket for wakeup */
- sodp->sod_state &= SOD_WAKE_CLR;
- sodp->sod_state |= SOD_WAKE_NEED;
- }
- tcp->tcp_rwnd -= seg_len;
- } else {
- /* Just update tcp_rwnd */
- tcp->tcp_rwnd -= seg_len;
- }
-enq:
- qfull = SOD_QFULL(sodp);
-
- (sodp->sod_enqueue)(sodp, mp);
-
- if (! qfull && SOD_QFULL(sodp)) {
- /* Wasn't QFULL, now QFULL, need back-enable */
- SOD_QSETBE(sodp);
- }
-
- /*
- * Check to see if remote avail swnd < mss due to delayed ACK,
- * first get advertised rwnd.
- */
- thwin = ((uint_t)BE16_TO_U16(tcp->tcp_tcph->th_win));
- /* Minus delayed ACK count */
- thwin -= tcp->tcp_rnxt - tcp->tcp_rack;
- if (thwin < tcp->tcp_mss) {
- /* Remote avail swnd < mss, need ACK now */
- return (TH_ACK_NEEDED);
- }
-
- return (0);
-}
-
-/*
* DEFAULT TCP ENTRY POINT via squeue on READ side.
*
* This is the default entry function into TCP on the read side. TCP is
@@ -15281,39 +14987,13 @@ est:
tcp_rcv_enqueue(tcp, mp, seg_len);
}
} else {
- sodirect_t *sodp = tcp->tcp_sodirect;
-
- /*
- * If an sodirect connection and an enabled sodirect_t then
- * sodp will be set to point to the tcp_t/sonode_t shared
- * sodirect_t and the sodirect_t's lock will be held.
- */
- if (sodp != NULL) {
- mutex_enter(sodp->sod_lock);
- if (!(sodp->sod_state & SOD_ENABLED)) {
- mutex_exit(sodp->sod_lock);
- sodp = NULL;
- } else if (tcp->tcp_kssl_ctx != NULL &&
- DB_TYPE(mp) == M_DATA) {
- mutex_exit(sodp->sod_lock);
- sodp = NULL;
- }
- }
if (mp->b_datap->db_type != M_DATA ||
(flags & TH_MARKNEXT_NEEDED)) {
- if (sodp != NULL) {
- if (!SOD_QEMPTY(sodp) &&
- (sodp->sod_state & SOD_WAKE_NOT)) {
- flags |= tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() did the mutex_exit() */
- mutex_enter(sodp->sod_lock);
- }
- } else if (tcp->tcp_rcv_list != NULL) {
+ if (tcp->tcp_rcv_list != NULL) {
flags |= tcp_rcv_drain(tcp->tcp_rq, tcp);
}
ASSERT(tcp->tcp_rcv_list == NULL ||
tcp->tcp_fused_sigurg);
-
if (flags & TH_MARKNEXT_NEEDED) {
#ifdef DEBUG
(void) strlog(TCP_MOD_ID, 0, 1, SL_TRACE,
@@ -15331,40 +15011,11 @@ est:
DTRACE_PROBE1(kssl_mblk__ksslinput_data1,
mblk_t *, mp);
tcp_kssl_input(tcp, mp);
- } else if (sodp) {
- flags |= tcp_rcv_sod_enqueue(
- tcp, sodp, mp, seg_len);
- flags |= tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() did the mutex_exit() */
} else {
putnext(tcp->tcp_rq, mp);
if (!canputnext(tcp->tcp_rq))
tcp->tcp_rwnd -= seg_len;
}
- } else if ((tcp->tcp_kssl_ctx != NULL) &&
- (DB_TYPE(mp) == M_DATA)) {
- /* Do SSL processing first */
- DTRACE_PROBE1(kssl_mblk__ksslinput_data2,
- mblk_t *, mp);
- tcp_kssl_input(tcp, mp);
- } else if (sodp != NULL) {
- /*
- * Sodirect so all mblk_t's are queued on the
- * socket directly, check for wakeup of blocked
- * reader (if any), and last if flow-controled.
- */
- flags |= tcp_rcv_sod_enqueue(tcp, sodp, mp, seg_len);
- if ((sodp->sod_state & SOD_WAKE_NEED) ||
- (flags & (TH_PUSH|TH_FIN))) {
- flags |= tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() did the mutex_exit() */
- } else {
- if (SOD_QFULL(sodp)) {
- /* Q is full, need backenable */
- SOD_QSETBE(sodp);
- }
- mutex_exit(sodp->sod_lock);
- }
} else if ((flags & (TH_PUSH|TH_FIN)) ||
tcp->tcp_rcv_cnt + seg_len >= tcp->tcp_rq->q_hiwat >> 3) {
if (tcp->tcp_rcv_list != NULL) {
@@ -15384,33 +15035,41 @@ est:
tcp_rcv_enqueue(tcp, mp, seg_len);
flags |= tcp_rcv_drain(tcp->tcp_rq, tcp);
} else {
- putnext(tcp->tcp_rq, mp);
- if (!canputnext(tcp->tcp_rq))
- tcp->tcp_rwnd -= seg_len;
+ /* Does this need SSL processing first? */
+ if ((tcp->tcp_kssl_ctx != NULL) &&
+ (DB_TYPE(mp) == M_DATA)) {
+ DTRACE_PROBE1(
+ kssl_mblk__ksslinput_data2,
+ mblk_t *, mp);
+ tcp_kssl_input(tcp, mp);
+ } else {
+ putnext(tcp->tcp_rq, mp);
+ if (!canputnext(tcp->tcp_rq))
+ tcp->tcp_rwnd -= seg_len;
+ }
}
} else {
/*
* Enqueue all packets when processing an mblk
* from the co queue and also enqueue normal packets.
+ * For packets which belong to SSL stream do SSL
+ * processing first.
*/
- tcp_rcv_enqueue(tcp, mp, seg_len);
+ if ((tcp->tcp_kssl_ctx != NULL) &&
+ (DB_TYPE(mp) == M_DATA)) {
+ DTRACE_PROBE1(kssl_mblk__tcpksslin3,
+ mblk_t *, mp);
+ tcp_kssl_input(tcp, mp);
+ } else {
+ tcp_rcv_enqueue(tcp, mp, seg_len);
+ }
}
/*
* Make sure the timer is running if we have data waiting
* for a push bit. This provides resiliency against
* implementations that do not correctly generate push bits.
- *
- * Note, for sodirect if Q isn't empty and there's not a
- * pending wakeup then we need a timer. Also note that sodp
- * is assumed to be still valid after exit()ing the sod_lock
- * above and while the SOD state can change it can only change
- * such that the Q is empty now even though data was added
- * above.
*/
- if (((sodp != NULL && !SOD_QEMPTY(sodp) &&
- (sodp->sod_state & SOD_WAKE_NOT)) ||
- (sodp == NULL && tcp->tcp_rcv_list != NULL)) &&
- tcp->tcp_push_tid == 0) {
+ if (tcp->tcp_rcv_list != NULL && tcp->tcp_push_tid == 0) {
/*
* The connection may be closed at this point, so don't
* do anything for a detached tcp.
@@ -15422,7 +15081,6 @@ est:
tcps->tcps_push_timer_interval));
}
}
-
xmit_check:
/* Is there anything left to do? */
ASSERT(!(flags & TH_MARKNEXT_NEEDED));
@@ -15498,27 +15156,13 @@ ack_check:
/*
* Send up any queued data and then send the mark message
*/
- sodirect_t *sodp;
-
- SOD_PTR_ENTER(tcp, sodp);
+ if (tcp->tcp_rcv_list != NULL) {
+ flags |= tcp_rcv_drain(tcp->tcp_rq, tcp);
+ }
+ ASSERT(tcp->tcp_rcv_list == NULL || tcp->tcp_fused_sigurg);
mp1 = tcp->tcp_urp_mark_mp;
tcp->tcp_urp_mark_mp = NULL;
- if (sodp != NULL) {
-
- ASSERT(tcp->tcp_rcv_list == NULL);
-
- flags |= tcp_rcv_sod_enqueue(tcp, sodp, mp1, 0);
- flags |= tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() does the mutex_exit() */
- } else if (tcp->tcp_rcv_list != NULL) {
- flags |= tcp_rcv_drain(tcp->tcp_rq, tcp);
-
- ASSERT(tcp->tcp_rcv_list == NULL ||
- tcp->tcp_fused_sigurg);
-
- putnext(tcp->tcp_rq, mp1);
- }
#ifdef DEBUG
(void) strlog(TCP_MOD_ID, 0, 1, SL_TRACE,
"tcp_rput: sending zero-length %s %s",
@@ -15526,6 +15170,7 @@ ack_check:
"MSGNOTMARKNEXT"),
tcp_display(tcp, NULL, DISP_PORT_ONLY));
#endif /* DEBUG */
+ putnext(tcp->tcp_rq, mp1);
flags &= ~TH_SEND_URP_MARK;
}
if (flags & TH_ACK_NEEDED) {
@@ -15563,32 +15208,14 @@ ack_check:
* In the eager case tcp_rsrv will do this when run
* after tcp_accept is done.
*/
- sodirect_t *sodp;
-
ASSERT(tcp->tcp_listener == NULL);
-
- SOD_PTR_ENTER(tcp, sodp);
- if (sodp != NULL) {
- /* No more sodirect */
- tcp->tcp_sodirect = NULL;
- if (!SOD_QEMPTY(sodp)) {
- /* Mblk(s) to process, notify */
- flags |= tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() does the mutex_exit() */
- } else {
- /* Nothing to process */
- mutex_exit(sodp->sod_lock);
- }
- } else if (tcp->tcp_rcv_list != NULL) {
+ if (tcp->tcp_rcv_list != NULL) {
/*
* Push any mblk(s) enqueued from co processing.
*/
flags |= tcp_rcv_drain(tcp->tcp_rq, tcp);
-
- ASSERT(tcp->tcp_rcv_list == NULL ||
- tcp->tcp_fused_sigurg);
}
-
+ ASSERT(tcp->tcp_rcv_list == NULL || tcp->tcp_fused_sigurg);
if ((mp1 = mi_tpi_ordrel_ind()) != NULL) {
tcp->tcp_ordrel_done = B_TRUE;
putnext(tcp->tcp_rq, mp1);
@@ -16358,8 +15985,6 @@ tcp_rsrv_input(void *arg, mblk_t *mp, void *arg2)
queue_t *q = tcp->tcp_rq;
uint_t thwin;
tcp_stack_t *tcps = tcp->tcp_tcps;
- sodirect_t *sodp;
- boolean_t fc;
freeb(mp);
@@ -16410,27 +16035,7 @@ tcp_rsrv_input(void *arg, mblk_t *mp, void *arg2)
return;
}
- SOD_PTR_ENTER(tcp, sodp);
- if (sodp != NULL) {
- /* An sodirect connection */
- if (SOD_QFULL(sodp)) {
- /* Flow-controlled, need another back-enable */
- fc = B_TRUE;
- SOD_QSETBE(sodp);
- } else {
- /* Not flow-controlled */
- fc = B_FALSE;
- }
- mutex_exit(sodp->sod_lock);
- } else if (canputnext(q)) {
- /* STREAMS, not flow-controlled */
- fc = B_FALSE;
- } else {
- /* STREAMS, flow-controlled */
- fc = B_TRUE;
- }
- if (!fc) {
- /* Not flow-controlled, open rwnd */
+ if (canputnext(q)) {
tcp->tcp_rwnd = q->q_hiwat;
thwin = ((uint_t)BE16_TO_U16(tcp->tcp_tcph->th_win))
<< tcp->tcp_rcv_ws;
@@ -16449,32 +16054,13 @@ tcp_rsrv_input(void *arg, mblk_t *mp, void *arg2)
BUMP_MIB(&tcps->tcps_mib, tcpOutWinUpdate);
}
}
-
/* Handle a failure to allocate a T_ORDREL_IND here */
if (tcp->tcp_fin_rcvd && !tcp->tcp_ordrel_done) {
ASSERT(tcp->tcp_listener == NULL);
-
- SOD_PTR_ENTER(tcp, sodp);
- if (sodp != NULL) {
- /* No more sodirect */
- tcp->tcp_sodirect = NULL;
- if (!SOD_QEMPTY(sodp)) {
- /* Notify mblk(s) to process */
- (void) tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() does the mutex_exit() */
- } else {
- /* Nothing to process */
- mutex_exit(sodp->sod_lock);
- }
- } else if (tcp->tcp_rcv_list != NULL) {
- /*
- * Push any mblk(s) enqueued from co processing.
- */
- (void) tcp_rcv_drain(tcp->tcp_rq, tcp);
- ASSERT(tcp->tcp_rcv_list == NULL ||
- tcp->tcp_fused_sigurg);
+ if (tcp->tcp_rcv_list != NULL) {
+ (void) tcp_rcv_drain(q, tcp);
}
-
+ ASSERT(tcp->tcp_rcv_list == NULL || tcp->tcp_fused_sigurg);
mp = mi_tpi_ordrel_ind();
if (mp) {
tcp->tcp_ordrel_done = B_TRUE;
@@ -18522,8 +18108,6 @@ tcp_accept_finish(void *arg, mblk_t *mp, void *arg2)
*/
if (tcp->tcp_rcv_list != NULL) {
/* We drain directly in case of fused tcp loopback */
- sodirect_t *sodp;
-
if (!tcp->tcp_fused && canputnext(q)) {
tcp->tcp_rwnd = q->q_hiwat;
thwin = ((uint_t)BE16_TO_U16(tcp->tcp_tcph->th_win))
@@ -18539,26 +18123,7 @@ tcp_accept_finish(void *arg, mblk_t *mp, void *arg2)
}
}
-
- SOD_PTR_ENTER(tcp, sodp);
- if (sodp != NULL) {
- /* Sodirect, move from rcv_list */
- ASSERT(!tcp->tcp_fused);
- while ((mp = tcp->tcp_rcv_list) != NULL) {
- tcp->tcp_rcv_list = mp->b_next;
- mp->b_next = NULL;
- (void) tcp_rcv_sod_enqueue(tcp, sodp, mp,
- msgdsize(mp));
- }
- tcp->tcp_rcv_last_head = NULL;
- tcp->tcp_rcv_last_tail = NULL;
- tcp->tcp_rcv_cnt = 0;
- (void) tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() did the mutex_exit() */
- } else {
- /* Not sodirect, drain */
- (void) tcp_rcv_drain(q, tcp);
- }
+ (void) tcp_rcv_drain(q, tcp);
/*
* For fused tcp loopback, back-enable peer endpoint
@@ -18750,21 +18315,6 @@ tcp_wput_accept(queue_t *q, mblk_t *mp)
listener = eager->tcp_listener;
eager->tcp_issocket = B_TRUE;
- /*
- * TCP is _D_SODIRECT and sockfs is directly above so
- * save shared sodirect_t pointer (if any).
- *
- * If tcp_fused and sodirect enabled disable it.
- */
- eager->tcp_sodirect = SOD_QTOSODP(eager->tcp_rq);
- if (eager->tcp_fused && eager->tcp_sodirect != NULL) {
- /* Fused, disable sodirect */
- mutex_enter(eager->tcp_sodirect->sod_lock);
- SOD_DISABLE(eager->tcp_sodirect);
- mutex_exit(eager->tcp_sodirect->sod_lock);
- eager->tcp_sodirect = NULL;
- }
-
econnp->conn_zoneid = listener->tcp_connp->conn_zoneid;
econnp->conn_allzones = listener->tcp_connp->conn_allzones;
ASSERT(econnp->conn_netstack ==
@@ -22551,7 +22101,6 @@ tcp_wput_ioctl(void *arg, mblk_t *mp, void *arg2)
tcp_fuse_disable_pair(tcp, B_FALSE);
}
tcp->tcp_issocket = B_FALSE;
- tcp->tcp_sodirect = NULL;
TCP_STAT(tcps, tcp_sock_fallback);
DB_TYPE(mp) = M_IOCACK;
@@ -23834,8 +23383,6 @@ tcp_push_timer(void *arg)
conn_t *connp = (conn_t *)arg;
tcp_t *tcp = connp->conn_tcp;
tcp_stack_t *tcps = tcp->tcp_tcps;
- uint_t flags;
- sodirect_t *sodp;
TCP_DBGSTAT(tcps, tcp_push_timer_cnt);
@@ -23847,17 +23394,9 @@ tcp_push_timer(void *arg)
*/
TCP_FUSE_SYNCSTR_PLUG_DRAIN(tcp);
tcp->tcp_push_tid = 0;
-
- SOD_PTR_ENTER(tcp, sodp);
- if (sodp != NULL) {
- flags = tcp_rcv_sod_wakeup(tcp, sodp);
- /* sod_wakeup() does the mutex_exit() */
- } else if (tcp->tcp_rcv_list != NULL) {
- flags = tcp_rcv_drain(tcp->tcp_rq, tcp);
- }
- if (flags == TH_ACK_NEEDED)
+ if ((tcp->tcp_rcv_list != NULL) &&
+ (tcp_rcv_drain(tcp->tcp_rq, tcp) == TH_ACK_NEEDED))
tcp_xmit_ctl(NULL, tcp, tcp->tcp_snxt, tcp->tcp_rnxt, TH_ACK);
-
TCP_FUSE_SYNCSTR_UNPLUG_DRAIN(tcp);
}