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