diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-12-19 08:36:51 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-12-19 08:36:51 +0000 |
commit | 347b9bada49618963c84880ec8c3c23c96aa0017 (patch) | |
tree | d431218ec3017a484e7de695c002a79a0e68cc86 /sys/kern/uipc_socket2.c | |
parent | c22be17b5bebb223df391aa82dfc7704004aafa7 (diff) |
Introduce the NET_LOCK() a rwlock used to serialize accesses to the parts
of the network stack that are not yet ready to be executed in parallel or
where new sleeping points are not possible.
This first pass replace all the entry points leading to ip_output(). This
is done to not introduce new sleeping points when trying to acquire ART's
write lock, needed when a new L2 entry is created via the RT_RESOLVE.
Inputs from and ok bluhm@, ok dlg@
Diffstat (limited to 'sys/kern/uipc_socket2.c')
-rw-r--r-- | sys/kern/uipc_socket2.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 58aaaf6497c..8a66e1d9b4c 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.68 2016/11/15 11:57:02 bluhm Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.69 2016/12/19 08:36:49 mpi Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -53,6 +53,8 @@ u_long sb_max = SB_MAX; /* patchable */ extern struct pool mclpools[]; extern struct pool mbpool; +int sbsleep(struct sockbuf *, struct rwlock *); + /* * Procedures to manipulate state flags of socket * and do appropriate wakeups. Normal sequence from the @@ -145,7 +147,7 @@ sonewconn(struct socket *head, int connstatus) struct socket *so; int soqueue = connstatus ? 1 : 0; - splsoftassert(IPL_SOFTNET); + NET_ASSERT_LOCKED(); if (mclpools[0].pr_nout > mclpools[0].pr_hardlimit * 95 / 100) return (NULL); @@ -271,16 +273,29 @@ socantrcvmore(struct socket *so) int sbwait(struct sockbuf *sb) { - splsoftassert(IPL_SOFTNET); + NET_ASSERT_LOCKED(); sb->sb_flagsintr |= SB_WAIT; - return (tsleep(&sb->sb_cc, + return (rwsleep(&sb->sb_cc, &netlock, (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "netio", sb->sb_timeo)); } int -sblock(struct sockbuf *sb, int wait) +sbsleep(struct sockbuf *sb, struct rwlock *lock) +{ + int error, prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH; + + if (lock != NULL) + error = rwsleep(&sb->sb_flags, lock, prio, "netlck", 0); + else + error = tsleep(&sb->sb_flags, prio, "netlck", 0); + + return (error); +} + +int +sblock(struct sockbuf *sb, int wait, struct rwlock *lock) { int error; @@ -295,9 +310,7 @@ sblock(struct sockbuf *sb, int wait) while (sb->sb_flags & SB_LOCK) { sb->sb_flags |= SB_WANT; - error = tsleep(&sb->sb_flags, - (sb->sb_flags & SB_NOINTR) ? - PSOCK : PSOCK|PCATCH, "netlck", 0); + error = sbsleep(sb, lock); if (error) return (error); } @@ -325,7 +338,7 @@ sbunlock(struct sockbuf *sb) void sowakeup(struct socket *so, struct sockbuf *sb) { - splsoftassert(IPL_SOFTNET); + NET_ASSERT_LOCKED(); selwakeup(&sb->sb_sel); sb->sb_flagsintr &= ~SB_SEL; |