Message ID | 20220801152016.36498-2-deller@gmx.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Dump command line of faulting process to syslog | expand |
Hi Helge, I love your patch! Perhaps something to improve: [auto build test WARNING on tip/x86/mm] [also build test WARNING on linus/master] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Helge-Deller/Dump-command-line-of-faulting-process-to-syslog/20220801-232209 base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 8f1d56f64f8d6b80dea2d1978d10071132a695c5 config: hexagon-randconfig-r005-20220801 (https://download.01.org/0day-ci/archive/20220807/202208072219.zrLROtui-lkp@intel.com/config) compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 52cd00cabf479aa7eb6dbb063b7ba41ea57bce9e) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/82149c3c87cadf0a362c3015753f97c7582f31e4 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Helge-Deller/Dump-command-line-of-faulting-process-to-syslog/20220801-232209 git checkout 82149c3c87cadf0a362c3015753f97c7582f31e4 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash kernel/sched/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from kernel/sched/core.c:84: In file included from kernel/sched/sched.h:50: >> include/linux/proc_fs.h:222:64: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:72: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:80: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ kernel/sched/core.c:3577:20: warning: unused function 'rq_has_pinned_tasks' [-Wunused-function] static inline bool rq_has_pinned_tasks(struct rq *rq) ^ kernel/sched/core.c:5505:20: warning: unused function 'sched_tick_start' [-Wunused-function] static inline void sched_tick_start(int cpu) { } ^ kernel/sched/core.c:5506:20: warning: unused function 'sched_tick_stop' [-Wunused-function] static inline void sched_tick_stop(int cpu) { } ^ kernel/sched/core.c:6200:20: warning: unused function 'sched_core_cpu_starting' [-Wunused-function] static inline void sched_core_cpu_starting(unsigned int cpu) {} ^ kernel/sched/core.c:6201:20: warning: unused function 'sched_core_cpu_deactivate' [-Wunused-function] static inline void sched_core_cpu_deactivate(unsigned int cpu) {} ^ kernel/sched/core.c:6202:20: warning: unused function 'sched_core_cpu_dying' [-Wunused-function] static inline void sched_core_cpu_dying(unsigned int cpu) {} ^ 9 warnings generated. -- In file included from kernel/sched/fair.c:54: In file included from kernel/sched/sched.h:50: >> include/linux/proc_fs.h:222:64: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:72: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:80: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ kernel/sched/fair.c:5512:6: warning: no previous prototype for function 'init_cfs_bandwidth' [-Wmissing-prototypes] void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} ^ kernel/sched/fair.c:5512:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} ^ static kernel/sched/fair.c:11697:6: warning: no previous prototype for function 'free_fair_sched_group' [-Wmissing-prototypes] void free_fair_sched_group(struct task_group *tg) { } ^ kernel/sched/fair.c:11697:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void free_fair_sched_group(struct task_group *tg) { } ^ static kernel/sched/fair.c:11699:5: warning: no previous prototype for function 'alloc_fair_sched_group' [-Wmissing-prototypes] int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) ^ kernel/sched/fair.c:11699:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) ^ static kernel/sched/fair.c:11704:6: warning: no previous prototype for function 'online_fair_sched_group' [-Wmissing-prototypes] void online_fair_sched_group(struct task_group *tg) { } ^ kernel/sched/fair.c:11704:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void online_fair_sched_group(struct task_group *tg) { } ^ static kernel/sched/fair.c:11706:6: warning: no previous prototype for function 'unregister_fair_sched_group' [-Wmissing-prototypes] void unregister_fair_sched_group(struct task_group *tg) { } ^ kernel/sched/fair.c:11706:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void unregister_fair_sched_group(struct task_group *tg) { } ^ static kernel/sched/fair.c:489:20: warning: unused function 'list_del_leaf_cfs_rq' [-Wunused-function] static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq) ^ kernel/sched/fair.c:510:19: warning: unused function 'tg_is_idle' [-Wunused-function] static inline int tg_is_idle(struct task_group *tg) ^ kernel/sched/fair.c:2961:20: warning: unused function 'account_numa_enqueue' [-Wunused-function] static inline void account_numa_enqueue(struct rq *rq, struct task_struct *p) ^ kernel/sched/fair.c:2965:20: warning: unused function 'account_numa_dequeue' [-Wunused-function] static inline void account_numa_dequeue(struct rq *rq, struct task_struct *p) ^ kernel/sched/fair.c:2969:20: warning: unused function 'update_scan_period' [-Wunused-function] static inline void update_scan_period(struct task_struct *p, int new_cpu) ^ kernel/sched/fair.c:4171:20: warning: unused function 'cfs_rq_is_decayed' [-Wunused-function] static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) ^ kernel/sched/fair.c:4185:20: warning: unused function 'remove_entity_load_avg' [-Wunused-function] static inline void remove_entity_load_avg(struct sched_entity *se) {} ^ kernel/sched/fair.c:5493:20: warning: unused function 'sync_throttle' [-Wunused-function] static inline void sync_throttle(struct task_group *tg, int cpu) {} ^ kernel/sched/fair.c:5506:19: warning: unused function 'throttled_lb_pair' [-Wunused-function] static inline int throttled_lb_pair(struct task_group *tg, ^ kernel/sched/fair.c:5518:37: warning: unused function 'tg_cfs_bandwidth' [-Wunused-function] static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg) ^ kernel/sched/fair.c:5522:20: warning: unused function 'destroy_cfs_bandwidth' [-Wunused-function] static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} ^ kernel/sched/fair.c:5523:20: warning: unused function 'update_runtime_enabled' [-Wunused-function] static inline void update_runtime_enabled(struct rq *rq) {} ^ kernel/sched/fair.c:5524:20: warning: unused function 'unthrottle_offline_cfs_rqs' [-Wunused-function] static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {} ^ 21 warnings generated. -- In file included from kernel/sched/build_policy.c:34: In file included from kernel/sched/sched.h:50: >> include/linux/proc_fs.h:222:64: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:72: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:80: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ In file included from kernel/sched/build_policy.c:45: kernel/sched/rt.c:259:6: warning: no previous prototype for function 'unregister_rt_sched_group' [-Wmissing-prototypes] void unregister_rt_sched_group(struct task_group *tg) { } ^ kernel/sched/rt.c:259:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void unregister_rt_sched_group(struct task_group *tg) { } ^ static kernel/sched/rt.c:261:6: warning: no previous prototype for function 'free_rt_sched_group' [-Wmissing-prototypes] void free_rt_sched_group(struct task_group *tg) { } ^ kernel/sched/rt.c:261:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void free_rt_sched_group(struct task_group *tg) { } ^ static kernel/sched/rt.c:263:5: warning: no previous prototype for function 'alloc_rt_sched_group' [-Wmissing-prototypes] int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent) ^ kernel/sched/rt.c:263:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent) ^ static 6 warnings generated. -- In file included from kernel/sched/build_utility.c:35: >> include/linux/proc_fs.h:222:64: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:72: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ include/linux/proc_fs.h:222:80: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } ^ 3 warnings generated. vim +222 include/linux/proc_fs.h 221 > 222 static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } 223
On 8/7/22 16:28, kernel test robot wrote: > Hi Helge, > > I love your patch! Perhaps something to improve: > > [auto build test WARNING on tip/x86/mm] > [also build test WARNING on linus/master] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > [...] > include/linux/proc_fs.h:222:72: warning: omitting the parameter name in a function definition is a C2x extension [-Wc2x-extensions] > static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } > ^ Will fix. Thanks! Helge
diff --git a/fs/proc/base.c b/fs/proc/base.c index 8dfa36a99c74..4da9a8b3c7d1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -217,20 +217,17 @@ static int proc_root_link(struct dentry *dentry, struct path *path) */ static ssize_t get_mm_proctitle(struct mm_struct *mm, char __user *buf, size_t count, unsigned long pos, - unsigned long arg_start) + unsigned long arg_start, char *page) { - char *page; int ret, got; + size_t size; - if (pos >= PAGE_SIZE) + size = min_t(size_t, PAGE_SIZE, count); + if (pos >= size) return 0; - page = (char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - ret = 0; - got = access_remote_vm(mm, arg_start, page, PAGE_SIZE, FOLL_ANON); + got = access_remote_vm(mm, arg_start, page, size, FOLL_ANON); if (got > 0) { int len = strnlen(page, got); @@ -238,7 +235,9 @@ static ssize_t get_mm_proctitle(struct mm_struct *mm, char __user *buf, if (len < got) len++; - if (len > pos) { + if (!buf) + ret = len; + else if (len > pos) { len -= pos; if (len > count) len = count; @@ -248,16 +247,15 @@ static ssize_t get_mm_proctitle(struct mm_struct *mm, char __user *buf, ret = len; } } - free_page((unsigned long)page); return ret; } static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos, char *page) { unsigned long arg_start, arg_end, env_start, env_end; unsigned long pos, len; - char *page, c; + char c; /* Check if process spawned far enough to have cmdline. */ if (!mm->env_end) @@ -283,7 +281,7 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf, len = env_end - arg_start; /* We're not going to care if "*ppos" has high bits set */ - pos = *ppos; + pos = ppos ? *ppos : 0; if (pos >= len) return 0; if (count > len - pos) @@ -299,7 +297,7 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf, * pos is 0, and set a flag in the 'struct file'. */ if (access_remote_vm(mm, arg_end-1, &c, 1, FOLL_ANON) == 1 && c) - return get_mm_proctitle(mm, buf, count, pos, arg_start); + return get_mm_proctitle(mm, buf, count, pos, arg_start, page); /* * For the non-setproctitle() case we limit things strictly @@ -311,10 +309,6 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf, if (count > arg_end - pos) count = arg_end - pos; - page = (char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - len = 0; while (count) { int got; @@ -323,7 +317,8 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf, got = access_remote_vm(mm, pos, page, size, FOLL_ANON); if (got <= 0) break; - got -= copy_to_user(buf, page, got); + if (buf) + got -= copy_to_user(buf, page, got); if (unlikely(!got)) { if (!len) len = -EFAULT; @@ -335,12 +330,11 @@ static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf, count -= got; } - free_page((unsigned long)page); return len; } static ssize_t get_task_cmdline(struct task_struct *tsk, char __user *buf, - size_t count, loff_t *pos) + size_t count, loff_t *pos, char *page) { struct mm_struct *mm; ssize_t ret; @@ -349,23 +343,51 @@ static ssize_t get_task_cmdline(struct task_struct *tsk, char __user *buf, if (!mm) return 0; - ret = get_mm_cmdline(mm, buf, count, pos); + ret = get_mm_cmdline(mm, buf, count, pos, page); mmput(mm); return ret; } +/* + * Place up to maxcount chars of the command line of the process into the + * cmdline buffer. + */ +void get_task_cmdline_kernel(struct task_struct *tsk, + char *cmdline, size_t maxcount) +{ + int i; + + memset(cmdline, 0, maxcount); + get_task_cmdline(tsk, NULL, maxcount - 1, NULL, cmdline); + + /* remove NULs between parameters */ + for (i = 0; i < maxcount - 2; i++) { + if (cmdline[i]) + continue; + if (cmdline[i+1] == 0) + break; + cmdline[i] = ' '; + } +} + static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct task_struct *tsk; ssize_t ret; + char *page; BUG_ON(*pos < 0); tsk = get_proc_task(file_inode(file)); if (!tsk) return -ESRCH; - ret = get_task_cmdline(tsk, buf, count, pos); + page = (char *)__get_free_page(GFP_KERNEL); + if (page) { + ret = get_task_cmdline(tsk, buf, count, pos, page); + free_page((unsigned long)page); + } else + ret = -ENOMEM; put_task_struct(tsk); if (ret > 0) *pos += ret; diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 81d6e4ec2294..9a256e86205c 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -158,6 +158,9 @@ int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task); #endif /* CONFIG_PROC_PID_ARCH_STATUS */ +void get_task_cmdline_kernel(struct task_struct *tsk, + char *cmdline, size_t maxcount); + #else /* CONFIG_PROC_FS */ static inline void proc_root_init(void) @@ -216,6 +219,8 @@ static inline struct pid *tgid_pidfd_to_pid(const struct file *file) return ERR_PTR(-EBADF); } +static inline void get_task_cmdline_kernel(struct task_struct *, char *, size_t) { } + #endif /* CONFIG_PROC_FS */ struct net;
Add a new function get_task_cmdline_kernel() which reads the command line of a process into a kernel buffer. This command line can then be dumped by arch code to print additional debug info on how a faulting process was started. The new function re-uses the existing code which provides the cmdline for the procfs. For that the existing functions were modified so that the buffer page is allocated outside of get_mm_proctitle() and get_mm_cmdline() and instead provided as parameter. Signed-off-by: Helge Deller <deller@gmx.de> --- fs/proc/base.c | 68 +++++++++++++++++++++++++++-------------- include/linux/proc_fs.h | 5 +++ 2 files changed, 50 insertions(+), 23 deletions(-) -- 2.37.1