From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757121AbcIGK1Y (ORCPT ); Wed, 7 Sep 2016 06:27:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42430 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757074AbcIGK1S (ORCPT ); Wed, 7 Sep 2016 06:27:18 -0400 From: Yauheni Kaliuta To: linux-kernel@vger.kernel.org Cc: aris@redhat.com, jolsa@redhat.com Subject: [PATCH RFC 1/2] rlimits: add infra to report violations Date: Wed, 7 Sep 2016 13:27:34 +0300 Message-Id: <1473244055-25240-2-git-send-email-yauheni.kaliuta@redhat.com> In-Reply-To: <1473244055-25240-1-git-send-email-yauheni.kaliuta@redhat.com> References: <20160824112428.GA15743@krava> <1473244055-25240-1-git-send-email-yauheni.kaliuta@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 07 Sep 2016 10:27:18 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The patch defines tracepoints for resource limits (rlimits) violations reporting and adds a thin layer to be called from rlimits aware code without direct dependency of the tracepoints. Signed-off-by: Yauheni Kaliuta --- include/linux/resource.h | 5 +++ kernel/Makefile | 4 +- kernel/rlimit.c | 26 +++++++++++ kernel/trace-rlimit.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 kernel/rlimit.c create mode 100644 kernel/trace-rlimit.h diff --git a/include/linux/resource.h b/include/linux/resource.h index 5bc3116e649c..f4de2827e647 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -9,5 +9,10 @@ struct task_struct; int getrusage(struct task_struct *p, int who, struct rusage __user *ru); int do_prlimit(struct task_struct *tsk, unsigned int resource, struct rlimit *new_rlim, struct rlimit *old_rlim); +void rlimit_exceeded_task(int rlimit_id, u64 req, struct task_struct *task); +void rlimit_exceeded(int rlimit_id, u64 req); +void rlimit_hard_exceeded_task(int rlimit_id, u64 req, + struct task_struct *task); +void rlimit_hard_exceeded(int rlimit_id, u64 req); #endif diff --git a/kernel/Makefile b/kernel/Makefile index e2ec54e2b952..30999d83a261 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -9,7 +9,7 @@ obj-y = fork.o exec_domain.o panic.o \ extable.o params.o \ kthread.o sys_ni.o nsproxy.o \ notifier.o ksysfs.o cred.o reboot.o \ - async.o range.o smpboot.o + async.o range.o smpboot.o rlimit.o obj-$(CONFIG_MULTIUSER) += groups.o @@ -18,6 +18,8 @@ ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_irq_work.o = $(CC_FLAGS_FTRACE) endif +CFLAGS_rlimit.o := -I$(src) + # Prevents flicker of uninteresting __do_softirq()/__local_bh_disable_ip() # in coverage traces. KCOV_INSTRUMENT_softirq.o := n diff --git a/kernel/rlimit.c b/kernel/rlimit.c new file mode 100644 index 000000000000..0b42ebc3a9d5 --- /dev/null +++ b/kernel/rlimit.c @@ -0,0 +1,26 @@ + +#include + +#define CREATE_TRACE_POINTS +#include "trace-rlimit.h" + +void rlimit_exceeded_task(int rlimit_id, u64 req, struct task_struct *task) +{ + trace_rlimit_exceeded(rlimit_id, task_rlimit(task, rlimit_id), req, + task_pid_nr(task), task->comm); +} + +void rlimit_exceeded(int rlimit_id, u64 req) +{ + rlimit_exceeded_task(rlimit_id, req, current); +} + +void rlimit_hard_exceeded_task(int rlimit_id, u64 req, struct task_struct *task) +{ + trace_rlimit_hard_exceeded(rlimit_id, task_rlimit_max(task, rlimit_id), + req, task_pid_nr(task), task->comm); +} +void rlimit_hard_exceeded(int rlimit_id, u64 req) +{ + rlimit_hard_exceeded_task(rlimit_id, req, current); +} diff --git a/kernel/trace-rlimit.h b/kernel/trace-rlimit.h new file mode 100644 index 000000000000..e7433ae8a09e --- /dev/null +++ b/kernel/trace-rlimit.h @@ -0,0 +1,112 @@ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM rlimit + +#if !defined(_TRACE_RLIMIT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_RLIMIT_H +#include + +TRACE_DEFINE_ENUM(RLIMIT_CPU); +TRACE_DEFINE_ENUM(RLIMIT_FSIZE); +TRACE_DEFINE_ENUM(RLIMIT_DATA); +TRACE_DEFINE_ENUM(RLIMIT_STACK); +TRACE_DEFINE_ENUM(RLIMIT_CORE); +TRACE_DEFINE_ENUM(RLIMIT_RSS); +TRACE_DEFINE_ENUM(RLIMIT_NPROC); +TRACE_DEFINE_ENUM(RLIMIT_NOFILE); +TRACE_DEFINE_ENUM(RLIMIT_MEMLOCK); +TRACE_DEFINE_ENUM(RLIMIT_AS); +TRACE_DEFINE_ENUM(RLIMIT_LOCKS); +TRACE_DEFINE_ENUM(RLIMIT_SIGPENDING); +TRACE_DEFINE_ENUM(RLIMIT_MSGQUEUE); +TRACE_DEFINE_ENUM(RLIMIT_NICE); +TRACE_DEFINE_ENUM(RLIMIT_RTPRIO); +TRACE_DEFINE_ENUM(RLIMIT_RTTIME); + + +#define __print_rlimit_name(id_var) \ + __print_symbolic(id_var, \ + { RLIMIT_CPU, "CPU" }, \ + { RLIMIT_FSIZE, "FSIZE" }, \ + { RLIMIT_DATA, "DATA" }, \ + { RLIMIT_STACK, "STACK" }, \ + { RLIMIT_CORE, "CORE" }, \ + { RLIMIT_RSS, "RSS" }, \ + { RLIMIT_NPROC, "NPROC" }, \ + { RLIMIT_NOFILE, "NOFILE" }, \ + { RLIMIT_MEMLOCK, "MEMLOCK" }, \ + { RLIMIT_AS, "AS" }, \ + { RLIMIT_LOCKS, "LOCKS" }, \ + { RLIMIT_SIGPENDING, "SIGPENDING" }, \ + { RLIMIT_MSGQUEUE, "MSGQUEUE" }, \ + { RLIMIT_NICE, "NICE" }, \ + { RLIMIT_RTPRIO, "RTPRIO" }, \ + { RLIMIT_RTTIME, "RTTIME" }) + +DECLARE_EVENT_CLASS(rlimit_exceeded_template, + + TP_PROTO(int rlimit_id, + unsigned long long cur, + unsigned long long req, + pid_t pid, + char *comm), + + TP_ARGS(rlimit_id, cur, req, pid, comm), + + TP_STRUCT__entry( + __field(int, rlimit_id) + __field(unsigned long long, cur) + __field(unsigned long long, req) + __field(pid_t, pid) + __string(comm, comm) + ), + TP_fast_assign( + __entry->rlimit_id = rlimit_id; + __entry->cur = cur; + __entry->req = req; + __entry->pid = pid; + __assign_str(comm, comm); + ), + TP_printk("RLIMIT %s violation [%s:%d]. Limit %llu, requested %s", + __print_rlimit_name(__entry->rlimit_id), + __get_str(comm), + __entry->pid, + __entry->cur, + __print_symbolic(__entry->req, + {(unsigned long long)-1, "Unknown"})) + ); + +DEFINE_EVENT(rlimit_exceeded_template, rlimit_exceeded, + TP_PROTO(int rlimit_id, + unsigned long long cur, + unsigned long long req, + pid_t pid, + char *comm), + + TP_ARGS(rlimit_id, cur, req, pid, comm) + ); + +DEFINE_EVENT_PRINT(rlimit_exceeded_template, rlimit_hard_exceeded, + TP_PROTO(int rlimit_id, + unsigned long long cur, + unsigned long long req, + pid_t pid, + char *comm), + + TP_ARGS(rlimit_id, cur, req, pid, comm), + + TP_printk("Hard RLIMIT %s violation [%s:%d]. Limit %llu, requested %s", + __print_rlimit_name(__entry->rlimit_id), + __get_str(comm), + __entry->pid, + __entry->cur, + __print_symbolic(__entry->req, + {(unsigned long long)-1, "Unknown"})) + ); + +#endif /* _TRACE_RLIMIT_H */ +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace-rlimit +#include -- 2.7.4