On Tue, May 16, 2023 at 01:55:32PM +0300, Vitaliy Makkoveev wrote: > Let's start to unlock (*pr_sysctl)() handlers. We have many of them, so > introduce temporary PR_MPSAFE flag to mark MP safe instead of pushing > kernel lock within handlers.
I had the same idea and flag name for pr_input functions in a pending diff. Could you name your flag PR_MPSYSCTL? Then it is clear what it is used for. > Unlock ip_sysctl(). Still take kernel lock within IPCTL_MRTSTATS case. > ok? OK bluhm@ > This is not related to (*pr_sysctl)() unlocking, but if there is no > objections, I want to replace tabs by space after #define in PR_* flags > definitions. Yes please. I also prefer #defineSPACE over #defineTAB as diff formating does not jump around. Could you also use 0x0080 when doing this. Flags is a short and we could need more flags for fine grained unlocking. I saw one issue in sysctl_niq(). Another CPU could write mq_maxlen and our logic is inconsistent. Below is a fix with read once. Each CPU detects its own change, last write wins. Or should we protect everything with mq_mtx? Then sysctl 123 -> 345 would have the correct old value on both CPUs. bluhm Index: kern/uipc_mbuf.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.285 diff -u -p -r1.285 uipc_mbuf.c --- kern/uipc_mbuf.c 5 May 2023 01:19:51 -0000 1.285 +++ kern/uipc_mbuf.c 16 May 2023 15:05:52 -0000 @@ -1788,7 +1788,7 @@ int sysctl_mq(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct mbuf_queue *mq) { - unsigned int maxlen; + unsigned int oldmax, newmax; int error; /* All sysctl names at this level are terminal. */ @@ -1799,10 +1799,10 @@ sysctl_mq(int *name, u_int namelen, void case IFQCTL_LEN: return (sysctl_rdint(oldp, oldlenp, newp, mq_len(mq))); case IFQCTL_MAXLEN: - maxlen = mq->mq_maxlen; - error = sysctl_int(oldp, oldlenp, newp, newlen, &maxlen); - if (!error && maxlen != mq->mq_maxlen) - mq_set_maxlen(mq, maxlen); + oldmax = newmax = READ_ONCE(mq->mq_maxlen); + error = sysctl_int(oldp, oldlenp, newp, newlen, &newmax); + if (!error && oldmax != newmax) + mq_set_maxlen(mq, newmax); return (error); case IFQCTL_DROPS: return (sysctl_rdint(oldp, oldlenp, newp, mq_drops(mq)));