From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751135AbdFAHIa (ORCPT ); Thu, 1 Jun 2017 03:08:30 -0400 Received: from out03.mta.xmission.com ([166.70.13.233]:39362 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750848AbdFAHI2 (ORCPT ); Thu, 1 Jun 2017 03:08:28 -0400 From: ebiederm@xmission.com (Eric W. Biederman) To: Thomas Gleixner Cc: LKML , Oleg Nesterov , Linus Torvalds , Peter Zijlstra , Ingo Molnar , Michael Kerrisk , linux-man@vger.kernel.org, libc-alpha@sourceware.org References: Date: Thu, 01 Jun 2017 02:01:38 -0500 In-Reply-To: (Thomas Gleixner's message of "Tue, 30 May 2017 15:21:34 +0200 (CEST)") Message-ID: <87y3tcgpil.fsf@xmission.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-XM-SPF: eid=1dGKDT-0003Fs-GY;;;mid=<87y3tcgpil.fsf@xmission.com>;;;hst=in01.mta.xmission.com;;;ip=97.121.81.159;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX18Crgtf2YYN2gqRq+l7aPiYBzpCqTLKi3U= X-SA-Exim-Connect-IP: 97.121.81.159 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 0.0 TVD_RCVD_IP Message was received from an IP address * 0.0 T_TM2_M_HEADER_IN_MSG BODY: No description available. * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa05 1397; Body=1 Fuz1=1 Fuz2=1] * 0.1 XMSolicitRefs_0 Weightloss drug X-Spam-DCC: XMission; sa05 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ;Thomas Gleixner X-Spam-Relay-Country: X-Spam-Timing: total 5656 ms - load_scoreonly_sql: 0.06 (0.0%), signal_user_changed: 3.7 (0.1%), b_tie_ro: 2.5 (0.0%), parse: 1.55 (0.0%), extract_message_metadata: 30 (0.5%), get_uri_detail_list: 5 (0.1%), tests_pri_-1000: 13 (0.2%), tests_pri_-950: 1.60 (0.0%), tests_pri_-900: 1.29 (0.0%), tests_pri_-400: 34 (0.6%), check_bayes: 32 (0.6%), b_tokenize: 13 (0.2%), b_tok_get_all: 10 (0.2%), b_comp_prob: 3.6 (0.1%), b_tok_touch_all: 3.3 (0.1%), b_finish: 0.71 (0.0%), tests_pri_0: 475 (8.4%), check_dkim_signature: 0.61 (0.0%), check_dkim_adsp: 3.1 (0.1%), tests_pri_500: 5092 (90.0%), poll_dns_idle: 5080 (89.8%), rewrite_mail: 0.00 (0.0%) Subject: Re: signals: Bug or manpage inconsistency? X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in01.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Thomas Gleixner writes: > While trying to address the longstanding FIXME in the posix timer code > related to ignored signals, I stumbled over the following issue: > > I blocked the signal of the timer, then installed the SIG_IGN handler, > created and started the timer. After a short sleep the timer has fired > several times, but it's still ignored AND blocked. > > Calling sigpending() after that has the timer signal set. See test case > below. > > But 'man sigpending' says: > > "If a signal is both blocked and has a disposition of "ignored", it is _not_ > added to the mask of pending signals when generated." > > So something is clearly wrong here. > > The same happens with sigwait() while the signal is still blocked and > ignored, it returns with that signal number and has the signal dequeued. > > > The whole blocked vs. ignored handling is inconsistent both in the posix > spec and in the kernel. > > The only thing vs. ignored signals what the spec mandates is: > > SIG_IGN: > > Delivery of the signal shall have no effect on the process. > > ... > > Setting a signal action to SIG_IGN for a signal that is pending shall > cause the pending signal to be discarded, whether or not it is blocked. > > ... > > Any queued values pending shall be discarded and the resources used to > queue them shall be released and made available to queue other signals. > > That's exactly what the kernel does in do_sigaction(). > > And for everything else the spec is blurry: > > If the action associated with a blocked signal is to ignore the signal > and if that signal is generated for the process, it is unspecified > whether the signal is discarded immediately upon generation or remains > pending. > > So the kernel has chosen to keep them pending for whatever reasons, which > does not make any sense to me, but there is probably a historic reason. > > The commit which added the queuing of blocked and ignored signals is in the > history tree with a pretty useless changelog. > > https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git > > commit 98fc8ab9e74389e0c7001052597f61336dc62833 > Author: Linus Torvalds > Date: Tue Feb 11 20:49:03 2003 -0800 > > Don't wake up processes unnecessarily for ignored signals > > It rewrites sig_ignored() and adds the following to it: > > + /* > + * Blocked signals are never ignored, since the > + * signal handler may change by the time it is > + * unblocked. > + */ > + if (sigismember(&t->blocked, sig)) > + return 0; > > I have no idea how that is related to $subject of the commit and why this > decision was made. > > Linus, any recollection? > > IMO, it's perfectly reasonable to discard ignored signals even when the > signal is in the blocked mask. When its unblocked and SIG_IGN is replaced > then the next signal will be delivered. But hell knows, how much user space > depends on this weird behaviour by now. I just looked through the history and the commit you point to looks like it was either code motion or a regression fix. The change to ignore blocked signals actually came in between 1.2 and 2.0. It looks like the relevant diff was: commit 886bad3fe1fe0c67208f15a02047e450e30f2b3a Author: Linus Torvalds Date: Mon Apr 1 16:00:00 1996 -0800 Linux version 1.3.82 diff --git a/kernel/exit.c b/kernel/exit.c index 2b8e6d13ba1f..329d0b36bb08 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -23,25 +23,28 @@ extern void kerneld_exit(void); int getrusage(struct task_struct *, int, struct rusage *); -static int generate(unsigned long sig, struct task_struct * p) +static inline void generate(unsigned long sig, struct task_struct * p) { unsigned long mask = 1 << (sig-1); struct sigaction * sa = sig + p->sig->action - 1; - /* always generate signals for traced processes ??? */ - if (!(p->flags & PF_PTRACED)) { + /* + * Optimize away the signal, if it's a signal that can + * be handled immediately (ie non-blocked and untraced) + * and that is ignored (either explicitly or by default) + */ + if (!(mask & p->blocked) && !(p->flags & PF_PTRACED)) { /* don't bother with ignored signals (but SIGCHLD is special) */ if (sa->sa_handler == SIG_IGN && sig != SIGCHLD) - return 0; + return; /* some signals are ignored by default.. (but SIGCONT already did its deed) */ if ((sa->sa_handler == SIG_DFL) && (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH || sig == SIGURG)) - return 0; + return; } p->signal |= mask; if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked)) wake_up_process(p); - return 1; } int send_sig(unsigned long sig,struct task_struct * p,int priv) Eric