Download raw body.
Switch AF_KEY sockets to the new locking scheme
The simplest case. Nothing to change in sockets layer, only set
SB_MTXLOCK on buffers. This diff doesn't conflict with "Turn sblock()
to `sb_lock' ..." [1] diff.
1. https://marc.info/?t=171478067200001&r=1&w=2
Not related to this diff, but pkpcb uses solock() only to protect
`kcb_flags' and `kcb_reg'. Protected paths are pretty small and have no
context switch, so per-pkpcb mutex(9) could be used instead of solock().
This removes context switch from `kcb_list' walkthroughs and this SRP
could be converted to SMR list.
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
diff -u -p -r1.333 uipc_socket.c
--- sys/kern/uipc_socket.c 3 May 2024 17:43:09 -0000 1.333
+++ sys/kern/uipc_socket.c 8 May 2024 10:43:14 -0000
@@ -166,6 +166,7 @@ soalloc(const struct protosw *prp, int w
break;
}
break;
+ case AF_KEY:
case AF_UNIX:
so->so_snd.sb_flags |= SB_MTXLOCK;
so->so_rcv.sb_flags |= SB_MTXLOCK;
Index: sys/net/pfkeyv2.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.c,v
diff -u -p -r1.260 pfkeyv2.c
--- sys/net/pfkeyv2.c 11 Jan 2024 14:15:11 -0000 1.260
+++ sys/net/pfkeyv2.c 8 May 2024 10:43:14 -0000
@@ -443,8 +443,7 @@ pfkey_sendup(struct pkpcb *kp, struct mb
{
struct socket *so = kp->kcb_socket;
struct mbuf *m;
-
- soassertlocked(so);
+ int ret;
if (more) {
if (!(m = m_dup_pkt(m0, 0, M_DONTWAIT)))
@@ -452,7 +451,11 @@ pfkey_sendup(struct pkpcb *kp, struct mb
} else
m = m0;
- if (!sbappendaddr(so, &so->so_rcv, &pfkey_addr, m, NULL)) {
+ mtx_enter(&so->so_rcv.sb_mtx);
+ ret = sbappendaddr(so, &so->so_rcv, &pfkey_addr, m, NULL);
+ mtx_leave(&so->so_rcv.sb_mtx);
+
+ if (ret == 0) {
m_freem(m);
return (ENOBUFS);
}
@@ -515,9 +518,7 @@ pfkeyv2_sendmessage(void **headers, int
* Send message to the specified socket, plus all
* promiscuous listeners.
*/
- solock(so);
pfkey_sendup(sotokeycb(so), packet, 0);
- sounlock(so);
/*
* Promiscuous messages contain the original message
@@ -544,10 +545,8 @@ pfkeyv2_sendmessage(void **headers, int
if (kp->kcb_socket == so || kp->kcb_rdomain != rdomain)
continue;
- keylock(kp);
if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC)
pfkey_sendup(kp, packet, 1);
- keyunlock(kp);
}
SRPL_LEAVE(&sr);
m_freem(packet);
@@ -562,18 +561,18 @@ pfkeyv2_sendmessage(void **headers, int
if (kp->kcb_rdomain != rdomain)
continue;
- keylock(kp);
if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED) {
if (!satype) {
/* Just send to everyone registered */
pfkey_sendup(kp, packet, 1);
} else {
+ keylock(kp);
/* Check for specified satype */
if ((1 << satype) & kp->kcb_reg)
pfkey_sendup(kp, packet, 1);
+ keyunlock(kp);
}
}
- keyunlock(kp);
}
SRPL_LEAVE(&sr);
/* Free last/original copy of the packet */
@@ -595,14 +594,14 @@ pfkeyv2_sendmessage(void **headers, int
/* Send to all registered promiscuous listeners */
SRPL_FOREACH(kp, &sr, &pkptable.pkp_list, kcb_list) {
+ int flags = READ_ONCE(kp->kcb_flags);
+
if (kp->kcb_rdomain != rdomain)
continue;
- keylock(kp);
- if ((kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
- !(kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED))
+ if ((flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
+ !(flags & PFKEYV2_SOCKETFLAGS_REGISTERED))
pfkey_sendup(kp, packet, 1);
- keyunlock(kp);
}
SRPL_LEAVE(&sr);
m_freem(packet);
@@ -614,9 +613,7 @@ pfkeyv2_sendmessage(void **headers, int
if (kp->kcb_rdomain != rdomain)
continue;
- keylock(kp);
pfkey_sendup(kp, packet, 1);
- keyunlock(kp);
}
SRPL_LEAVE(&sr);
m_freem(packet);
@@ -1196,10 +1193,8 @@ pfkeyv2_dosend(struct socket *so, void *
if (bkp->kcb_rdomain != kp->kcb_rdomain)
continue;
- keylock(bkp);
if (bkp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC)
pfkey_sendup(bkp, packet, 1);
- keyunlock(bkp);
}
SRPL_LEAVE(&sr);
@@ -2049,14 +2044,13 @@ pfkeyv2_dosend(struct socket *so, void *
goto ret;
SRPL_FOREACH(bkp, &sr, &pkptable.pkp_list, kcb_list) {
- if (bkp == kp || bkp->kcb_rdomain != kp->kcb_rdomain)
+ if (bkp == kp ||
+ bkp->kcb_rdomain != kp->kcb_rdomain)
continue;
if (!smsg->sadb_msg_seq ||
(smsg->sadb_msg_seq == kp->kcb_pid)) {
- keylock(bkp);
pfkey_sendup(bkp, packet, 1);
- keyunlock(bkp);
}
}
SRPL_LEAVE(&sr);
Switch AF_KEY sockets to the new locking scheme