Download raw body.
sysctl: push locking down to HW_BATTERY
sysctl(2) is full of unnecessary pages wiring, and we want to decrease
this pressure.
Avoid locking and pages wiring in read-only and error paths. Keep
current `sysctl_lock' + kernel lock locking to serialize modification
path, but drop unnecessary pages wiring.
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.466
diff -u -p -r1.466 kern_sysctl.c
--- sys/kern/kern_sysctl.c 4 May 2025 13:42:07 -0000 1.466
+++ sys/kern/kern_sysctl.c 4 May 2025 17:53:23 -0000
@@ -825,7 +825,6 @@ hw_sysctl(int *name, u_int namelen, void
case HW_SENSORS:
case HW_SETPERF:
case HW_PERFPOLICY:
- case HW_BATTERY:
#endif /* !SMALL_KERNEL */
case HW_ALLOWPOWERDOWN:
case HW_UCOMNAMES:
@@ -874,6 +873,11 @@ hw_sysctl(int *name, u_int namelen, void
case HW_USERMEM64:
return (sysctl_rdquad(oldp, oldlenp, newp,
ptoa((psize_t)physmem - uvmexp.wired)));
+#ifndef SMALL_KERNEL
+ case HW_BATTERY:
+ return (sysctl_hwbattery(name + 1, namelen - 1, oldp, oldlenp,
+ newp, newlen));
+#endif
default:
return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name,
namelen, oldp, oldlenp, newp, newlen);
@@ -933,11 +937,6 @@ hw_sysctl_locked(int *name, u_int namele
case HW_SMT:
return (sysctl_hwsmt(oldp, oldlenp, newp, newlen));
#endif
-#ifndef SMALL_KERNEL
- case HW_BATTERY:
- return (sysctl_hwbattery(name + 1, namelen - 1, oldp, oldlenp,
- newp, newlen));
-#endif
default:
return (EOPNOTSUPP);
}
@@ -956,19 +955,25 @@ int (*hw_battery_setchargestop)(int);
int
sysctl_hwchargemode(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
- int mode = hw_battery_chargemode;
- int error;
+ int mode, error;
if (!hw_battery_setchargemode)
return EOPNOTSUPP;
+ mode = atomic_load_int(&hw_battery_chargemode);
error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
&mode, -1, 1);
if (error)
return error;
- if (newp != NULL)
+ if (newp != NULL) {
+ if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)))
+ return error;
+ KERNEL_LOCK();
error = hw_battery_setchargemode(mode);
+ KERNEL_UNLOCK();
+ rw_exit(&sysctl_lock);
+ }
return error;
}
@@ -976,19 +981,25 @@ sysctl_hwchargemode(void *oldp, size_t *
int
sysctl_hwchargestart(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
- int start = hw_battery_chargestart;
- int error;
+ int start, error;
if (!hw_battery_setchargestart)
return EOPNOTSUPP;
+ start = atomic_load_int(&hw_battery_chargestart);
error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
&start, 0, 100);
if (error)
return error;
- if (newp != NULL)
+ if (newp != NULL) {
+ if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)))
+ return error;
+ KERNEL_LOCK();
error = hw_battery_setchargestart(start);
+ KERNEL_UNLOCK();
+ rw_exit(&sysctl_lock);
+ }
return error;
}
@@ -996,19 +1007,25 @@ sysctl_hwchargestart(void *oldp, size_t
int
sysctl_hwchargestop(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
{
- int stop = hw_battery_chargestop;
- int error;
+ int stop, error;
if (!hw_battery_setchargestop)
return EOPNOTSUPP;
+ stop = atomic_load_int(&hw_battery_chargestop);
error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
&stop, 0, 100);
if (error)
return error;
- if (newp != NULL)
+ if (newp != NULL) {
+ if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)))
+ return error;
+ KERNEL_LOCK();
error = hw_battery_setchargestop(stop);
+ KERNEL_UNLOCK();
+ rw_exit(&sysctl_lock);
+ }
return error;
}
sysctl: push locking down to HW_BATTERY