Page MenuHomeFreeBSD

D35125.id105789.diff
No OneTemporary

D35125.id105789.diff

diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -2944,22 +2944,12 @@
void
sorflush(struct socket *so)
{
- struct socket aso;
struct protosw *pr;
int error;
VNET_SO_ASSERT(so);
/*
- * In order to avoid calling dom_dispose with the socket buffer mutex
- * held, we make a partial copy of the socket buffer and clear the
- * original. The new socket buffer copy won't have initialized locks so
- * we can only call routines that won't use or assert those locks.
- * Ideally calling socantrcvmore() would prevent data from being added
- * to the buffer, but currently it merely prevents buffered data from
- * being read by userspace. We make this effort to free buffered data
- * nonetheless.
- *
* Dislodge threads currently blocked in receive and wait to acquire
* a lock against other simultaneous readers before clearing the
* socket buffer. Don't let our acquire be interrupted by a signal
@@ -2974,28 +2964,15 @@
return;
}
- SOCK_RECVBUF_LOCK(so);
- bzero(&aso, sizeof(aso));
- aso.so_pcb = so->so_pcb;
- bcopy(&so->so_rcv.sb_startzero, &aso.so_rcv.sb_startzero,
- offsetof(struct sockbuf, sb_endzero) -
- offsetof(struct sockbuf, sb_startzero));
- bzero(&so->so_rcv.sb_startzero,
- offsetof(struct sockbuf, sb_endzero) -
- offsetof(struct sockbuf, sb_startzero));
- SOCK_RECVBUF_UNLOCK(so);
- SOCK_IO_RECV_UNLOCK(so);
-
- /*
- * Dispose of special rights and flush the copied socket. Don't call
- * any unsafe routines (that rely on locks being initialized) on aso.
- */
pr = so->so_proto;
if (pr->pr_flags & PR_RIGHTS) {
MPASS(pr->pr_domain->dom_dispose != NULL);
- (*pr->pr_domain->dom_dispose)(&aso);
+ (*pr->pr_domain->dom_dispose)(so);
+ } else {
+ sbrelease(&so->so_rcv, so);
+ SOCK_IO_RECV_UNLOCK(so);
}
- sbrelease_internal(&aso.so_rcv, so);
+
}
/*
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
@@ -2767,7 +2767,9 @@
static void
unp_dispose(struct socket *so)
{
+ struct sockbuf *sb = &so->so_rcv;
struct unpcb *unp;
+ struct mbuf *m;
MPASS(!SOLISTENING(so));
@@ -2775,7 +2777,21 @@
UNP_LINK_WLOCK();
unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS;
UNP_LINK_WUNLOCK();
- unp_dispose_mbuf(so->so_rcv.sb_mb);
+
+ /*
+ * 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(sb, so);
+ SOCK_RECVBUF_UNLOCK(so);
+ if (SOCK_IO_RECV_OWNED(so))
+ SOCK_IO_RECV_UNLOCK(so);
+
+ unp_dispose_mbuf(m);
}
static void
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -83,7 +83,6 @@
struct mtx *sb_mtx; /* sockbuf lock */
struct selinfo *sb_sel; /* process selecting read/write */
short sb_state; /* (a) socket state on sockbuf */
-#define sb_startzero sb_flags
short sb_flags; /* (a) flags, see above */
struct mbuf *sb_mb; /* (a) the mbuf chain */
struct mbuf *sb_mbtail; /* (a) the last mbuf in the chain */
@@ -108,7 +107,6 @@
struct mbuf *sb_mtlstail; /* (a) last mbuf in TLS chain */
int (*sb_upcall)(struct socket *, void *, int); /* (a) */
void *sb_upcallarg; /* (a) */
-#define sb_endzero sb_tls_seqno
uint64_t sb_tls_seqno; /* (a) TLS seqno */
struct ktls_session *sb_tls_info; /* (a + b) TLS state */
TAILQ_HEAD(, kaiocb) sb_aiojobq; /* (a) pending AIO ops */
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -301,10 +301,12 @@
soiolock((so), &(so)->so_snd_sx, (flags))
#define SOCK_IO_SEND_UNLOCK(so) \
soiounlock(&(so)->so_snd_sx)
+#define SOCK_IO_SEND_OWNED(so) sx_xlocked(&(so)->so_snd_sx)
#define SOCK_IO_RECV_LOCK(so, flags) \
soiolock((so), &(so)->so_rcv_sx, (flags))
#define SOCK_IO_RECV_UNLOCK(so) \
soiounlock(&(so)->so_rcv_sx)
+#define SOCK_IO_RECV_OWNED(so) sx_xlocked(&(so)->so_rcv_sx)
/*
* Do we need to notify the other side when I/O is possible?

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 24, 5:56 AM (9 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27894391
Default Alt Text
D35125.id105789.diff (4 KB)

Event Timeline