diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2022-08-22 10:37:28 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2022-08-22 10:37:28 +0000 |
commit | 7b63f372dc76ea2dad97ef9197710e5e653f6215 (patch) | |
tree | 8aaa6056ca17d7cee070c8d2a567344a6b12e463 /sys/netinet6 | |
parent | 43e1b15fa12ce7c8b1b58bdb5c3f9daacc185fbe (diff) |
Use rwlock per inpcb table to protect notify list. The notify
function may sleep, so holding a mutex is not possible. The same
list entry and rwlock is used for UDP multicast and raw IP delivery.
By adding a write lock, exclusive netlock is no longer necessary
for PCB notify and UDP and raw IP input.
OK mvs@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_pcb.c | 6 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 10 |
2 files changed, 11 insertions, 5 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 43a6e739e28..471a9614fea 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.119 2022/08/08 12:06:31 bluhm Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.120 2022/08/22 10:37:27 bluhm Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -387,8 +387,6 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst, u_int32_t flowinfo; u_int rdomain; - NET_ASSERT_LOCKED_EXCLUSIVE(); - if ((unsigned)cmd >= PRC_NCMDS) return; @@ -430,6 +428,7 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst, SIMPLEQ_INIT(&inpcblist); rdomain = rtable_l2(rtable); + rw_enter_write(&table->inpt_notify); mtx_enter(&table->inpt_mtx); TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) { if ((inp->inp_flags & INP_IPV6) == 0) @@ -513,6 +512,7 @@ in6_pcbnotify(struct inpcbtable *table, struct sockaddr_in6 *dst, (*notify)(inp, errno); in_pcbunref(inp); } + rw_exit_write(&table->inpt_notify); } struct inpcb * diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 3809f776044..29af83ad5e4 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.154 2022/08/22 08:08:46 mvs Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.155 2022/08/22 10:37:27 bluhm Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -172,8 +172,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) } } #endif - NET_ASSERT_LOCKED_EXCLUSIVE(); SIMPLEQ_INIT(&inpcblist); + rw_enter_write(&rawin6pcbtable.inpt_notify); mtx_enter(&rawin6pcbtable.inpt_mtx); TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) { if (in6p->inp_socket->so_state & SS_CANTRCVMORE) @@ -224,6 +224,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) struct counters_ref ref; uint64_t *counters; + rw_exit_write(&rawin6pcbtable.inpt_notify); + if (proto != IPPROTO_ICMPV6) { rip6stat_inc(rip6s_nosock); if (m->m_flags & M_MCAST) @@ -240,6 +242,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) counters = counters_enter(&ref, ip6counters); counters[ip6s_delivered]--; counters_leave(&ref, ip6counters); + + return IPPROTO_DONE; } while ((in6p = SIMPLEQ_FIRST(&inpcblist)) != NULL) { @@ -267,6 +271,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) } in_pcbunref(in6p); } + rw_exit_write(&rawin6pcbtable.inpt_notify); + return IPPROTO_DONE; } |