Loading include/trace/events/signal.h +22 −63 Original line number Diff line number Diff line Loading @@ -23,11 +23,23 @@ } \ } while (0) #ifndef TRACE_HEADER_MULTI_READ enum { TRACE_SIGNAL_DELIVERED, TRACE_SIGNAL_IGNORED, TRACE_SIGNAL_ALREADY_PENDING, TRACE_SIGNAL_OVERFLOW_FAIL, TRACE_SIGNAL_LOSE_INFO, }; #endif /** * signal_generate - called when a signal is generated * @sig: signal number * @info: pointer to struct siginfo * @task: pointer to struct task_struct * @group: shared or private * @result: TRACE_SIGNAL_* * * Current process sends a 'sig' signal to 'task' process with * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV, Loading @@ -37,9 +49,10 @@ */ TRACE_EVENT(signal_generate, TP_PROTO(int sig, struct siginfo *info, struct task_struct *task), TP_PROTO(int sig, struct siginfo *info, struct task_struct *task, int group, int result), TP_ARGS(sig, info, task), TP_ARGS(sig, info, task, group, result), TP_STRUCT__entry( __field( int, sig ) Loading @@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate, __field( int, code ) __array( char, comm, TASK_COMM_LEN ) __field( pid_t, pid ) __field( int, group ) __field( int, result ) ), TP_fast_assign( Loading @@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate, TP_STORE_SIGINFO(__entry, info); memcpy(__entry->comm, task->comm, TASK_COMM_LEN); __entry->pid = task->pid; __entry->group = group; __entry->result = result; ), TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d", TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d", __entry->sig, __entry->errno, __entry->code, __entry->comm, __entry->pid) __entry->comm, __entry->pid, __entry->group, __entry->result) ); /** Loading Loading @@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver, __entry->sa_handler, __entry->sa_flags) ); DECLARE_EVENT_CLASS(signal_queue_overflow, TP_PROTO(int sig, int group, struct siginfo *info), TP_ARGS(sig, group, info), TP_STRUCT__entry( __field( int, sig ) __field( int, group ) __field( int, errno ) __field( int, code ) ), TP_fast_assign( __entry->sig = sig; __entry->group = group; TP_STORE_SIGINFO(__entry, info); ), TP_printk("sig=%d group=%d errno=%d code=%d", __entry->sig, __entry->group, __entry->errno, __entry->code) ); /** * signal_overflow_fail - called when signal queue is overflow * @sig: signal number * @group: signal to process group or not (bool) * @info: pointer to struct siginfo * * Kernel fails to generate 'sig' signal with 'info' siginfo, because * siginfo queue is overflow, and the signal is dropped. * 'group' is not 0 if the signal will be sent to a process group. * 'sig' is always one of RT signals. */ DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail, TP_PROTO(int sig, int group, struct siginfo *info), TP_ARGS(sig, group, info) ); /** * signal_lose_info - called when siginfo is lost * @sig: signal number * @group: signal to process group or not (bool) * @info: pointer to struct siginfo * * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo * queue is overflow. * 'group' is not 0 if the signal will be sent to a process group. * 'sig' is always one of non-RT signals. */ DEFINE_EVENT(signal_queue_overflow, signal_lose_info, TP_PROTO(int sig, int group, struct siginfo *info), TP_ARGS(sig, group, info) ); #endif /* _TRACE_SIGNAL_H */ /* This part must be outside protection */ Loading kernel/signal.c +19 −9 Original line number Diff line number Diff line Loading @@ -1054,13 +1054,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, struct sigpending *pending; struct sigqueue *q; int override_rlimit; trace_signal_generate(sig, info, t); int ret = 0, result; assert_spin_locked(&t->sighand->siglock); result = TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, from_ancestor_ns)) return 0; goto ret; pending = group ? &t->signal->shared_pending : &t->pending; /* Loading @@ -1068,8 +1068,11 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, * exactly one non-rt signal, so that we can get more * detailed information about the cause of the signal. */ result = TRACE_SIGNAL_ALREADY_PENDING; if (legacy_queue(pending, sig)) return 0; goto ret; result = TRACE_SIGNAL_DELIVERED; /* * fast-pathed signals for kernel-internal things like SIGSTOP * or SIGKILL. Loading Loading @@ -1127,14 +1130,15 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, * signal was rt and sent by user using something * other than kill(). */ trace_signal_overflow_fail(sig, group, info); return -EAGAIN; result = TRACE_SIGNAL_OVERFLOW_FAIL; ret = -EAGAIN; goto ret; } else { /* * This is a silent loss of information. We still * send the signal, but the *info bits are lost. */ trace_signal_lose_info(sig, group, info); result = TRACE_SIGNAL_LOSE_INFO; } } Loading @@ -1142,7 +1146,9 @@ out_set: signalfd_notify(t, sig); sigaddset(&pending->signal, sig); complete_signal(sig, t, group); return 0; ret: trace_signal_generate(sig, info, t, group, result); return ret; } static int send_signal(int sig, struct siginfo *info, struct task_struct *t, Loading Loading @@ -1585,7 +1591,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) int sig = q->info.si_signo; struct sigpending *pending; unsigned long flags; int ret; int ret, result; BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); Loading @@ -1594,6 +1600,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) goto ret; ret = 1; /* the signal is ignored */ result = TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, 0)) goto out; Loading @@ -1605,6 +1612,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) */ BUG_ON(q->info.si_code != SI_TIMER); q->info.si_overrun++; result = TRACE_SIGNAL_ALREADY_PENDING; goto out; } q->info.si_overrun = 0; Loading @@ -1614,7 +1622,9 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) list_add_tail(&q->list, &pending->list); sigaddset(&pending->signal, sig); complete_signal(sig, t, group); result = TRACE_SIGNAL_DELIVERED; out: trace_signal_generate(sig, &q->info, t, group, result); unlock_task_sighand(t, &flags); ret: return ret; Loading Loading
include/trace/events/signal.h +22 −63 Original line number Diff line number Diff line Loading @@ -23,11 +23,23 @@ } \ } while (0) #ifndef TRACE_HEADER_MULTI_READ enum { TRACE_SIGNAL_DELIVERED, TRACE_SIGNAL_IGNORED, TRACE_SIGNAL_ALREADY_PENDING, TRACE_SIGNAL_OVERFLOW_FAIL, TRACE_SIGNAL_LOSE_INFO, }; #endif /** * signal_generate - called when a signal is generated * @sig: signal number * @info: pointer to struct siginfo * @task: pointer to struct task_struct * @group: shared or private * @result: TRACE_SIGNAL_* * * Current process sends a 'sig' signal to 'task' process with * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV, Loading @@ -37,9 +49,10 @@ */ TRACE_EVENT(signal_generate, TP_PROTO(int sig, struct siginfo *info, struct task_struct *task), TP_PROTO(int sig, struct siginfo *info, struct task_struct *task, int group, int result), TP_ARGS(sig, info, task), TP_ARGS(sig, info, task, group, result), TP_STRUCT__entry( __field( int, sig ) Loading @@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate, __field( int, code ) __array( char, comm, TASK_COMM_LEN ) __field( pid_t, pid ) __field( int, group ) __field( int, result ) ), TP_fast_assign( Loading @@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate, TP_STORE_SIGINFO(__entry, info); memcpy(__entry->comm, task->comm, TASK_COMM_LEN); __entry->pid = task->pid; __entry->group = group; __entry->result = result; ), TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d", TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d", __entry->sig, __entry->errno, __entry->code, __entry->comm, __entry->pid) __entry->comm, __entry->pid, __entry->group, __entry->result) ); /** Loading Loading @@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver, __entry->sa_handler, __entry->sa_flags) ); DECLARE_EVENT_CLASS(signal_queue_overflow, TP_PROTO(int sig, int group, struct siginfo *info), TP_ARGS(sig, group, info), TP_STRUCT__entry( __field( int, sig ) __field( int, group ) __field( int, errno ) __field( int, code ) ), TP_fast_assign( __entry->sig = sig; __entry->group = group; TP_STORE_SIGINFO(__entry, info); ), TP_printk("sig=%d group=%d errno=%d code=%d", __entry->sig, __entry->group, __entry->errno, __entry->code) ); /** * signal_overflow_fail - called when signal queue is overflow * @sig: signal number * @group: signal to process group or not (bool) * @info: pointer to struct siginfo * * Kernel fails to generate 'sig' signal with 'info' siginfo, because * siginfo queue is overflow, and the signal is dropped. * 'group' is not 0 if the signal will be sent to a process group. * 'sig' is always one of RT signals. */ DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail, TP_PROTO(int sig, int group, struct siginfo *info), TP_ARGS(sig, group, info) ); /** * signal_lose_info - called when siginfo is lost * @sig: signal number * @group: signal to process group or not (bool) * @info: pointer to struct siginfo * * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo * queue is overflow. * 'group' is not 0 if the signal will be sent to a process group. * 'sig' is always one of non-RT signals. */ DEFINE_EVENT(signal_queue_overflow, signal_lose_info, TP_PROTO(int sig, int group, struct siginfo *info), TP_ARGS(sig, group, info) ); #endif /* _TRACE_SIGNAL_H */ /* This part must be outside protection */ Loading
kernel/signal.c +19 −9 Original line number Diff line number Diff line Loading @@ -1054,13 +1054,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, struct sigpending *pending; struct sigqueue *q; int override_rlimit; trace_signal_generate(sig, info, t); int ret = 0, result; assert_spin_locked(&t->sighand->siglock); result = TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, from_ancestor_ns)) return 0; goto ret; pending = group ? &t->signal->shared_pending : &t->pending; /* Loading @@ -1068,8 +1068,11 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, * exactly one non-rt signal, so that we can get more * detailed information about the cause of the signal. */ result = TRACE_SIGNAL_ALREADY_PENDING; if (legacy_queue(pending, sig)) return 0; goto ret; result = TRACE_SIGNAL_DELIVERED; /* * fast-pathed signals for kernel-internal things like SIGSTOP * or SIGKILL. Loading Loading @@ -1127,14 +1130,15 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, * signal was rt and sent by user using something * other than kill(). */ trace_signal_overflow_fail(sig, group, info); return -EAGAIN; result = TRACE_SIGNAL_OVERFLOW_FAIL; ret = -EAGAIN; goto ret; } else { /* * This is a silent loss of information. We still * send the signal, but the *info bits are lost. */ trace_signal_lose_info(sig, group, info); result = TRACE_SIGNAL_LOSE_INFO; } } Loading @@ -1142,7 +1146,9 @@ out_set: signalfd_notify(t, sig); sigaddset(&pending->signal, sig); complete_signal(sig, t, group); return 0; ret: trace_signal_generate(sig, info, t, group, result); return ret; } static int send_signal(int sig, struct siginfo *info, struct task_struct *t, Loading Loading @@ -1585,7 +1591,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) int sig = q->info.si_signo; struct sigpending *pending; unsigned long flags; int ret; int ret, result; BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); Loading @@ -1594,6 +1600,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) goto ret; ret = 1; /* the signal is ignored */ result = TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, 0)) goto out; Loading @@ -1605,6 +1612,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) */ BUG_ON(q->info.si_code != SI_TIMER); q->info.si_overrun++; result = TRACE_SIGNAL_ALREADY_PENDING; goto out; } q->info.si_overrun = 0; Loading @@ -1614,7 +1622,9 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) list_add_tail(&q->list, &pending->list); sigaddset(&pending->signal, sig); complete_signal(sig, t, group); result = TRACE_SIGNAL_DELIVERED; out: trace_signal_generate(sig, &q->info, t, group, result); unlock_task_sighand(t, &flags); ret: return ret; Loading