[RFC PATCH 21/39] sysctl: refresh device-dependent bounds per call

From: wen . yang

Date: Wed Oct 28 2026 - 12:42:34 EST


From: Wen Yang <wen.yang@xxxxxxxxx>

Refresh device-dependent limits before validating sysctl writes.

Suggested-by: Joel Granados <joel.granados@xxxxxxxxxx>
Signed-off-by: Wen Yang <wen.yang@xxxxxxxxx>
---
drivers/base/power/main.c | 21 +++++++++++++++------
drivers/gpu/drm/i915/i915_perf.c | 19 ++++++++++++++-----
2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 88a31e09e4f3..8346875a4fa2 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -543,7 +543,6 @@ MODULE_PARM_DESC(dpm_watchdog_enabled, "Enable DPM watchdog");
static unsigned int __read_mostly dpm_watchdog_timeout = CONFIG_DPM_WATCHDOG_TIMEOUT;
static unsigned int __read_mostly dpm_watchdog_warning_timeout =
CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
-static const unsigned int dpm_watchdog_timeout_max = CONFIG_DPM_WATCHDOG_TIMEOUT;

static int proc_dodpm_watchdog_timeout_secs(const struct ctl_table *table,
int write, void *buffer,
@@ -565,23 +564,33 @@ static int proc_dodpm_watchdog_timeout_secs(const struct ctl_table *table,
return 0;
}

+static int proc_dodpm_watchdog_warning_timeout_secs(const struct ctl_table *table,
+ int write, void *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ struct ctl_table tmp = *table;
+
+ tmp.max = READ_ONCE(dpm_watchdog_timeout);
+ return proc_douintvec_minmax(&tmp, write, buffer, lenp, ppos);
+}
+
static const struct ctl_table dpm_watchdog_sysctls[] = {
{
.procname = "dpm_watchdog_timeout_secs",
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dodpm_watchdog_timeout_secs,
- .extra1 = SYSCTL_ONE,
- .extra2 = (void *)&dpm_watchdog_timeout_max,
+ .min = 1,
+ .max = CONFIG_DPM_WATCHDOG_TIMEOUT,
},
{
.procname = "dpm_watchdog_warning_timeout_secs",
.data = &dpm_watchdog_warning_timeout,
.maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = proc_douintvec_minmax,
- .extra1 = SYSCTL_ONE,
- .extra2 = (void *)&dpm_watchdog_timeout,
+ .proc_handler = proc_dodpm_watchdog_warning_timeout_secs,
+ .min = 1,
+ .max = UINT_MAX,
},
};

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 19b82427aa41..2e758f2008db 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -4795,6 +4795,15 @@ int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
return ret;
}

+static int oa_max_sample_rate_handler(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct ctl_table tmp = *table;
+
+ tmp.max = (unsigned long)READ_ONCE(oa_sample_rate_hard_limit);
+ return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+}
+
static const struct ctl_table oa_table[] = {
{
.procname = "perf_stream_paranoid",
@@ -4802,17 +4811,17 @@ static const struct ctl_table oa_table[] = {
.maxlen = sizeof(i915_perf_stream_paranoid),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
- .extra1 = SYSCTL_ZERO,
- .extra2 = SYSCTL_ONE,
+ .min = 0,
+ .max = 1,
},
{
.procname = "oa_max_sample_rate",
.data = &i915_oa_max_sample_rate,
.maxlen = sizeof(i915_oa_max_sample_rate),
.mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = SYSCTL_ZERO,
- .extra2 = &oa_sample_rate_hard_limit,
+ .proc_handler = oa_max_sample_rate_handler,
+ .min = 0,
+ .max = INT_MAX,
},
};

--
2.25.1