]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sysctl: Replace unidirectional INT converter macros with functions
authorJoel Granados <joel.granados@kernel.org>
Wed, 3 Dec 2025 21:42:32 +0000 (22:42 +0100)
committerJoel Granados <joel.granados@kernel.org>
Tue, 6 Jan 2026 10:26:42 +0000 (11:26 +0100)
Replace SYSCTL_USER_TO_KERN_INT_CONV and SYSCTL_KERN_TO_USER_INT_CONV
macros with function implementing the same logic.This makes debugging
easier and aligns with the functions preference described in
coding-style.rst. Update all jiffies converters to use explicit function
implementations instead of macro-generated versions.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
include/linux/sysctl.h
kernel/sysctl.c
kernel/time/jiffies.c

index d712992789f0f2f3fe4cec10fb14907b7fd61a7e..655fb85ec29278a3a268e363243c7f318bf0e75e 100644 (file)
@@ -74,40 +74,6 @@ extern const int sysctl_vals[];
 #define SYSCTL_KERN_TO_USER(dir) (!dir)
 
 #ifdef CONFIG_PROC_SYSCTL
-#define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op)           \
-int sysctl_user_to_kern_int_conv##name(const bool *negp,       \
-                                      const unsigned long *u_ptr,\
-                                      int *k_ptr)              \
-{                                                              \
-       unsigned long u = u_ptr_op(*u_ptr);                     \
-       if (*negp) {                                            \
-               if (u > (unsigned long) INT_MAX + 1)            \
-                       return -EINVAL;                         \
-               WRITE_ONCE(*k_ptr, -u);                         \
-       } else {                                                \
-               if (u > (unsigned long) INT_MAX)                \
-                       return -EINVAL;                         \
-               WRITE_ONCE(*k_ptr, u);                          \
-       }                                                       \
-       return 0;                                               \
-}
-
-#define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op)           \
-int sysctl_kern_to_user_int_conv##name(bool *negp,             \
-                                      unsigned long *u_ptr,    \
-                                      const int *k_ptr)        \
-{                                                              \
-       int val = READ_ONCE(*k_ptr);                            \
-       if (val < 0) {                                          \
-               *negp = true;                                   \
-               *u_ptr = -k_ptr_op((unsigned long)val);         \
-       } else {                                                \
-               *negp = false;                                  \
-               *u_ptr = k_ptr_op((unsigned long)val);          \
-       }                                                       \
-       return 0;                                               \
-}
-
 /**
  * To range check on a converted value, use a temp k_ptr
  * When checking range, value should be within (tbl->extra1, tbl->extra2)
@@ -135,22 +101,8 @@ int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\
                return user_to_kern(negp, u_ptr, k_ptr);                \
        return 0;                                                       \
 }
-#else // CONFIG_PROC_SYSCTL
-#define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op)           \
-int sysctl_user_to_kern_int_conv##name(const bool *negp,       \
-                                      const unsigned long *u_ptr,\
-                                      int *k_ptr)              \
-{                                                              \
-       return -ENOSYS;                                         \
-}
 
-#define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op)           \
-int sysctl_kern_to_user_int_conv##name(bool *negp,             \
-                                      unsigned long *u_ptr,    \
-                                      const int *k_ptr)        \
-{                                                              \
-       return -ENOSYS;                                         \
-}
+#else // CONFIG_PROC_SYSCTL
 
 #define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user,       \
                               k_ptr_range_check)                       \
@@ -170,6 +122,7 @@ typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer,
 int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dobool(const struct ctl_table *table, int write, void *buffer,
                size_t *lenp, loff_t *ppos);
+
 int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer,
                         size_t *lenp, loff_t *ppos);
@@ -177,6 +130,11 @@ int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
                       size_t *lenp, loff_t *ppos,
                       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
                                   int dir, const struct ctl_table *table));
+int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp,
+                         ulong (*k_ptr_op)(const ulong));
+int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp,
+                         ulong (*u_ptr_op)(const ulong));
+
 int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer,
                size_t *lenp, loff_t *ppos);
index 54deced9ab698f223e12cc1f7ee09503789dbfe2..42975aa84ee3e7020b21af11a97feda12252e301 100644 (file)
@@ -458,8 +458,73 @@ static int do_proc_uint_conv_minmax(ulong *u_ptr, uint *k_ptr, int dir,
                              proc_uint_u2k_conv, proc_uint_k2u_conv);
 }
 
-static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY)
-static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY)
+/**
+ * proc_int_k2u_conv_kop - Assign kernel value to a user space pointer
+ * @u_ptr: pointer to user space variable
+ * @k_ptr: pointer to kernel variable
+ * @negp: assigned %TRUE if the converted kernel value is negative;
+ *        %FALSE otherweise
+ * @k_ptr_op: execute this function before assigning to u_ptr
+ *
+ * Uses READ_ONCE to get value from k_ptr. Executes k_ptr_op before assigning
+ * to u_ptr if not NULL. Does **not** check for overflow.
+ *
+ * Returns: 0 on success.
+ */
+int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp,
+                         ulong (*k_ptr_op)(const ulong))
+{
+       int val = READ_ONCE(*k_ptr);
+
+       if (val < 0) {
+               *negp = true;
+               *u_ptr = k_ptr_op ? -k_ptr_op((ulong)val) : -(ulong)val;
+       } else {
+               *negp = false;
+               *u_ptr = k_ptr_op ? k_ptr_op((ulong)val) : (ulong) val;
+       }
+       return 0;
+}
+
+/**
+ * proc_int_u2k_conv_uop - Assign user value to a kernel pointer
+ * @u_ptr: pointer to user space variable
+ * @k_ptr: pointer to kernel variable
+ * @negp: If %TRUE, the converted user value is made negative.
+ * @u_ptr_op: execute this function before assigning to k_ptr
+ *
+ * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if
+ * not NULL. Check for overflow with UINT_MAX.
+ *
+ * Returns: 0 on success.
+ */
+int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp,
+                         ulong (*u_ptr_op)(const ulong))
+{
+       ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr;
+
+       if (*negp) {
+               if (u > (ulong) INT_MAX + 1)
+                       return -EINVAL;
+               WRITE_ONCE(*k_ptr, -u);
+       } else {
+               if (u > (ulong) INT_MAX)
+                       return -EINVAL;
+               WRITE_ONCE(*k_ptr, u);
+       }
+       return 0;
+}
+
+static int sysctl_user_to_kern_int_conv(const bool *negp, const ulong *u_ptr,
+                                       int *k_ptr)
+{
+       return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, NULL);
+}
+
+static int sysctl_kern_to_user_int_conv(bool *negp, ulong *u_ptr, const int *k_ptr)
+{
+       return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, NULL);
+}
 
 static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv,
                              sysctl_kern_to_user_int_conv, false)
