mirror of https://github.com/torvalds/linux.git
Summary
* Move jiffies converters out of kernel/sysctl.c Moved the jiffies converters into kernel/time/jiffies.c and replaced the pipe-max-size proc_handler converter with a macro based version. This is all part of the effort to relocate non-sysctl logic out of kernel/sysctl.c into more relevant subsystems. No functional changes. * Generalize proc handler converter creation Removed duplicated sysctl converter logic by consolidating it in macros. These are used inside sysctl core as well as in pipe.c and jiffies.c. Converter kernel and user space pointer args are now automatically const qualified for the convenience of the caller. No functional changes. * Miscellaneous Fixed kernel-doc format warnings, removed unnecessary __user qualifiers, and moved the nmi_watchdog sysctl into .rodata. * Testing This series was run through sysctl selftests/kunit test suite in x86_64. It went into linux-next after rc2, giving it a good 4/5 weeks of testing. -----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEErkcJVyXmMSXOyyeQupfNUreWQU8FAmktuJMACgkQupfNUreW QU9l8Qv+Noh/wLTqBEmHCrQ8k19YCNlBHO6a10Q5bFiAiGdTAMCZ7oFzoAwAjv5y pLtzS75G89zP0O6wgkxTsmoDNi4MRJenOCyjyEDFYvrK+qSTm0CWs0sZCsHqX4Dg 7M+7PVK/EbMO5509J2ae6cYS9pjfwg3EBQZ978b/FATkuhRjxOIJhIv3ZoaFjme4 0q/xqHw+oms5CUL035BfqtkoskIiRT19DAvM/DEjc2ByaHCTGURv00XLvSDHaRer O0Z8nXaxOOCscLunZbC3UL+hC7tB0nPE+XSzm9ylBEM7bTxeZmtvx2G6ru0+873U Sp+BwpFhe0RmzBFlclkd7UPtvGlFAY2QgAfpSaiLsodkoX0mctquTgpy99LhxKej EEyjl9tPVrYoH4MG562bZPGrQHtV4vnR9DXYx56vYtY2Fyr1GZmWawQoMZsHe9AU cVw5HrfeKeHBhk9hi3ZvT9z96ns3YBmIHnYNDeMy+mF/i+cVu///GwgGuFqUqKag 3eWcTaPh =DXVD -----END PGP SIGNATURE----- Merge tag 'sysctl-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl Pull sysctl updates from Joel Granados: - Move jiffies converters out of kernel/sysctl.c Move the jiffies converters into kernel/time/jiffies.c and replace the pipe-max-size proc_handler converter with a macro based version. This is all part of the effort to relocate non-sysctl logic out of kernel/sysctl.c into more relevant subsystems. No functional changes. - Generalize proc handler converter creation Remove duplicated sysctl converter logic by consolidating it in macros. These are used inside sysctl core as well as in pipe.c and jiffies.c. Converter kernel and user space pointer args are now automatically const qualified for the convenience of the caller. No functional changes. - Miscellaneous Fix kernel-doc format warnings, remove unnecessary __user qualifiers, and move the nmi_watchdog sysctl into .rodata. - Testing This series was run through sysctl selftests/kunit test suite in x86_64. It went into linux-next after rc2, giving it a good 4/5 weeks of testing. * tag 'sysctl-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl: (21 commits) sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv sysctl: Create pipe-max-size converter using sysctl UINT macros sysctl: Move proc_doulongvec_ms_jiffies_minmax to kernel/time/jiffies.c sysctl: Move jiffies converters to kernel/time/jiffies.c sysctl: Move UINT converter macros to sysctl header sysctl: Move INT converter macros to sysctl header sysctl: Allow custom converters from outside sysctl sysctl: remove __user qualifier from stack_erasing_sysctl buffer argument sysctl: Create macro for user-to-kernel uint converter sysctl: Add optional range checking to SYSCTL_UINT_CONV_CUSTOM sysctl: Create unsigned int converter using new macro sysctl: Add optional range checking to SYSCTL_INT_CONV_CUSTOM sysctl: Create integer converters with one macro sysctl: Create converter functions with two new macros sysctl: Discriminate between kernel and user converter params sysctl: Indicate the direction of operation with macro names sysctl: Remove superfluous __do_proc_* indirection sysctl: Remove superfluous tbl_data param from "dovec" functions sysctl: Replace void pointer with const pointer to ctl_table sysctl: fix kernel-doc format warning ...
This commit is contained in:
commit
ac20755937
28
fs/pipe.c
28
fs/pipe.c
|
|
@ -1481,31 +1481,16 @@ static struct file_system_type pipe_fs_type = {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
|
||||
unsigned int *valp,
|
||||
int write, void *data)
|
||||
{
|
||||
if (write) {
|
||||
unsigned int val;
|
||||
|
||||
val = round_pipe_size(*lvalp);
|
||||
if (val == 0)
|
||||
return -EINVAL;
|
||||
|
||||
*valp = val;
|
||||
} else {
|
||||
unsigned int val = *valp;
|
||||
*lvalp = (unsigned long) val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static SYSCTL_USER_TO_KERN_UINT_CONV(_pipe_maxsz, round_pipe_size)
|
||||
static SYSCTL_UINT_CONV_CUSTOM(_pipe_maxsz,
|
||||
sysctl_user_to_kern_uint_conv_pipe_maxsz,
|
||||
sysctl_kern_to_user_uint_conv, true)
|
||||
|
||||
static int proc_dopipe_max_size(const struct ctl_table *table, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
return do_proc_douintvec(table, write, buffer, lenp, ppos,
|
||||
do_proc_dopipe_max_size_conv, NULL);
|
||||
return proc_douintvec_conv(table, write, buffer, lenp, ppos,
|
||||
do_proc_uint_conv_pipe_maxsz);
|
||||
}
|
||||
|
||||
static const struct ctl_table fs_pipe_sysctls[] = {
|
||||
|
|
@ -1515,6 +1500,7 @@ static const struct ctl_table fs_pipe_sysctls[] = {
|
|||
.maxlen = sizeof(pipe_max_size),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dopipe_max_size,
|
||||
.extra1 = SYSCTL_ONE,
|
||||
},
|
||||
{
|
||||
.procname = "pipe-user-pages-hard",
|
||||
|
|
|
|||
|
|
@ -611,4 +611,16 @@ extern unsigned long nsecs_to_jiffies(u64 n);
|
|||
|
||||
#define TIMESTAMP_SIZE 30
|
||||
|
||||
struct ctl_table;
|
||||
int proc_dointvec_jiffies(const struct ctl_table *table, int dir, void *buffer,
|
||||
size_t *lenp, loff_t *ppos);
|
||||
int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos);
|
||||
int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos);
|
||||
int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
|
||||
size_t *lenp, loff_t *ppos);
|
||||
int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -59,6 +59,121 @@ extern const int sysctl_vals[];
|
|||
#define SYSCTL_LONG_ONE ((void *)&sysctl_long_vals[1])
|
||||
#define SYSCTL_LONG_MAX ((void *)&sysctl_long_vals[2])
|
||||
|
||||
#define SYSCTL_CONV_IDENTITY(val) (val)
|
||||
/**
|
||||
*
|
||||
* "dir" originates from read_iter (dir = 0) or write_iter (dir = 1)
|
||||
* in the file_operations struct at proc/proc_sysctl.c. Its value means
|
||||
* one of two things for sysctl:
|
||||
* 1. SYSCTL_USER_TO_KERN(dir) Writing to an internal kernel variable from user
|
||||
* space (dir > 0)
|
||||
* 2. SYSCTL_KERN_TO_USER(dir) Writing to a user space buffer from a kernel
|
||||
* variable (dir == 0).
|
||||
*/
|
||||
#define SYSCTL_USER_TO_KERN(dir) (!!(dir))
|
||||
#define SYSCTL_KERN_TO_USER(dir) (!dir)
|
||||
|
||||
#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)
|
||||
*/
|
||||
#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \
|
||||
k_ptr_range_check) \
|
||||
int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\
|
||||
int dir, const struct ctl_table *tbl) \
|
||||
{ \
|
||||
if (SYSCTL_KERN_TO_USER(dir)) \
|
||||
return kern_to_user(negp, u_ptr, k_ptr); \
|
||||
\
|
||||
if (k_ptr_range_check) { \
|
||||
int tmp_k, ret; \
|
||||
if (!tbl) \
|
||||
return -EINVAL; \
|
||||
ret = user_to_kern(negp, u_ptr, &tmp_k); \
|
||||
if (ret) \
|
||||
return ret; \
|
||||
if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || \
|
||||
(tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) \
|
||||
return -EINVAL; \
|
||||
WRITE_ONCE(*k_ptr, tmp_k); \
|
||||
} else \
|
||||
return user_to_kern(negp, u_ptr, k_ptr); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define SYSCTL_USER_TO_KERN_UINT_CONV(name, u_ptr_op) \
|
||||
int sysctl_user_to_kern_uint_conv##name(const unsigned long *u_ptr,\
|
||||
unsigned int *k_ptr) \
|
||||
{ \
|
||||
unsigned long u = u_ptr_op(*u_ptr); \
|
||||
if (u > UINT_MAX) \
|
||||
return -EINVAL; \
|
||||
WRITE_ONCE(*k_ptr, u); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \
|
||||
k_ptr_range_check) \
|
||||
int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr, \
|
||||
int dir, const struct ctl_table *tbl) \
|
||||
{ \
|
||||
if (SYSCTL_KERN_TO_USER(dir)) \
|
||||
return kern_to_user(u_ptr, k_ptr); \
|
||||
\
|
||||
if (k_ptr_range_check) { \
|
||||
unsigned int tmp_k; \
|
||||
int ret; \
|
||||
if (!tbl) \
|
||||
return -EINVAL; \
|
||||
ret = user_to_kern(u_ptr, &tmp_k); \
|
||||
if (ret) \
|
||||
return ret; \
|
||||
if ((tbl->extra1 && \
|
||||
*(unsigned int *)tbl->extra1 > tmp_k) || \
|
||||
(tbl->extra2 && \
|
||||
*(unsigned int *)tbl->extra2 < tmp_k)) \
|
||||
return -ERANGE; \
|
||||
WRITE_ONCE(*k_ptr, tmp_k); \
|
||||
} else \
|
||||
return user_to_kern(u_ptr, k_ptr); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
extern const unsigned long sysctl_long_vals[];
|
||||
|
||||
typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer,
|
||||
|
|
@ -68,25 +183,30 @@ 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);
|
||||
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_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
|
||||
int proc_dointvec_minmax(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);
|
||||
int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer,
|
||||
size_t *lenp, loff_t *ppos,
|
||||
int (*conv)(unsigned long *lvalp, unsigned int *valp,
|
||||
int write, const struct ctl_table *table));
|
||||
|
||||
int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer,
|
||||
size_t *lenp, loff_t *ppos);
|
||||
int proc_dointvec_jiffies(const struct ctl_table *, int, void *, size_t *, loff_t *);
|
||||
int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos);
|
||||
int proc_dointvec_userhz_jiffies(const struct ctl_table *, int, void *, size_t *,
|
||||
loff_t *);
|
||||
int proc_dointvec_ms_jiffies(const struct ctl_table *, int, void *, size_t *,
|
||||
loff_t *);
|
||||
int proc_doulongvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *);
|
||||
int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int, void *,
|
||||
size_t *, loff_t *);
|
||||
int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos,
|
||||
unsigned long convmul, unsigned long convdiv);
|
||||
int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t *);
|
||||
int proc_do_static_key(const struct ctl_table *table, int write, void *buffer,
|
||||
size_t *lenp, loff_t *ppos);
|
||||
int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, const unsigned int *k_ptr);
|
||||
|
||||
/*
|
||||
* Register a set of sysctl names by calling register_sysctl
|
||||
|
|
@ -156,6 +276,10 @@ struct ctl_node {
|
|||
* @nreg: When nreg drops to 0 the ctl_table_header will be unregistered.
|
||||
* @rcu: Delays the freeing of the inode. Introduced with "unfuck proc_sysctl ->d_compare()"
|
||||
*
|
||||
* @type: Enumeration to differentiate between ctl target types
|
||||
* @type.SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations
|
||||
* @type.SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Identifies a permanently empty dir
|
||||
* target to serve as a mount point
|
||||
*/
|
||||
struct ctl_table_header {
|
||||
union {
|
||||
|
|
@ -175,13 +299,6 @@ struct ctl_table_header {
|
|||
struct ctl_dir *parent;
|
||||
struct ctl_node *node;
|
||||
struct hlist_head inodes; /* head for proc_inode->sysctl_inodes */
|
||||
/**
|
||||
* enum type - Enumeration to differentiate between ctl target types
|
||||
* @SYSCTL_TABLE_TYPE_DEFAULT: ctl target with no special considerations
|
||||
* @SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY: Used to identify a permanently
|
||||
* empty directory target to serve
|
||||
* as mount point.
|
||||
*/
|
||||
enum {
|
||||
SYSCTL_TABLE_TYPE_DEFAULT,
|
||||
SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY,
|
||||
|
|
@ -235,12 +352,6 @@ extern struct ctl_table_header *register_sysctl_mount_point(const char *path);
|
|||
|
||||
void do_sysctl_args(void);
|
||||
bool sysctl_is_alias(char *param);
|
||||
int do_proc_douintvec(const struct ctl_table *table, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos,
|
||||
int (*conv)(unsigned long *lvalp,
|
||||
unsigned int *valp,
|
||||
int write, void *data),
|
||||
void *data);
|
||||
|
||||
extern int unaligned_enabled;
|
||||
extern int no_unaligned_warning;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static DEFINE_STATIC_KEY_FALSE(stack_erasing_bypass);
|
|||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
static int stack_erasing_sysctl(const struct ctl_table *table, int write,
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int ret = 0;
|
||||
int state = !static_branch_unlikely(&stack_erasing_bypass);
|
||||
|
|
|
|||
649
kernel/sysctl.c
649
kernel/sysctl.c
File diff suppressed because it is too large
Load Diff
|
|
@ -99,3 +99,128 @@ 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)
|
||||
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)
|
||||
static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax,
|
||||
sysctl_user_to_kern_int_conv_ms,
|
||||
sysctl_kern_to_user_int_conv_ms, true)
|
||||
|
||||
/**
|
||||
* proc_dointvec_jiffies - read a vector of integers as seconds
|
||||
* @table: the sysctl table
|
||||
* @dir: %TRUE if this is a write to the sysctl file
|
||||
* @buffer: the user buffer
|
||||
* @lenp: the size of the user buffer
|
||||
* @ppos: file position
|
||||
*
|
||||
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
|
||||
* values from/to the user buffer, treated as an ASCII string.
|
||||
* The values read are assumed to be in seconds, and are converted into
|
||||
* jiffies.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int proc_dointvec_jiffies(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
|
||||
do_proc_int_conv_jiffies);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_dointvec_jiffies);
|
||||
|
||||
/**
|
||||
* proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
|
||||
* @table: the sysctl table
|
||||
* @dir: %TRUE if this is a write to the sysctl file
|
||||
* @buffer: the user buffer
|
||||
* @lenp: the size of the user buffer
|
||||
* @ppos: pointer to the file position
|
||||
*
|
||||
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
|
||||
* values from/to the user buffer, treated as an ASCII string.
|
||||
* The values read are assumed to be in 1/USER_HZ seconds, and
|
||||
* are converted into jiffies.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
if (SYSCTL_USER_TO_KERN(dir) && USER_HZ < HZ)
|
||||
return -EINVAL;
|
||||
return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
|
||||
do_proc_int_conv_userhz_jiffies);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
|
||||
|
||||
/**
|
||||
* proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
|
||||
* @table: the sysctl table
|
||||
* @dir: %TRUE if this is a write to the sysctl file
|
||||
* @buffer: the user buffer
|
||||
* @lenp: the size of the user buffer
|
||||
* @ppos: the current position in the file
|
||||
*
|
||||
* Reads/writes up to table->maxlen/sizeof(unsigned int) integer
|
||||
* values from/to the user buffer, treated as an ASCII string.
|
||||
* The values read are assumed to be in 1/1000 seconds, and
|
||||
* are converted into jiffies.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
|
||||
size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
|
||||
do_proc_int_conv_ms_jiffies);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
|
||||
|
||||
int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
|
||||
do_proc_int_conv_ms_jiffies_minmax);
|
||||
}
|
||||
|
||||
/**
|
||||
* proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
|
||||
* @table: the sysctl table
|
||||
* @dir: %TRUE if this is a write to the sysctl file
|
||||
* @buffer: the user buffer
|
||||
* @lenp: the size of the user buffer
|
||||
* @ppos: file position
|
||||
*
|
||||
* Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
|
||||
* values from/to the user buffer, treated as an ASCII string. The values
|
||||
* are treated as milliseconds, and converted to jiffies when they are stored.
|
||||
*
|
||||
* This routine will ensure the values are within the range specified by
|
||||
* table->extra1 (min) and table->extra2 (max).
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos,
|
||||
HZ, 1000l);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
|
||||
|
||||
|
|
|
|||
|
|
@ -1240,14 +1240,11 @@ static const struct ctl_table watchdog_sysctls[] = {
|
|||
},
|
||||
#endif /* CONFIG_SMP */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct ctl_table watchdog_hardlockup_sysctl[] = {
|
||||
{
|
||||
.procname = "nmi_watchdog",
|
||||
.data = &watchdog_hardlockup_user_enabled,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0444,
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_nmi_watchdog,
|
||||
.extra1 = SYSCTL_ZERO,
|
||||
.extra2 = SYSCTL_ONE,
|
||||
|
|
@ -1257,10 +1254,6 @@ static struct ctl_table watchdog_hardlockup_sysctl[] = {
|
|||
static void __init watchdog_sysctl_init(void)
|
||||
{
|
||||
register_sysctl_init("kernel", watchdog_sysctls);
|
||||
|
||||
if (watchdog_hardlockup_available)
|
||||
watchdog_hardlockup_sysctl[0].mode = 0644;
|
||||
register_sysctl_init("kernel", watchdog_hardlockup_sysctl);
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
|||
Loading…
Reference in New Issue