git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mm/mempolicy.c: avoid use uninitialized preferred_node
[pandora-kernel.git]
/
kernel
/
signal.c
diff --git
a/kernel/signal.c
b/kernel/signal.c
index
389b366
..
0b864fc
100644
(file)
--- a/
kernel/signal.c
+++ b/
kernel/signal.c
@@
-481,6
+481,9
@@
flush_signal_handlers(struct task_struct *t, int force_default)
if (force_default || ka->sa.sa_handler != SIG_IGN)
ka->sa.sa_handler = SIG_DFL;
ka->sa.sa_flags = 0;
if (force_default || ka->sa.sa_handler != SIG_IGN)
ka->sa.sa_handler = SIG_DFL;
ka->sa.sa_flags = 0;
+#ifdef __ARCH_HAS_SA_RESTORER
+ ka->sa.sa_restorer = NULL;
+#endif
sigemptyset(&ka->sa.sa_mask);
ka++;
}
sigemptyset(&ka->sa.sa_mask);
ka++;
}
@@
-532,7
+535,8
@@
unblock_all_signals(void)
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
}
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
}
-static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static void collect_signal(int sig, struct sigpending *list, siginfo_t *info,
+ bool *resched_timer)
{
struct sigqueue *q, *first = NULL;
{
struct sigqueue *q, *first = NULL;
@@
-554,6
+558,12
@@
static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
still_pending:
list_del_init(&first->list);
copy_siginfo(info, &first->info);
still_pending:
list_del_init(&first->list);
copy_siginfo(info, &first->info);
+
+ *resched_timer =
+ (first->flags & SIGQUEUE_PREALLOC) &&
+ (info->si_code == SI_TIMER) &&
+ (info->si_sys_private);
+
__sigqueue_free(first);
} else {
/*
__sigqueue_free(first);
} else {
/*
@@
-570,7
+580,7
@@
still_pending:
}
static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
}
static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
- siginfo_t *info)
+ siginfo_t *info
, bool *resched_timer
)
{
int sig = next_signal(pending, mask);
{
int sig = next_signal(pending, mask);
@@
-584,7
+594,7
@@
static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
}
}
}
}
- collect_signal(sig, pending, info);
+ collect_signal(sig, pending, info
, resched_timer
);
}
return sig;
}
return sig;
@@
-598,15
+608,16
@@
static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
*/
int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
{
*/
int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
{
+ bool resched_timer = false;
int signr;
/* We only dequeue private signals from ourselves, we don't let
* signalfd steal them
*/
int signr;
/* We only dequeue private signals from ourselves, we don't let
* signalfd steal them
*/
- signr = __dequeue_signal(&tsk->pending, mask, info);
+ signr = __dequeue_signal(&tsk->pending, mask, info
, &resched_timer
);
if (!signr) {
signr = __dequeue_signal(&tsk->signal->shared_pending,
if (!signr) {
signr = __dequeue_signal(&tsk->signal->shared_pending,
- mask, info);
+ mask, info
, &resched_timer
);
/*
* itimer signal ?
*
/*
* itimer signal ?
*
@@
-651,7
+662,7
@@
int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
*/
current->jobctl |= JOBCTL_STOP_DEQUEUED;
}
*/
current->jobctl |= JOBCTL_STOP_DEQUEUED;
}
- if (
(info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private
) {
+ if (
resched_timer
) {
/*
* Release the siglock to ensure proper locking order
* of timer locks outside of siglocks. Note, we leave
/*
* Release the siglock to ensure proper locking order
* of timer locks outside of siglocks. Note, we leave
@@
-1759,6
+1770,10
@@
static inline int may_ptrace_stop(void)
* If SIGKILL was already sent before the caller unlocked
* ->siglock we must see ->core_state != NULL. Otherwise it
* is safe to enter schedule().
* If SIGKILL was already sent before the caller unlocked
* ->siglock we must see ->core_state != NULL. Otherwise it
* is safe to enter schedule().
+ *
+ * This is almost outdated, a task with the pending SIGKILL can't
+ * block in TASK_TRACED. But PTRACE_EVENT_EXIT can be reported
+ * after SIGKILL was already dequeued.
*/
if (unlikely(current->mm->core_state) &&
unlikely(current->mm == current->parent->mm))
*/
if (unlikely(current->mm->core_state) &&
unlikely(current->mm == current->parent->mm))
@@
-1884,6
+1899,7
@@
static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info)
if (gstop_done)
do_notify_parent_cldstop(current, false, why);
if (gstop_done)
do_notify_parent_cldstop(current, false, why);
+ /* tasklist protects us from ptrace_freeze_traced() */
__set_current_state(TASK_RUNNING);
if (clear_code)
current->exit_code = 0;
__set_current_state(TASK_RUNNING);
if (clear_code)
current->exit_code = 0;
@@
-2782,7
+2798,7
@@
do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
static int do_tkill(pid_t tgid, pid_t pid, int sig)
{
static int do_tkill(pid_t tgid, pid_t pid, int sig)
{
- struct siginfo info;
+ struct siginfo info
= {}
;
info.si_signo = sig;
info.si_errno = 0;
info.si_signo = sig;
info.si_errno = 0;