> On 18 May 2023, at 01:14, Alexander Bluhm <alexander.bl...@gmx.net> wrote: > > On Wed, May 17, 2023 at 12:46:02PM +0300, Vitaliy Makkoveev wrote: >> Introduce `ip6_soiikey_lock' rwlock(9) to protect `ip6_soiikey'. It >> accessed only by ip6_sysctl_soiikey() and ip6_sysctl() is the only >> ip6_sysctl_soiikey() caller so context switch is allowed here. Also >> remove unused `oldkey' from ip6_sysctl_soiikey(). > > rwlock or mutex? As sysctl mlocks userland memory, copyin/copyout > cannot sleep here. So it should be safe to use a mutex.
It is locked because context switch is strictly unwanted when you do copyin/copyout within foreach loops of kernel lock protected lists like ps_list. Really this lock is the kind of a hack. But since rwlocks already introduced context switch to sysctl() paths, we use sysctl_lock rwlock to prevent many processes to simultaneously lock large amount of memory. This is another hack in this layer. Guess, both of them will gone in the future, so copyin/copyout will sleep. So rwlock is better. > > And why is this ip6_soiikey in the kernel anyway? I guess it is > from a time when address configuration was done in the kernel. > Could slaacd(8) just read /etc/soii.key? It could, but this should be implemented in slaacd first. And this work is not related to (*pr_sysctl)() unlocking. > >> For IPV6CTL_MRTSTATS, IPV6CTL_MRTMIF and IPV6CTL_MRTMFC cases netlock >> could be relaxed to share netlock, but with separate diffs. >> >> ok? >> >> Index: sys/netinet6/in6_proto.c >> =================================================================== >> RCS file: /cvs/src/sys/netinet6/in6_proto.c,v >> retrieving revision 1.112 >> diff -u -p -r1.112 in6_proto.c >> --- sys/netinet6/in6_proto.c 23 Nov 2022 14:48:28 -0000 1.112 >> +++ sys/netinet6/in6_proto.c 17 May 2023 09:37:05 -0000 >> @@ -128,6 +128,7 @@ const struct protosw inet6sw[] = { >> { >> .pr_domain = &inet6domain, >> .pr_protocol = IPPROTO_IPV6, >> + .pr_flags = PR_MPSYSCTL, >> .pr_init = ip6_init, >> .pr_slowtimo = frag6_slowtimo, >> .pr_sysctl = ip6_sysctl >> Index: sys/netinet6/ip6_input.c >> =================================================================== >> RCS file: /cvs/src/sys/netinet6/ip6_input.c,v >> retrieving revision 1.254 >> diff -u -p -r1.254 ip6_input.c >> --- sys/netinet6/ip6_input.c 21 Aug 2022 14:15:55 -0000 1.254 >> +++ sys/netinet6/ip6_input.c 17 May 2023 09:37:05 -0000 >> @@ -118,6 +118,7 @@ struct niqueue ip6intrq = NIQUEUE_INITIA >> struct cpumem *ip6counters; >> >> uint8_t ip6_soiikey[IP6_SOIIKEY_LEN]; >> +struct rwlock ip6_soiikey_lock = RWLOCK_INITIALIZER("soiikeylk"); >> >> int ip6_ours(struct mbuf **, int *, int, int); >> int ip6_check_rh0hdr(struct mbuf *, int *); >> @@ -1477,17 +1478,16 @@ ip6_sysctl_ip6stat(void *oldp, size_t *o >> int >> ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen) >> { >> - uint8_t oldkey[IP6_SOIIKEY_LEN]; >> int error; >> >> error = suser(curproc); >> if (error != 0) >> return (error); >> >> - memcpy(oldkey, ip6_soiikey, sizeof(oldkey)); >> - >> + rw_enter_write(&ip6_soiikey_lock); >> error = sysctl_struct(oldp, oldlenp, newp, newlen, ip6_soiikey, >> sizeof(ip6_soiikey)); >> + rw_exit_write(&ip6_soiikey_lock); >> >> return (error); >> }