Print this page
5880 Increase IOV_MAX to at least 1024
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com>
*** 76,85 ****
--- 76,86 ----
#include <sys/sunldi_impl.h>
#include <sys/autoconf.h>
#include <sys/policy.h>
#include <sys/dld.h>
#include <sys/zone.h>
+ #include <sys/limits.h>
#include <c2/audit.h>
/*
* This define helps improve the readability of streams code while
* still maintaining a very old streams performance enhancement. The
*** 985,1000 ****
* If this is the first time we're called by e.g. strread
* only do the downcall if there is a deferred wakeup
* (registered in sd_wakeq).
*/
struiod_t uiod;
if (first)
stp->sd_wakeq &= ~RSLEEP;
! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov,
! sizeof (uiod.d_iov) / sizeof (*uiod.d_iov));
uiod.d_mp = 0;
/*
* Mark that a thread is in rwnext on the read side
* to prevent strrput from nacking ioctls immediately.
* When the last concurrent rwnext returns
--- 986,1009 ----
* If this is the first time we're called by e.g. strread
* only do the downcall if there is a deferred wakeup
* (registered in sd_wakeq).
*/
struiod_t uiod;
+ struct iovec buf[IOV_MAX_STACK];
+ int iovlen = 0;
if (first)
stp->sd_wakeq &= ~RSLEEP;
! if (uiop->uio_iovcnt > IOV_MAX_STACK) {
! iovlen = uiop->uio_iovcnt * sizeof (iovec_t);
! uiod.d_iov = kmem_alloc(iovlen, KM_SLEEP);
! } else {
! uiod.d_iov = buf;
! }
!
! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov, uiop->uio_iovcnt);
uiod.d_mp = 0;
/*
* Mark that a thread is in rwnext on the read side
* to prevent strrput from nacking ioctls immediately.
* When the last concurrent rwnext returns
*** 1029,1038 ****
--- 1038,1049 ----
ASSERT(MUTEX_HELD(&stp->sd_lock));
if (error == 0 || error == EWOULDBLOCK) {
if ((bp = uiod.d_mp) != NULL) {
*errorp = 0;
ASSERT(MUTEX_HELD(&stp->sd_lock));
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (bp);
}
error = 0;
} else if (error == EINVAL) {
/*
*** 1048,1059 ****
--- 1059,1076 ----
*/
error = 0;
} else {
*errorp = error;
ASSERT(MUTEX_HELD(&stp->sd_lock));
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (NULL);
}
+
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
+
/*
* Try a getq in case a rwnext() generated mblk
* has bubbled up via strrput().
*/
}
*** 2544,2553 ****
--- 2561,2572 ----
static int
strput(struct stdata *stp, mblk_t *mctl, struct uio *uiop, ssize_t *iosize,
int b_flag, int pri, int flags)
{
struiod_t uiod;
+ struct iovec buf[IOV_MAX_STACK];
+ int iovlen = 0;
mblk_t *mp;
queue_t *wqp = stp->sd_wrq;
int error = 0;
ssize_t count = *iosize;
*** 2635,2651 ****
}
mp->b_flag |= b_flag;
mp->b_band = (uchar_t)pri;
! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov,
! sizeof (uiod.d_iov) / sizeof (*uiod.d_iov));
uiod.d_uio.uio_offset = 0;
uiod.d_mp = mp;
error = rwnext(wqp, &uiod);
if (! uiod.d_mp) {
uioskip(uiop, *iosize);
return (error);
}
ASSERT(mp == uiod.d_mp);
if (error == EINVAL) {
/*
--- 2654,2678 ----
}
mp->b_flag |= b_flag;
mp->b_band = (uchar_t)pri;
! if (uiop->uio_iovcnt > IOV_MAX_STACK) {
! iovlen = uiop->uio_iovcnt * sizeof (iovec_t);
! uiod.d_iov = (struct iovec *)kmem_alloc(iovlen, KM_SLEEP);
! } else {
! uiod.d_iov = buf;
! }
!
! (void) uiodup(uiop, &uiod.d_uio, uiod.d_iov, uiop->uio_iovcnt);
uiod.d_uio.uio_offset = 0;
uiod.d_mp = mp;
error = rwnext(wqp, &uiod);
if (! uiod.d_mp) {
uioskip(uiop, *iosize);
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (error);
}
ASSERT(mp == uiod.d_mp);
if (error == EINVAL) {
/*
*** 2659,2686 ****
--- 2686,2721 ----
* so fall-back to putnext().
*/
error = 0;
} else {
freemsg(mp);
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (error);
}
/* Have to check canput before consuming data from the uio */
if (pri == 0) {
if (!canputnext(wqp) && !(flags & MSG_IGNFLOW)) {
freemsg(mp);
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (EWOULDBLOCK);
}
} else {
if (!bcanputnext(wqp, pri) && !(flags & MSG_IGNFLOW)) {
freemsg(mp);
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (EWOULDBLOCK);
}
}
ASSERT(mp == uiod.d_mp);
/* Copyin data from the uio */
if ((error = struioget(wqp, mp, &uiod, 0)) != 0) {
freemsg(mp);
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (error);
}
uioskip(uiop, *iosize);
if (flags & MSG_IGNFLOW) {
/*
*** 2693,2702 ****
--- 2728,2739 ----
} else {
stream_willservice(stp);
putnext(wqp, mp);
stream_runservice(stp);
}
+ if (iovlen != 0)
+ kmem_free(uiod.d_iov, iovlen);
return (0);
}
/*
* Write attempts to break the write request into messages conforming