Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142758983
D35125.id105789.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D35125.id105789.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35125: sockets: remove the socket-on-stack hack from sorflush()
Attached
Detach File
Event Timeline
Log In to Comment