summaryrefslogtreecommitdiff
path: root/sys/kern/uipc_socket2.c
diff options
context:
space:
mode:
authormvs <mvs@cvs.openbsd.org>2021-05-01 16:13:14 +0000
committermvs <mvs@cvs.openbsd.org>2021-05-01 16:13:14 +0000
commit93bb6fd7698cf751377d0213f6abf5cef1277386 (patch)
treeefc9f1a02d3a275e5c204b6f83f978cfb9e9ae66 /sys/kern/uipc_socket2.c
parent58b3d2ba77817cf3ac54cf921bf87b95844589c4 (diff)
Implement per-socket `so_lock' rwlock(9) and use it to protect routing
(PF_ROUTE) sockets. This can be done because we have no cases where one thread should lock two sockets simultaneously. Against the previous version rtm_senddesync_timer() execution was moved to process context. Also this time `so_lock' used for routing sockets only but in the future it will be used to other socket types too. tested by claudio@ ok claudio@ bluhm@
Diffstat (limited to 'sys/kern/uipc_socket2.c')
-rw-r--r--sys/kern/uipc_socket2.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 940da149093..851a0dfa16d 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket2.c,v 1.108 2021/04/26 08:21:35 claudio Exp $ */
+/* $OpenBSD: uipc_socket2.c,v 1.109 2021/05/01 16:13:13 mvs Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
@@ -162,6 +162,7 @@ sonewconn(struct socket *head, int connstatus)
so = pool_get(&socket_pool, PR_NOWAIT|PR_ZERO);
if (so == NULL)
return (NULL);
+ rw_init(&so->so_lock, "solock");
so->so_type = head->so_type;
so->so_options = head->so_options &~ SO_ACCEPTCONN;
so->so_linger = head->so_linger;
@@ -287,6 +288,8 @@ solock(struct socket *so)
rw_enter_write(&unp_lock);
break;
case PF_ROUTE:
+ rw_enter_write(&so->so_lock);
+ break;
case PF_KEY:
default:
KERNEL_LOCK();
@@ -313,6 +316,8 @@ sounlock(struct socket *so, int s)
rw_exit_write(&unp_lock);
break;
case PF_ROUTE:
+ rw_exit_write(&so->so_lock);
+ break;
case PF_KEY:
default:
KERNEL_UNLOCK();
@@ -332,6 +337,8 @@ soassertlocked(struct socket *so)
rw_assert_wrlock(&unp_lock);
break;
case PF_ROUTE:
+ rw_assert_wrlock(&so->so_lock);
+ break;
case PF_KEY:
default:
KERNEL_ASSERT_LOCKED();
@@ -354,6 +361,8 @@ sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg,
ret = rwsleep_nsec(ident, &unp_lock, prio, wmesg, nsecs);
break;
case PF_ROUTE:
+ ret = rwsleep_nsec(ident, &so->so_lock, prio, wmesg, nsecs);
+ break;
case PF_KEY:
default:
ret = tsleep_nsec(ident, prio, wmesg, nsecs);