Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F159291254
D45443.id139311.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D45443.id139311.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
@@ -292,12 +292,15 @@
static int unp_connectat(int, struct socket *, struct sockaddr *,
struct thread *, bool);
static void unp_connect2(struct socket *so, struct socket *so2);
+typedef STAILQ_HEAD(udxg_mbq, mbuf) uxdg_mbq_t;
+static void unp_dispose_uxdg_mbq(uxdg_mbq_t *);
static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
static void unp_dispose(struct socket *so);
static void unp_shutdown(struct unpcb *);
static void unp_drop(struct unpcb *);
static void unp_gc(__unused void *, int);
-static void unp_scan(struct mbuf *, void (*)(struct filedescent **, int));
+static void unp_scan(bool is_dgram, 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 *,
@@ -1054,7 +1057,7 @@
UNP_PCB_UNLOCK(unp);
}
if (control != NULL && error != 0)
- unp_scan(control, unp_freerights);
+ unp_scan(false, control, unp_freerights);
release:
if (control != NULL)
@@ -1333,7 +1336,7 @@
SOCK_IO_SEND_UNLOCK(so);
out2:
if (c)
- unp_scan(c, unp_freerights);
+ unp_scan(true, c, unp_freerights);
out:
if (f)
m_freem(f);
@@ -1534,7 +1537,7 @@
error = unp_externalize(cm, controlp, flags);
if (error != 0) {
SOCK_IO_RECV_UNLOCK(so);
- unp_scan(m, unp_freerights);
+ unp_scan(true, m, unp_freerights);
m_freem(m);
return (error);
}
@@ -2099,20 +2102,24 @@
static void
unp_disconnect(struct unpcb *unp, struct unpcb *unp2)
{
+ uxdg_mbq_t mbq;
struct socket *so, *so2;
struct mbuf *m = NULL;
#ifdef INVARIANTS
struct unpcb *unptmp;
#endif
+ int sotype;
UNP_PCB_LOCK_ASSERT(unp);
UNP_PCB_LOCK_ASSERT(unp2);
KASSERT(unp->unp_conn == unp2,
("%s: unpcb %p is not connected to %p", __func__, unp, unp2));
+ STAILQ_INIT(&mbq);
unp->unp_conn = NULL;
so = unp->unp_socket;
so2 = unp2->unp_socket;
+ sotype = unp->unp_socket->so_type;
switch (unp->unp_socket->so_type) {
case SOCK_DGRAM:
/*
@@ -2136,7 +2143,7 @@
so2->so_rcv.uxdg_mbcnt += so->so_snd.uxdg_mbcnt;
} else {
m = STAILQ_FIRST(&so->so_snd.uxdg_mb);
- STAILQ_INIT(&so->so_snd.uxdg_mb);
+ STAILQ_CONCAT(&mbq, &so->so_snd.uxdg_mb);
so2->so_rcv.sb_acc -= so->so_snd.uxdg_cc;
so2->so_rcv.sb_ccc -= so->so_snd.uxdg_cc;
so2->so_rcv.sb_ctl -= so->so_snd.uxdg_ctl;
@@ -2189,8 +2196,11 @@
}
if (m != NULL) {
- unp_scan(m, unp_freerights);
- m_freem(m);
+ unp_scan(sotype == SOCK_DGRAM, m, unp_freerights);
+ if (sotype == SOCK_DGRAM)
+ unp_dispose_uxdg_mbq(&mbq);
+ else
+ m_freem(m);
}
}
@@ -3025,14 +3035,14 @@
SOCK_RECVBUF_LOCK(so);
switch (so->so_type) {
case SOCK_DGRAM:
- unp_scan(STAILQ_FIRST(&so->so_rcv.uxdg_mb), op);
- unp_scan(so->so_rcv.uxdg_peeked, op);
+ unp_scan(true, STAILQ_FIRST(&so->so_rcv.uxdg_mb), op);
+ unp_scan(true, so->so_rcv.uxdg_peeked, op);
TAILQ_FOREACH(sb, &so->so_rcv.uxdg_conns, uxdg_clist)
- unp_scan(STAILQ_FIRST(&sb->uxdg_mb), op);
+ unp_scan(true, STAILQ_FIRST(&sb->uxdg_mb), op);
break;
case SOCK_STREAM:
case SOCK_SEQPACKET:
- unp_scan(so->so_rcv.sb_mb, op);
+ unp_scan(false, so->so_rcv.sb_mb, op);
break;
}
SOCK_RECVBUF_UNLOCK(so);
@@ -3202,19 +3212,33 @@
free(unref, M_TEMP);
}
+static void
+unp_dispose_uxdg_mbq(uxdg_mbq_t *mbq)
+{
+ struct mbuf *m, *m2;
+
+ STAILQ_FOREACH_SAFE(m, mbq, m_stailqpkt, m2) {
+ STAILQ_REMOVE(mbq, m, mbuf, m_stailqpkt);
+ m_freem(m);
+ }
+}
+
/*
* Synchronize against unp_gc, which can trip over data as we are freeing it.
*/
static void
unp_dispose(struct socket *so)
{
+ uxdg_mbq_t mbq;
struct sockbuf *sb;
struct unpcb *unp;
struct mbuf *m;
int error __diagused;
+ int sotype;
MPASS(!SOLISTENING(so));
+ STAILQ_INIT(&mbq);
unp = sotounpcb(so);
UNP_LINK_WLOCK();
unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS;
@@ -3226,7 +3250,8 @@
error = SOCK_IO_RECV_LOCK(so, SBL_WAIT | SBL_NOINTR);
MPASS(!error);
SOCK_RECVBUF_LOCK(so);
- switch (so->so_type) {
+ sotype = so->so_type;
+ switch (sotype) {
case SOCK_DGRAM:
while ((sb = TAILQ_FIRST(&so->so_rcv.uxdg_conns)) != NULL) {
STAILQ_CONCAT(&so->so_rcv.uxdg_mb, &sb->uxdg_mb);
@@ -3241,7 +3266,7 @@
sb->uxdg_peeked = NULL;
}
m = STAILQ_FIRST(&sb->uxdg_mb);
- STAILQ_INIT(&sb->uxdg_mb);
+ STAILQ_CONCAT(&mbq, &sb->uxdg_mb);
/* XXX: our shortened sbrelease() */
(void)chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, 0,
RLIM_INFINITY);
@@ -3279,13 +3304,16 @@
SOCK_IO_RECV_UNLOCK(so);
if (m != NULL) {
- unp_scan(m, unp_freerights);
- m_freem(m);
+ unp_scan(sotype == SOCK_DGRAM, m, unp_freerights);
+ if (sotype == SOCK_DGRAM)
+ unp_dispose_uxdg_mbq(&mbq);
+ else
+ m_freem(m);
}
}
static void
-unp_scan(struct mbuf *m0, void (*op)(struct filedescent **, int))
+unp_scan(bool is_dgram, struct mbuf *m0, void (*op)(struct filedescent **, int))
{
struct mbuf *m;
struct cmsghdr *cm;
@@ -3324,7 +3352,7 @@
}
}
}
- m0 = m0->m_nextpkt;
+ m0 = is_dgram ? STAILQ_NEXT(m0, m_stailqpkt) : m0->m_nextpkt;
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jun 13, 11:42 AM (9 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33924312
Default Alt Text
D45443.id139311.diff (5 KB)
Attached To
Mode
D45443: unix/dgram: dispose mbufs on uxdg_mb queue
Attached
Detach File
Event Timeline
Log In to Comment