aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-09-10 21:20:39 +0000
committerMark Johnston <markj@FreeBSD.org>2021-09-10 21:20:39 +0000
commit74a68313b503940158a2e8e8f02626d7cdbdaff9 (patch)
treeaaf35e0335f54437b93b472edaefbb0d95c868f5
parent3b96abbab03327176b1e4ee02a6742bf9807dd75 (diff)
downloadsrc-74a68313b503940158a2e8e8f02626d7cdbdaff9.tar.gz
src-74a68313b503940158a2e8e8f02626d7cdbdaff9.zip
socket: Add macros to lock socket buffers using socket references
Since commit c67f3b8b78e50c6df7c057d6cf108e4d6b4312d0 the sockbuf mutexes belong to the containing socket. Sockbufs contain a pointer to a mutex, which by default is initialized to the corresponding mutexes in the socket. The SOCKBUF_LOCK() etc. macros operate on this pointer. However, the pointer is clobbered by listen(2) so it's not safe to use them unless one is sure that the socket is not a listening socket. This change introduces a new set of macros which lock socket buffers through the socket. This is a bit cheaper since it removes the pointer indirection, and allows one to safely lock socket buffers and then check for a listening socket. For MFC, these macros should be reimplemented in terms of the existing socket buffer layout. Reviewed by: tuexen, gallatin, jhb Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31900
-rw-r--r--sys/sys/sockbuf.h7
-rw-r--r--sys/sys/socketvar.h30
2 files changed, 33 insertions, 4 deletions
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index 3b345870bd5f..3fc9b10cd240 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -118,8 +118,11 @@ struct sockbuf {
#ifdef _KERNEL
/*
- * Per-socket buffer mutex used to protect most fields in the socket
- * buffer.
+ * Per-socket buffer mutex used to protect most fields in the socket buffer.
+ * These make use of the mutex pointer embedded in struct sockbuf, which
+ * currently just references mutexes in the containing socket. The
+ * SOCK_SENDBUF_LOCK() etc. macros can be used instead of or in combination with
+ * these locking macros.
*/
#define SOCKBUF_MTX(_sb) ((_sb)->sb_mtx)
#define SOCKBUF_LOCK_INIT(_sb, _name) \
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 69dd1706e366..57913f7bbd65 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -77,8 +77,8 @@ enum socket_qstate {
* Locking key to struct socket:
* (a) constant after allocation, no locking required.
* (b) locked by SOCK_LOCK(so).
- * (cr) locked by SOCKBUF_LOCK(&so->so_rcv).
- * (cs) locked by SOCKBUF_LOCK(&so->so_snd).
+ * (cr) locked by SOCK_RECVBUF_LOCK(so)/SOCKBUF_LOCK(&so->so_rcv).
+ * (cs) locked by SOCK_SENDBUF_LOCK(so)/SOCKBUF_LOCK(&so->so_snd).
* (e) locked by SOLISTEN_LOCK() of corresponding listening socket.
* (f) not locked since integer reads/writes are atomic.
* (g) used only as a sleep/wakeup address, no value.
@@ -256,6 +256,32 @@ struct socket {
} while (0)
/*
+ * Socket buffer locks. These manipulate the same mutexes as SOCKBUF_LOCK()
+ * and related macros.
+ */
+#define SOCK_RECVBUF_MTX(so) \
+ (&(so)->so_rcv_mtx)
+#define SOCK_RECVBUF_LOCK(so) \
+ mtx_lock(SOCK_RECVBUF_MTX(so))
+#define SOCK_RECVBUF_UNLOCK(so) \
+ mtx_unlock(SOCK_RECVBUF_MTX(so))
+#define SOCK_RECVBUF_LOCK_ASSERT(so) \
+ mtx_assert(SOCK_RECVBUF_MTX(so), MA_OWNED)
+#define SOCK_RECVBUF_UNLOCK_ASSERT(so) \
+ mtx_assert(SOCK_RECVBUF_MTX(so), MA_NOTOWNED)
+
+#define SOCK_SENDBUF_MTX(so) \
+ (&(so)->so_snd_mtx)
+#define SOCK_SENDBUF_LOCK(so) \
+ mtx_lock(SOCK_SENDBUF_MTX(so))
+#define SOCK_SENDBUF_UNLOCK(so) \
+ mtx_unlock(SOCK_SENDBUF_MTX(so))
+#define SOCK_SENDBUF_LOCK_ASSERT(so) \
+ mtx_assert(SOCK_SENDBUF_MTX(so), MA_OWNED)
+#define SOCK_SENDBUF_UNLOCK_ASSERT(so) \
+ mtx_assert(SOCK_SENDBUF_MTX(so), MA_NOTOWNED)
+
+/*
* Macros for sockets and socket buffering.
*/