Increase send/receive queue to accomodate large readx/writex requests.

Receive packets in a small pieces (NB_SORECEIVE_CHUNK), so TCP slowstart will
get its ACKs faster.

Obtained from:	Darwin
This commit is contained in:
Boris Popov 2002-09-18 07:38:10 +00:00
parent 076ef4620b
commit 3c30400408
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103528
2 changed files with 78 additions and 22 deletions

View File

@ -66,8 +66,8 @@
#define M_NBDATA M_PCB
static int smb_tcpsndbuf = 10 * 1024;
static int smb_tcprcvbuf = 10 * 1024;
static int smb_tcpsndbuf = NB_SNDQ - 1;
static int smb_tcprcvbuf = NB_RCVQ - 1;
SYSCTL_DECL(_net_smb);
SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &smb_tcpsndbuf, 0, "");
@ -395,9 +395,9 @@ nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
{
struct socket *so = nbp->nbp_tso;
struct uio auio;
struct mbuf *m;
struct mbuf *m, *tm, *im;
u_int8_t rpcode;
int len;
int len, resid;
int error, rcvflg;
if (so == NULL)
@ -405,8 +405,12 @@ nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
if (mpp)
*mpp = NULL;
m = NULL;
for(;;) {
m = NULL;
/*
* Poll for a response header.
* If we don't have one waiting, return.
*/
error = nbssn_recvhdr(nbp, &len, &rpcode, MSG_DONTWAIT, td);
if (so->so_state &
(SS_ISDISCONNECTING | SS_ISDISCONNECTED | SS_CANTRCVMORE)) {
@ -418,32 +422,76 @@ nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
return error;
if (len == 0 && nbp->nbp_state != NBST_SESSION)
break;
/* no data, try again */
if (rpcode == NB_SSN_KEEPALIVE)
continue;
bzero(&auio, sizeof(auio));
auio.uio_resid = len;
auio.uio_td = td;
do {
/*
* Loop, blocking, for data following the response header.
*
* Note that we can't simply block here with MSG_WAITALL for the
* entire response size, as it may be larger than the TCP
* slow-start window that the sender employs. This will result
* in the sender stalling until the delayed ACK is sent, then
* resuming slow-start, resulting in very poor performance.
*
* Instead, we never request more than NB_SORECEIVE_CHUNK
* bytes at a time, resulting in an ack being pushed by
* the TCP code at the completion of each call.
*/
resid = len;
while (resid > 0) {
tm = NULL;
rcvflg = MSG_WAITALL;
error = so->so_proto->pr_usrreqs->pru_soreceive
(so, (struct sockaddr **)NULL,
&auio, &m, (struct mbuf **)NULL, &rcvflg);
} while (error == EWOULDBLOCK || error == EINTR ||
bzero(&auio, sizeof(auio));
auio.uio_resid = min(resid, NB_SORECEIVE_CHUNK);
auio.uio_td = td;
resid -= auio.uio_resid;
/*
* Spin until we have collected everything in
* this chunk.
*/
do {
rcvflg = MSG_WAITALL;
error = so->so_proto->pr_usrreqs->pru_soreceive
(so, (struct sockaddr **)NULL,
&auio, &m, (struct mbuf **)NULL, &rcvflg);
} while (error == EWOULDBLOCK || error == EINTR ||
error == ERESTART);
if (error)
break;
if (auio.uio_resid > 0) {
SMBERROR("packet is shorter than expected\n");
error = EPIPE;
break;
if (error)
goto out;
/* short return guarantees unhappiness */
if (auio.uio_resid > 0) {
SMBERROR("packet is shorter than expected\n");
error = EPIPE;
goto out;
}
/* append received chunk to previous chunk(s) */
if (m == NULL) {
m = tm;
} else {
/*
* Just glue the new chain on the end.
* Consumer will pullup as required.
*/
for (im = m; im->m_next != NULL; im = im->m_next)
;
im->m_next = tm;
}
}
/* got a session/message packet? */
if (nbp->nbp_state == NBST_SESSION &&
rpcode == NB_SSN_MESSAGE)
break;
/* drop packet and try for another */
NBDEBUG("non-session packet %x\n", rpcode);
if (m)
if (m) {
m_freem(m);
m = NULL;
}
}
out:
if (error) {
if (m)
m_freem(m);

View File

@ -78,8 +78,16 @@ struct nbpcb {
/*
* Nominal space allocated per a NETBIOS socket.
*/
#define NB_SNDQ (10 * 1024)
#define NB_RCVQ (20 * 1024)
#define NB_SNDQ (64 * 1024)
#define NB_RCVQ (64 * 1024)
/*
* TCP slowstart presents a problem in conjunction with large
* reads. To ensure a steady stream of ACKs while reading using
* large transaction sizes, we call soreceive() with a smaller
* buffer size. See nbssn_recv().
*/
#define NB_SORECEIVE_CHUNK (8 * 1024)
extern struct smb_tran_desc smb_tran_nbtcp_desc;