index d31a6d40d38dc4db696f0bbe205121d73c242177..825e4c9fd26a2c8964b40509f3a5129c2b3b9f88 100644 (file)
@@ -100,26 +100,101 @@ void __init register_refined_jiffies(long cycles_per_second)
        __clocksource_register(&refined_jiffies);
 }
 
-#define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ)
-#define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ)
-
-static SYSCTL_USER_TO_KERN_INT_CONV(_hz, SYSCTL_CONV_MULT_HZ)
-static SYSCTL_KERN_TO_USER_INT_CONV(_hz, SYSCTL_CONV_DIV_HZ)
-static SYSCTL_USER_TO_KERN_INT_CONV(_userhz, clock_t_to_jiffies)
-static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_to_clock_t)
-static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies)
-static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs)
-
-static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz,
-                             sysctl_kern_to_user_int_conv_hz, false)
+#ifdef CONFIG_PROC_SYSCTL
+static ulong mult_hz(const ulong val)
+{
+       return val * HZ;
+}
+
+static ulong div_hz(const ulong val)
+{
+       return val / HZ;
+}
+
+static int sysctl_u2k_int_conv_hz(const bool *negp, const ulong *u_ptr, int *k_ptr)
+{
+       return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, mult_hz);
+}
+
+static int sysctl_k2u_int_conv_hz(bool *negp, ulong *u_ptr, const int *k_ptr)
+{
+       return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, div_hz);
+}
+
+static int sysctl_u2k_int_conv_userhz(const bool *negp, const ulong *u_ptr, int *k_ptr)
+{
+       return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, clock_t_to_jiffies);
+}
+
+static ulong sysctl_jiffies_to_clock_t(const ulong val)
+{
+       return jiffies_to_clock_t(val);
+}
+
+static int sysctl_k2u_int_conv_userhz(bool *negp, ulong *u_ptr, const int *k_ptr)
+{
+       return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_clock_t);
+}
+
+static ulong sysctl_msecs_to_jiffies(const ulong val)
+{
+       return msecs_to_jiffies(val);
+}
+
+static int sysctl_u2k_int_conv_ms(const bool *negp, const ulong *u_ptr, int *k_ptr)
+{
+       return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, sysctl_msecs_to_jiffies);
+}
+
+static ulong sysctl_jiffies_to_msecs(const ulong val)
+{
+       return jiffies_to_msecs(val);
+}
+
+static int sysctl_k2u_int_conv_ms(bool *negp, ulong *u_ptr, const int *k_ptr)
+{
+       return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_msecs);
+}
+
+
+static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_u2k_int_conv_hz,
+                             sysctl_k2u_int_conv_hz, false)
 static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies,
-                             sysctl_user_to_kern_int_conv_userhz,
-                             sysctl_kern_to_user_int_conv_userhz, false)
-static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms,
-                             sysctl_kern_to_user_int_conv_ms, false)
+                             sysctl_u2k_int_conv_userhz,
+                             sysctl_k2u_int_conv_userhz, false)
+static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_u2k_int_conv_ms,
+                             sysctl_k2u_int_conv_ms, false)
 static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax,
-                             sysctl_user_to_kern_int_conv_ms,
-                             sysctl_kern_to_user_int_conv_ms, true)
+                             sysctl_u2k_int_conv_ms,
+                             sysctl_k2u_int_conv_ms, true)
+
+#else // CONFIG_PROC_SYSCTL
+static int do_proc_int_conv_jiffies(bool *negp, ulong *u_ptr, int *k_ptr,
+                                   int dir, const struct ctl_table *tbl)
+{
+       return -ENOSYS;
+}
+
+static int do_proc_int_conv_userhz_jiffies(bool *negp, ulong *u_ptr,
+                                          int *k_ptr, int dir,
+                                          const struct ctl_table *tbl)
+{
+       return -ENOSYS;
+}
+
+static int do_proc_int_conv_ms_jiffies(bool *negp, ulong *u_ptr, int *k_ptr,
+                                      int dir, const struct ctl_table *tbl)
+{
+       return -ENOSYS;
+}
+
+static int do_proc_int_conv_ms_jiffies_minmax(bool *negp, ulong *u_ptr,
+                                             int *k_ptr, int dir,
+                                             const struct ctl_table *tbl)
+{
+       return -ENOSYS;
+}
+#endif
 
 /**
  * proc_dointvec_jiffies - read a vector of integers as seconds