Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96070c83 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

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

parents 87f71ae2 163566f6
Loading
Loading
Loading
Loading
+22 −63
Original line number Diff line number Diff line
@@ -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,
@@ -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			)
@@ -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(
@@ -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)
);

/**
@@ -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 */
+19 −9
Original line number Diff line number Diff line
@@ -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;
	/*
@@ -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.
@@ -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;
		}
	}

@@ -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,
@@ -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));

@@ -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;

@@ -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;
@@ -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;