mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
signals: kill block_all_signals() and unblock_all_signals()
It is hardly possible to enumerate all problems with block_all_signals() and unblock_all_signals(). Just for example, 1. block_all_signals(SIGSTOP/etc) simply can't help if the caller is multithreaded. Another thread can dequeue the signal and force the group stop. 2. Even is the caller is single-threaded, it will "stop" anyway. It will not sleep, but it will spin in kernel space until SIGCONT or SIGKILL. And a lot more. In short, this interface doesn't work at all, at least the last 10+ years. Daniel said: Yeah the only times I played around with the DRM_LOCK stuff was when old drivers accidentally deadlocked - my impression is that the entire DRM_LOCK thing was never really tested properly ;-) Hence I'm all for purging where this leaks out of the drm subsystem. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Acked-by: Dave Airlie <airlied@redhat.com> Cc: Richard Weinberger <richard@nod.at> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
4f05028f8d
commit
2e01fabe67
4 changed files with 2 additions and 98 deletions
|
@ -503,41 +503,6 @@ int unhandled_signal(struct task_struct *tsk, int sig)
|
|||
return !tsk->ptrace;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the system that a driver wants to block all signals for this
|
||||
* process, and wants to be notified if any signals at all were to be
|
||||
* sent/acted upon. If the notifier routine returns non-zero, then the
|
||||
* signal will be acted upon after all. If the notifier routine returns 0,
|
||||
* then then signal will be blocked. Only one block per process is
|
||||
* allowed. priv is a pointer to private data that the notifier routine
|
||||
* can use to determine if the signal should be blocked or not.
|
||||
*/
|
||||
void
|
||||
block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
current->notifier_mask = mask;
|
||||
current->notifier_data = priv;
|
||||
current->notifier = notifier;
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
}
|
||||
|
||||
/* Notify the system that blocking has ended. */
|
||||
|
||||
void
|
||||
unblock_all_signals(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(¤t->sighand->siglock, flags);
|
||||
current->notifier = NULL;
|
||||
current->notifier_data = NULL;
|
||||
recalc_sigpending();
|
||||
spin_unlock_irqrestore(¤t->sighand->siglock, flags);
|
||||
}
|
||||
|
||||
static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
|
||||
{
|
||||
struct sigqueue *q, *first = NULL;
|
||||
|
@ -580,19 +545,8 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
|
|||
{
|
||||
int sig = next_signal(pending, mask);
|
||||
|
||||
if (sig) {
|
||||
if (current->notifier) {
|
||||
if (sigismember(current->notifier_mask, sig)) {
|
||||
if (!(current->notifier)(current->notifier_data)) {
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sig)
|
||||
collect_signal(sig, pending, info);
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
@ -2483,9 +2437,6 @@ EXPORT_SYMBOL(force_sig);
|
|||
EXPORT_SYMBOL(send_sig);
|
||||
EXPORT_SYMBOL(send_sig_info);
|
||||
EXPORT_SYMBOL(sigprocmask);
|
||||
EXPORT_SYMBOL(block_all_signals);
|
||||
EXPORT_SYMBOL(unblock_all_signals);
|
||||
|
||||
|
||||
/*
|
||||
* System call entry points.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue