diff options
author | Oleg Nesterov <oleg@redhat.com> | 2011-11-22 15:13:48 -0500 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2012-01-13 12:48:50 -0500 |
commit | 6c303d3ab39f0dc69546f179c424ee1124f50906 (patch) | |
tree | 40fd551256229f2ac1f931c3f9e650ba67deefc7 /kernel/signal.c | |
parent | 099469502f62fbe0d7e4f0b83a2f22538367f734 (diff) |
tracing: let trace_signal_generate() report more info, kill overflow_fail/lose_info
__send_signal()->trace_signal_generate() doesn't report enough info.
The users want to know was the signal actually delivered or not, and
they also need the shared/private info.
The patch moves trace_signal_generate() at the end of __send_signal()
and adds the 2 additional arguments.
This also allows us to kill trace_signal_overflow_fail/lose_info, we
can simply add the appropriate TRACE_SIGNAL_ "result" codes.
Reported-by: Seiji Aguchi <saguchi@redhat.com>
Reviewed-by: Seiji Aguchi <seiji.aguchi@hds.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index c73c4284160e..1bd9e86fda1f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1054,13 +1054,13 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1054 | struct sigpending *pending; | 1054 | struct sigpending *pending; |
1055 | struct sigqueue *q; | 1055 | struct sigqueue *q; |
1056 | int override_rlimit; | 1056 | int override_rlimit; |
1057 | 1057 | int ret = 0, result; | |
1058 | trace_signal_generate(sig, info, t); | ||
1059 | 1058 | ||
1060 | assert_spin_locked(&t->sighand->siglock); | 1059 | assert_spin_locked(&t->sighand->siglock); |
1061 | 1060 | ||
1061 | result = TRACE_SIGNAL_IGNORED; | ||
1062 | if (!prepare_signal(sig, t, from_ancestor_ns)) | 1062 | if (!prepare_signal(sig, t, from_ancestor_ns)) |
1063 | return 0; | 1063 | goto ret; |
1064 | 1064 | ||
1065 | pending = group ? &t->signal->shared_pending : &t->pending; | 1065 | pending = group ? &t->signal->shared_pending : &t->pending; |
1066 | /* | 1066 | /* |
@@ -1068,8 +1068,11 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1068 | * exactly one non-rt signal, so that we can get more | 1068 | * exactly one non-rt signal, so that we can get more |
1069 | * detailed information about the cause of the signal. | 1069 | * detailed information about the cause of the signal. |
1070 | */ | 1070 | */ |
1071 | result = TRACE_SIGNAL_ALREADY_PENDING; | ||
1071 | if (legacy_queue(pending, sig)) | 1072 | if (legacy_queue(pending, sig)) |
1072 | return 0; | 1073 | goto ret; |
1074 | |||
1075 | result = TRACE_SIGNAL_DELIVERED; | ||
1073 | /* | 1076 | /* |
1074 | * fast-pathed signals for kernel-internal things like SIGSTOP | 1077 | * fast-pathed signals for kernel-internal things like SIGSTOP |
1075 | * or SIGKILL. | 1078 | * or SIGKILL. |
@@ -1127,14 +1130,15 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1127 | * signal was rt and sent by user using something | 1130 | * signal was rt and sent by user using something |
1128 | * other than kill(). | 1131 | * other than kill(). |
1129 | */ | 1132 | */ |
1130 | trace_signal_overflow_fail(sig, group, info); | 1133 | result = TRACE_SIGNAL_OVERFLOW_FAIL; |
1131 | return -EAGAIN; | 1134 | ret = -EAGAIN; |
1135 | goto ret; | ||
1132 | } else { | 1136 | } else { |
1133 | /* | 1137 | /* |
1134 | * This is a silent loss of information. We still | 1138 | * This is a silent loss of information. We still |
1135 | * send the signal, but the *info bits are lost. | 1139 | * send the signal, but the *info bits are lost. |
1136 | */ | 1140 | */ |
1137 | trace_signal_lose_info(sig, group, info); | 1141 | result = TRACE_SIGNAL_LOSE_INFO; |
1138 | } | 1142 | } |
1139 | } | 1143 | } |
1140 | 1144 | ||
@@ -1142,7 +1146,9 @@ out_set: | |||
1142 | signalfd_notify(t, sig); | 1146 | signalfd_notify(t, sig); |
1143 | sigaddset(&pending->signal, sig); | 1147 | sigaddset(&pending->signal, sig); |
1144 | complete_signal(sig, t, group); | 1148 | complete_signal(sig, t, group); |
1145 | return 0; | 1149 | ret: |
1150 | trace_signal_generate(sig, info, t, group, result); | ||
1151 | return ret; | ||
1146 | } | 1152 | } |
1147 | 1153 | ||
1148 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | 1154 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, |