Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109121774
D35300.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D35300.diff
View Options
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -434,7 +434,8 @@
{
.pr_type = SOCK_DGRAM,
.pr_domain = &localdomain,
- .pr_flags = PR_ATOMIC|PR_ADDR|PR_RIGHTS|PR_CAPATTACH,
+ .pr_flags = PR_ATOMIC | PR_ADDR |PR_RIGHTS | PR_CAPATTACH |
+ PR_SOCKBUF,
.pr_ctloutput = &uipc_ctloutput,
.pr_usrreqs = &uipc_usrreqs_dgram
},
@@ -528,6 +529,7 @@
break;
case SOCK_DGRAM:
+ STAILQ_INIT(&so->so_rcv.uxdg_mb);
sendspace = unpdg_maxdgram;
recvspace = unpdg_recvspace;
break;
@@ -850,6 +852,14 @@
}
if (local_unp_rights)
taskqueue_enqueue_timeout(taskqueue_thread, &unp_gc_task, -1);
+
+ switch (so->so_type) {
+ case SOCK_DGRAM:
+ /*
+ * Everything should have been unlinked/freed by unp_dispose().
+ */
+ MPASS(STAILQ_EMPTY(&so->so_rcv.uxdg_mb));
+ }
}
static int
@@ -1130,8 +1140,9 @@
const struct sockaddr *from;
struct socket *so2;
struct sockbuf *sb;
- struct mbuf *f, *clast;
- int cc, error;
+ struct mbuf *f;
+ u_int cc;
+ int error;
MPASS((uio != NULL && m == NULL) || (m != NULL && uio == NULL));
@@ -1193,7 +1204,7 @@
error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(flags));
if (error)
goto out2;
- SOCKBUF_LOCK(&so->so_snd);
+ SOCK_SENDBUF_LOCK(so);
if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
SOCK_SENDBUF_UNLOCK(so);
error = EPIPE;
@@ -1202,15 +1213,15 @@
if (so->so_error != 0) {
error = so->so_error;
so->so_error = 0;
- SOCKBUF_UNLOCK(&so->so_snd);
+ SOCK_SENDBUF_UNLOCK(so);
goto out3;
}
if (((so->so_state & SS_ISCONNECTED) == 0) && addr == NULL) {
- SOCKBUF_UNLOCK(&so->so_snd);
+ SOCK_SENDBUF_UNLOCK(so);
error = EDESTADDRREQ;
goto out3;
}
- SOCKBUF_UNLOCK(&so->so_snd);
+ SOCK_SENDBUF_UNLOCK(so);
if (addr != NULL) {
if ((error = unp_connectat(AT_FDCWD, so, addr, td, true)))
@@ -1238,34 +1249,35 @@
MPASS(from->sa_len <= MLEN);
bcopy(from, mtod(f, void *), from->sa_len);
cc = f->m_len + m->m_pkthdr.len;
- if (c != NULL)
+
+ /* Concatenate: from -> control -> data. */
+ if (c != NULL) {
+ struct mbuf *clast;
+
cc += m_length(c, &clast);
+ f->m_next = c;
+ clast->m_next = m;
+ c = NULL;
+ } else
+ f->m_next = m;
+ m = NULL;
+
so2 = unp2->unp_socket;
sb = &so2->so_rcv;
- SOCKBUF_LOCK(sb);
+ SOCK_RECVBUF_LOCK(so2);
if (cc <= sbspace(sb)) {
- /* Concatenate: from -> control -> data. */
- if (c != NULL) {
- f->m_next = c;
- clast->m_next = m;
- } else
- f->m_next = m;
- m = f;
- /* Reusing f as iterator. */
- for (f = m; f->m_next != NULL; f = f->m_next)
- sballoc(sb, f);
- sballoc(sb, f);
- sb->sb_mbtail = f;
- /* SBLINKRECORD */
- if (sb->sb_lastrecord != NULL)
- sb->sb_lastrecord->m_nextpkt = m;
- else
- sb->sb_mb = m;
- sb->sb_lastrecord = m;
- SBLASTMBUFCHK(sb);
- SBLASTRECORDCHK(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) {
+ if (f->m_type != MT_DATA)
+ sb->sb_ctl += f->m_len;
+ sb->sb_mbcnt += MSIZE;
+ if (f->m_flags & M_EXT)
+ sb->sb_mbcnt += f->m_ext.ext_size;
+ }
+ sb->sb_acc += cc;
+ sb->sb_ccc += cc;
sorwakeup_locked(so2);
- f = m = c = NULL;
} else {
soroverflow_locked(so2);
error = (so->so_state & SS_NBIO) ? EAGAIN : ENOBUFS;
@@ -1285,7 +1297,7 @@
unp_scan(c, unp_freerights);
out:
if (f)
- m_free(f);
+ m_freem(f);
if (c)
m_freem(c);
if (m)
@@ -1305,18 +1317,15 @@
ssize_t len;
int error;
- SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCK_RECVBUF_UNLOCK(so);
- m = so->so_rcv.sb_mb;
+ m = STAILQ_FIRST(&so->so_rcv.uxdg_mb);
KASSERT(m->m_type == MT_SONAME, ("m->m_type == %d", m->m_type));
if (psa != NULL)
*psa = sodupsockaddr(mtod(m, struct sockaddr *), M_WAITOK);
- if ((m = m->m_next) == NULL) {
- /* XXXRW: Can this happen? */
- SOCK_IO_RECV_UNLOCK(so);
- return (0);
- }
+ m = m->m_next;
+ KASSERT(m, ("%s: no data or control after soname", __func__));
/*
* With MSG_PEEK the control isn't executed, just copied.
@@ -1381,82 +1390,60 @@
* Loop blocking while waiting for a datagram.
*/
SOCK_RECVBUF_LOCK(so);
- while ((m = so->so_rcv.sb_mb) == NULL) {
+ while ((m = STAILQ_FIRST(&so->so_rcv.uxdg_mb)) == NULL) {
KASSERT(sbavail(&so->so_rcv) == 0,
("soreceive_dgram: sb_mb NULL but sbavail %u",
sbavail(&so->so_rcv)));
if (so->so_error) {
error = so->so_error;
so->so_error = 0;
- SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCK_RECVBUF_UNLOCK(so);
SOCK_IO_RECV_UNLOCK(so);
return (error);
}
if (so->so_rcv.sb_state & SBS_CANTRCVMORE ||
uio->uio_resid == 0) {
- SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCK_RECVBUF_UNLOCK(so);
SOCK_IO_RECV_UNLOCK(so);
return (0);
}
if (nonblock) {
- SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCK_RECVBUF_UNLOCK(so);
SOCK_IO_RECV_UNLOCK(so);
return (EWOULDBLOCK);
}
- SBLASTRECORDCHK(&so->so_rcv);
- SBLASTMBUFCHK(&so->so_rcv);
error = sbwait(so, SO_RCV);
if (error) {
- SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCK_RECVBUF_UNLOCK(so);
SOCK_IO_RECV_UNLOCK(so);
return (error);
}
}
- SOCKBUF_LOCK_ASSERT(&so->so_rcv);
+ SOCK_RECVBUF_LOCK_ASSERT(so);
if (uio->uio_td)
uio->uio_td->td_ru.ru_msgrcv++;
- SBLASTRECORDCHK(&so->so_rcv);
- SBLASTMBUFCHK(&so->so_rcv);
if (__predict_false(flags & MSG_PEEK))
return (uipc_peek_dgram(so, psa, uio, controlp, flagsp));
- /*
- * Advance the sb_mb, update sb_lastrecord if necessary.
- */
- so->so_rcv.sb_mb = m->m_nextpkt;
- if (so->so_rcv.sb_mb == NULL) {
- KASSERT(so->so_rcv.sb_lastrecord == m,
- ("%s: lastrecord != m", __func__));
- so->so_rcv.sb_lastrecord = NULL;
- so->so_rcv.sb_mbtail = NULL;
- } else if (so->so_rcv.sb_mb->m_nextpkt == NULL)
- so->so_rcv.sb_lastrecord = so->so_rcv.sb_mb;
-
- /*
- * Walk 'm's chain and free that many bytes from the socket buffer.
- */
- for (m2 = m; m2 != NULL; m2 = m2->m_next)
- sbfree(&so->so_rcv, m2);
-
- /*
- * Do a few last checks before we let go of the lock.
- */
- SBLASTRECORDCHK(&so->so_rcv);
- SBLASTMBUFCHK(&so->so_rcv);
- SOCKBUF_UNLOCK(&so->so_rcv);
+ STAILQ_REMOVE_HEAD(&so->so_rcv.uxdg_mb, m_stailqpkt);
+ for (m2 = m; m2 != NULL; m2 = m2->m_next) {
+ if (m2->m_type != MT_DATA)
+ so->so_rcv.sb_ctl -= m2->m_len;
+ so->so_rcv.sb_acc -= m2->m_len;
+ 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;
+ }
+ 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);
-
- if (m == NULL) {
- /* XXXRW: Can this happen? */
- SOCK_IO_RECV_UNLOCK(so);
- return (0);
- }
+ KASSERT(m, ("%s: no data or control after soname", __func__));
/*
* Packet to copyout() is now in 'm' and it is disconnected from the
@@ -2915,6 +2902,28 @@
}
}
+static void
+unp_scan_socket(struct socket *so, void (*op)(struct filedescent **, int))
+{
+
+ SOCK_LOCK_ASSERT(so);
+
+ if (sotounpcb(so)->unp_gcflag & UNPGC_IGNORE_RIGHTS)
+ return;
+
+ SOCK_RECVBUF_LOCK(so);
+ switch (so->so_type) {
+ case SOCK_DGRAM:
+ unp_scan(STAILQ_FIRST(&so->so_rcv.uxdg_mb), op);
+ break;
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ unp_scan(so->so_rcv.sb_mb, op);
+ break;
+ }
+ SOCK_RECVBUF_UNLOCK(so);
+}
+
static void
unp_gc_scan(struct unpcb *unp, void (*op)(struct filedescent **, int))
{
@@ -2926,22 +2935,13 @@
/*
* Mark all sockets in our accept queue.
*/
- TAILQ_FOREACH(soa, &so->sol_comp, so_list) {
- if (sotounpcb(soa)->unp_gcflag & UNPGC_IGNORE_RIGHTS)
- continue;
- SOCKBUF_LOCK(&soa->so_rcv);
- unp_scan(soa->so_rcv.sb_mb, op);
- SOCKBUF_UNLOCK(&soa->so_rcv);
- }
+ TAILQ_FOREACH(soa, &so->sol_comp, so_list)
+ unp_scan_socket(soa, op);
} else {
/*
* Mark all sockets we reference with RIGHTS.
*/
- if ((unp->unp_gcflag & UNPGC_IGNORE_RIGHTS) == 0) {
- SOCKBUF_LOCK(&so->so_rcv);
- unp_scan(so->so_rcv.sb_mb, op);
- SOCKBUF_UNLOCK(&so->so_rcv);
- }
+ unp_scan_socket(so, op);
}
SOCK_UNLOCK(so);
}
@@ -3108,11 +3108,23 @@
* Grab our special mbufs before calling sbrelease().
*/
SOCK_RECVBUF_LOCK(so);
- m = sbcut_locked(sb, sb->sb_ccc);
- KASSERT(sb->sb_ccc == 0 && sb->sb_mb == 0 && sb->sb_mbcnt == 0,
- ("%s: ccc %u mb %p mbcnt %u", __func__,
- sb->sb_ccc, (void *)sb->sb_mb, sb->sb_mbcnt));
- sbrelease_locked(so, SO_RCV);
+ switch (so->so_type) {
+ case SOCK_DGRAM:
+ m = STAILQ_FIRST(&sb->uxdg_mb);
+ STAILQ_INIT(&sb->uxdg_mb);
+ /* XXX: our shortened sbrelease() */
+ (void)chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, 0,
+ RLIM_INFINITY);
+ break;
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ m = sbcut_locked(sb, sb->sb_ccc);
+ KASSERT(sb->sb_ccc == 0 && sb->sb_mb == 0 && sb->sb_mbcnt == 0,
+ ("%s: ccc %u mb %p mbcnt %u", __func__,
+ sb->sb_ccc, (void *)sb->sb_mb, sb->sb_mbcnt));
+ sbrelease_locked(so, SO_RCV);
+ break;
+ }
SOCK_RECVBUF_UNLOCK(so);
if (SOCK_IO_RECV_OWNED(so))
SOCK_IO_RECV_UNLOCK(so);
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -133,6 +133,14 @@
uint64_t sb_tls_seqno; /* TLS seqno */
struct ktls_session *sb_tls_info; /* TLS state */
};
+ /*
+ * PF_UNIX/SOCK_DGRAM
+ *
+ * Local protocol, thus any socket buffer is a receive buffer.
+ */
+ struct {
+ STAILQ_HEAD(, mbuf) uxdg_mb;
+ };
};
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 2, 2:06 AM (21 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16394114
Default Alt Text
D35300.diff (9 KB)
Attached To
Mode
D35300: unix/dgram: use minimal possible socket buffer for PF_UNIX/SOCK_DGRAM
Attached
Detach File
Event Timeline
Log In to Comment