Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107934068
D35302.id106549.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D35302.id106549.diff
View Options
Index: sys/kern/uipc_usrreq.c
===================================================================
--- sys/kern/uipc_usrreq.c
+++ sys/kern/uipc_usrreq.c
@@ -302,11 +302,13 @@
static void unp_scan(struct mbuf *, void (*)(struct filedescent **, int));
static void unp_discard(struct file *);
static void unp_freerights(struct filedescent **, int);
-static int unp_internalize(struct mbuf **, struct thread *);
+static int unp_internalize(struct mbuf **, struct thread *,
+ struct mbuf **, u_int *, u_int *);
static void unp_internalize_fp(struct file *);
static int unp_externalize(struct mbuf *, struct mbuf **, int);
static int unp_externalize_fp(struct file *);
-static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *, int);
+static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *,
+ int, struct mbuf **, u_int *, u_int *);
static void unp_process_defers(void * __unused, int);
static void
@@ -1014,7 +1016,8 @@
error = EOPNOTSUPP;
goto release;
}
- if (control != NULL && (error = unp_internalize(&control, td)))
+ if (control != NULL &&
+ (error = unp_internalize(&control, td, NULL, NULL, NULL)))
goto release;
unp2 = NULL;
@@ -1051,7 +1054,8 @@
* SOCK_SEQPACKET (LOCAL_CREDS => WANTCRED_ONESHOT), or
* forever (LOCAL_CREDS_PERSISTENT => WANTCRED_ALWAYS).
*/
- control = unp_addsockcred(td, control, unp2->unp_flags);
+ control = unp_addsockcred(td, control, unp2->unp_flags, NULL,
+ NULL, NULL);
unp2->unp_flags &= ~UNP_WANTCRED_ONESHOT;
}
@@ -1140,8 +1144,8 @@
const struct sockaddr *from;
struct socket *so2;
struct sockbuf *sb;
- struct mbuf *f;
- u_int space;
+ struct mbuf *f, *clast;
+ u_int space, mbcnt, dspace __diagused, dmbcnt __diagused;
int error;
MPASS((uio != NULL && m == NULL) || (m != NULL && uio == NULL));
@@ -1163,8 +1167,11 @@
error = EFAULT;
goto out;
}
- f = m_get(M_WAITOK, MT_SONAME);
- if (c != NULL && (error = unp_internalize(&c, td)))
+ f = m_gethdr(M_WAITOK, MT_SONAME);
+ space = m->m_pkthdr.len;
+ mbcnt = MSIZE + m->m_pkthdr.memlen;
+ if (c != NULL &&
+ (error = unp_internalize(&c, td, &clast, &space, &mbcnt)))
goto out;
} else {
/* pru_sosend() with mbuf usually is a kernel thread. */
@@ -1177,7 +1184,7 @@
error = EMSGSIZE;
goto out;
}
- if ((f = m_get(M_NOWAIT, MT_SONAME)) == NULL) {
+ if ((f = m_gethdr(M_NOWAIT, MT_SONAME)) == NULL) {
error = ENOBUFS;
goto out;
}
@@ -1189,6 +1196,14 @@
m->m_pkthdr.csum_flags = 0;
m->m_pkthdr.fibnum = 0;
m->m_pkthdr.rsstype = 0;
+
+ space = m->m_pkthdr.len;
+ mbcnt = MSIZE;
+ for (struct mbuf *mb = m; mb != NULL; mb = mb->m_next) {
+ mbcnt += MSIZE;
+ if (mb->m_flags & M_EXT)
+ mbcnt += mb->m_ext.ext_size;
+ }
}
unp = sotounpcb(so);
@@ -1240,7 +1255,8 @@
}
if (unp2->unp_flags & UNP_WANTCRED_MASK)
- c = unp_addsockcred(td, c, unp2->unp_flags);
+ c = unp_addsockcred(td, c, unp2->unp_flags, &clast, &space,
+ &mbcnt);
if (unp->unp_addr != NULL)
from = (struct sockaddr *)unp->unp_addr;
else
@@ -1248,33 +1264,48 @@
f->m_len = from->sa_len;
MPASS(from->sa_len <= MLEN);
bcopy(from, mtod(f, void *), from->sa_len);
- space = f->m_len + m->m_pkthdr.len;
+ space += f->m_len;
- /* Concatenate: from -> control -> data. */
+ /*
+ * Concatenate mbufs: from -> control -> data.
+ * Save overall space and mbcnt in "from" mbuf.
+ */
if (c != NULL) {
- struct mbuf *clast;
+#ifdef INVARIANTS
+ struct mbuf *mc;
- space += m_length(c, &clast);
+ for (mc = c; mc->m_next != NULL; mc = mc->m_next);
+ MPASS(mc == clast);
+#endif
f->m_next = c;
clast->m_next = m;
c = NULL;
} else
f->m_next = m;
m = NULL;
+ f->m_pkthdr.len = space;
+ f->m_pkthdr.memlen = mbcnt;
+#ifdef INVARIANTS
+ dspace = dmbcnt = 0;
+ for (struct mbuf *mb = f; mb != NULL; mb = mb->m_next) {
+ dspace += mb->m_len;
+ dmbcnt += MSIZE;
+ if (mb->m_flags & M_EXT)
+ dmbcnt += mb->m_ext.ext_size;
+ }
+ MPASS(dspace == space);
+ MPASS(dmbcnt == mbcnt);
+#endif
so2 = unp2->unp_socket;
sb = &so2->so_rcv;
SOCK_RECVBUF_LOCK(so2);
if (space <= sbspace(sb)) {
STAILQ_INSERT_TAIL(&sb->uxdg_mb, f, m_stailqpkt);
- /* XXX: would be nice if m_uiotombuf() returns count. */
- for (; f != NULL ; f = f->m_next) {
- sb->sb_mbcnt += MSIZE;
- if (f->m_flags & M_EXT)
- sb->sb_mbcnt += f->m_ext.ext_size;
- }
sb->sb_ccc += space;
+ sb->sb_mbcnt += mbcnt;
sorwakeup_locked(so2);
+ f = NULL;
} else {
soroverflow_locked(so2);
error = (so->so_state & SS_NBIO) ? EAGAIN : ENOBUFS;
@@ -1363,7 +1394,7 @@
uipc_soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio,
struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
{
- struct mbuf *m, *m2;
+ struct mbuf *m;
int flags, error;
ssize_t len;
bool nonblock;
@@ -1416,7 +1447,9 @@
return (error);
}
}
- SOCK_RECVBUF_LOCK_ASSERT(so);
+
+ M_ASSERTPKTHDR(m);
+ KASSERT(m->m_type == MT_SONAME, ("m->m_type == %d", m->m_type));
if (uio->uio_td)
uio->uio_td->td_ru.ru_msgrcv++;
@@ -1425,15 +1458,10 @@
return (uipc_peek_dgram(so, psa, uio, controlp, flagsp));
STAILQ_REMOVE_HEAD(&so->so_rcv.uxdg_mb, m_stailqpkt);
- for (m2 = m; m2 != NULL; m2 = m2->m_next) {
- so->so_rcv.sb_ccc -= m2->m_len;
- so->so_rcv.sb_mbcnt -= MSIZE;
- if (m2->m_flags & M_EXT)
- so->so_rcv.sb_mbcnt -= m2->m_ext.ext_size;
- }
+ so->so_rcv.sb_ccc -= m->m_pkthdr.len;
+ so->so_rcv.sb_mbcnt -= m->m_pkthdr.memlen;
SOCK_RECVBUF_UNLOCK(so);
- KASSERT(m->m_type == MT_SONAME, ("m->m_type == %d", m->m_type));
if (psa != NULL)
*psa = sodupsockaddr(mtod(m, struct sockaddr *), M_WAITOK);
m = m_free(m);
@@ -2504,7 +2532,8 @@
}
static int
-unp_internalize(struct mbuf **controlp, struct thread *td)
+unp_internalize(struct mbuf **controlp, struct thread *td,
+ struct mbuf **clast, u_int *space, u_int *mbcnt)
{
struct mbuf *control, **initial_controlp;
struct proc *p;
@@ -2521,6 +2550,7 @@
int i, j, error, *fdp, oldfds;
u_int newlen;
+ MPASS((*controlp)->m_next == NULL); /* COMPAT_OLDSOCK may violate */
UNP_LINK_UNLOCK_ASSERT();
p = td->td_proc;
@@ -2667,6 +2697,13 @@
goto out;
}
+ if (space != NULL) {
+ *space += (*controlp)->m_len;
+ *mbcnt += MSIZE;
+ if ((*controlp)->m_flags & M_EXT)
+ *mbcnt += (*controlp)->m_ext.ext_size;
+ *clast = *controlp;
+ }
controlp = &(*controlp)->m_next;
}
if (clen > 0)
@@ -2680,7 +2717,8 @@
}
static struct mbuf *
-unp_addsockcred(struct thread *td, struct mbuf *control, int mode)
+unp_addsockcred(struct thread *td, struct mbuf *control, int mode,
+ struct mbuf **clast, u_int *space, u_int *mbcnt)
{
struct mbuf *m, *n, *n_prev;
const struct cmsghdr *cm;
@@ -2699,6 +2737,7 @@
m = sbcreatecontrol(NULL, ctrlsz, cmsgtype, SOL_SOCKET, M_NOWAIT);
if (m == NULL)
return (control);
+ MPASS((m->m_flags & M_EXT) == 0 && m->m_next == NULL);
if (mode & UNP_WANTCRED_ALWAYS) {
struct sockcred2 *sc;
@@ -2740,6 +2779,25 @@
control = n->m_next;
else
n_prev->m_next = n->m_next;
+ if (space != NULL) {
+ MPASS(*space >= n->m_len);
+ *space -= n->m_len;
+ MPASS(*mbcnt >= MSIZE);
+ *mbcnt -= MSIZE;
+ if (n->m_flags & M_EXT) {
+ MPASS(*mbcnt >=
+ n->m_ext.ext_size);
+ *mbcnt -= n->m_ext.ext_size;
+ }
+ MPASS(clast);
+ if (*clast == n) {
+ MPASS(n->m_next == NULL);
+ if (n_prev == NULL)
+ *clast = m;
+ else
+ *clast = n_prev;
+ }
+ }
n = m_free(n);
} else {
n_prev = n;
@@ -2749,6 +2807,10 @@
/* Prepend it to the head. */
m->m_next = control;
+ if (space != NULL) {
+ *space += m->m_len;
+ *mbcnt += MSIZE;
+ }
return (m);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 20, 4:22 PM (18 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15979647
Default Alt Text
D35302.id106549.diff (7 KB)
Attached To
Mode
D35302: unix/dgram: reduce mbuf chain traversals in send(2) and recv(2)
Attached
Detach File
Event Timeline
Log In to Comment