lkml.org 
[lkml]   [2021]   [Nov]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
SubjectRe: [PATCH v2 2/9] sysctl: Move some boundary constants from sysctl.c to sysctl_vals
Xiaoming Ni <nixiaoming@huawei.com> writes:

> On 2021/11/24 12:51, Eric W. Biederman wrote:
>> Luis Chamberlain <mcgrof@kernel.org> writes:
>>
>>> From: Xiaoming Ni <nixiaoming@huawei.com>
>>>
>>> sysctl has helpers which let us specify boundary values for a min or
>>> max int value. Since these are used for a boundary check only they don't
>>> change, so move these variables to sysctl_vals to avoid adding duplicate
>>> variables. This will help with our cleanup of kernel/sysctl.c.
>>
>> Ouch.
>>
>> I kind of, sort of, have to protest.
>>
>> Where the macros that use sysctl_vals don't have a type they have caused
>> mysterious code breakage because people did not realize they can not be
>> used with sysctls that take a long instead of an int.
>>
>> This came up with when the internal storage for ucounts see
>> kernel/ucount.c changed from an int to a long. We were quite a while
>> tracking what was going on until we realized that the code could not use
>> SYSCTL_ZERO and SYSCTL_INT_MAX and that we had to defined our own thatSYSCTL_ZERO and SYSCTL_ZERO involve dozens of files and are used in hundreds of places.
>> were long.
>>
> static unsigned long zero_ul;
> static unsigned long one_ul = 1;
> static unsigned long long_max = LONG_MAX;
> EXPORT_SYMBOL(proc_doulongvec_minmax);
>
> Yes, min/max of type unsigned long is used in multiple sysctl
> interfaces. It is necessary to add an unsigned long sysctl_val array
> to avoid repeated definitions in different .c files.
>
>> So before we extend something like this can we please change the
>> macro naming convention so that it includes the size of the type
>> we want.
>>
> The int type is the most widely used type. By default, numeric
> constants are also of the int type. SYSCTL_ZERO and SYSCTL_ZERO
> involve dozens of files and are used in hundreds of places. Whether
> only non-int macros need to be named with their type size?
>
>>
>> I am also not a fan of sysctl_vals living in proc_sysctl. They
>> have nothing to do with the code in that file. They would do much
>> better in kernel/sysctl.c close to the helpers that use them.
>>
> yes
>

Looking a little more. I think it makes sense to do something like:

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 1fa2b69c6fc3..c299009421ea 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -121,8 +121,8 @@ struct ctl_table {
struct ctl_table *child; /* Deprecated */
proc_handler *proc_handler; /* Callback for text formatting */
struct ctl_table_poll *poll;
- void *extra1;
- void *extra2;
+ long min;
+ long max;
} __randomize_layout;

Nearly every use of .extra1 and .extra2 are for min and max values.
A long takes the same storage as a void * parameter.

So it would be a net saving in storage as you don't have separate
storage for the values anywhere.
There are a few cases where .extra1 is used for something else
so keeping a "void *extra" field will probably be needed.

By finishing the removal of the child field adding a "void *extra"
field can be done at no storage cost.

Having the min and max parameters in the structure has the major
advantage that there is no redirection, and no fancy games. People
can just read the value from the structure initializer. Plus a
conversion from int to long won't requiring changing the min and
max constants.

So really I think instead of doubling down on the error prone case
that we have and extending sysctl_vals we should just get rid of
it entirely.

It is a bit more work to make that change but the long term result is
much better.

Any chance we can do that for a cleanup instead of extending sysctl_vals?

Eric

\
 
 \ /
  Last update: 2021-11-24 18:40    [W:0.065 / U:0.704 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site