提交 96070c83 编写于 作者: I Ingo Molnar

Merge branch 'sigtrace' of git://github.com/utrace/linux into perf/core

...@@ -23,11 +23,23 @@ ...@@ -23,11 +23,23 @@
} \ } \
} while (0) } 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 * signal_generate - called when a signal is generated
* @sig: signal number * @sig: signal number
* @info: pointer to struct siginfo * @info: pointer to struct siginfo
* @task: pointer to struct task_struct * @task: pointer to struct task_struct
* @group: shared or private
* @result: TRACE_SIGNAL_*
* *
* Current process sends a 'sig' signal to 'task' process with * Current process sends a 'sig' signal to 'task' process with
* 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV, * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV,
...@@ -37,9 +49,10 @@ ...@@ -37,9 +49,10 @@
*/ */
TRACE_EVENT(signal_generate, 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( TP_STRUCT__entry(
__field( int, sig ) __field( int, sig )
...@@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate, ...@@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate,
__field( int, code ) __field( int, code )
__array( char, comm, TASK_COMM_LEN ) __array( char, comm, TASK_COMM_LEN )
__field( pid_t, pid ) __field( pid_t, pid )
__field( int, group )
__field( int, result )
), ),
TP_fast_assign( TP_fast_assign(
...@@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate, ...@@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate,
TP_STORE_SIGINFO(__entry, info); TP_STORE_SIGINFO(__entry, info);
memcpy(__entry->comm, task->comm, TASK_COMM_LEN); memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
__entry->pid = task->pid; __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->sig, __entry->errno, __entry->code,
__entry->comm, __entry->pid) __entry->comm, __entry->pid, __entry->group,
__entry->result)
); );
/** /**
...@@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver, ...@@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver,
__entry->sa_handler, __entry->sa_flags) __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 */ #endif /* _TRACE_SIGNAL_H */
/* This part must be outside protection */ /* This part must be outside protection */
......
...@@ -1054,13 +1054,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, ...@@ -1054,13 +1054,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
struct sigpending *pending; struct sigpending *pending;
struct sigqueue *q; struct sigqueue *q;
int override_rlimit; int override_rlimit;
int ret = 0, result;
trace_signal_generate(sig, info, t);
assert_spin_locked(&t->sighand->siglock); assert_spin_locked(&t->sighand->siglock);
result = TRACE_SIGNAL_IGNORED;
if (!prepare_signal(sig, t, from_ancestor_ns)) if (!prepare_signal(sig, t, from_ancestor_ns))
return 0; goto ret;
pending = group ? &t->signal->shared_pending : &t->pending; pending = group ? &t->signal->shared_pending : &t->pending;
/* /*
...@@ -1068,8 +1068,11 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, ...@@ -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 * exactly one non-rt signal, so that we can get more
* detailed information about the cause of the signal. * detailed information about the cause of the signal.
*/ */
result = TRACE_SIGNAL_ALREADY_PENDING;
if (legacy_queue(pending, sig)) if (legacy_queue(pending, sig))
return 0; goto ret;
result = TRACE_SIGNAL_DELIVERED;
/* /*
* fast-pathed signals for kernel-internal things like SIGSTOP * fast-pathed signals for kernel-internal things like SIGSTOP
* or SIGKILL. * or SIGKILL.
...@@ -1127,14 +1130,15 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, ...@@ -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 * signal was rt and sent by user using something
* other than kill(). * other than kill().
*/ */
trace_signal_overflow_fail(sig, group, info); result = TRACE_SIGNAL_OVERFLOW_FAIL;
return -EAGAIN; ret = -EAGAIN;
goto ret;
} else { } else {
/* /*
* This is a silent loss of information. We still * This is a silent loss of information. We still
* send the signal, but the *info bits are lost. * send the signal, but the *info bits are lost.
*/ */
trace_signal_lose_info(sig, group, info); result = TRACE_SIGNAL_LOSE_INFO;
} }
} }
...@@ -1142,7 +1146,9 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, ...@@ -1142,7 +1146,9 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
signalfd_notify(t, sig); signalfd_notify(t, sig);
sigaddset(&pending->signal, sig); sigaddset(&pending->signal, sig);
complete_signal(sig, t, group); 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, static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
...@@ -1585,7 +1591,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) ...@@ -1585,7 +1591,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
int sig = q->info.si_signo; int sig = q->info.si_signo;
struct sigpending *pending; struct sigpending *pending;
unsigned long flags; unsigned long flags;
int ret; int ret, result;
BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
...@@ -1594,6 +1600,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) ...@@ -1594,6 +1600,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
goto ret; goto ret;
ret = 1; /* the signal is ignored */ ret = 1; /* the signal is ignored */
result = TRACE_SIGNAL_IGNORED;
if (!prepare_signal(sig, t, 0)) if (!prepare_signal(sig, t, 0))
goto out; goto out;
...@@ -1605,6 +1612,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) ...@@ -1605,6 +1612,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
*/ */
BUG_ON(q->info.si_code != SI_TIMER); BUG_ON(q->info.si_code != SI_TIMER);
q->info.si_overrun++; q->info.si_overrun++;
result = TRACE_SIGNAL_ALREADY_PENDING;
goto out; goto out;
} }
q->info.si_overrun = 0; q->info.si_overrun = 0;
...@@ -1614,7 +1622,9 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group) ...@@ -1614,7 +1622,9 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
list_add_tail(&q->list, &pending->list); list_add_tail(&q->list, &pending->list);
sigaddset(&pending->signal, sig); sigaddset(&pending->signal, sig);
complete_signal(sig, t, group); complete_signal(sig, t, group);
result = TRACE_SIGNAL_DELIVERED;
out: out:
trace_signal_generate(sig, &q->info, t, group, result);
unlock_task_sighand(t, &flags); unlock_task_sighand(t, &flags);
ret: ret:
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册