All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Eric Sandeen <sandeen@sandeen.net>,
	Linux Kernel <linux-kernel@vger.kernel.org>,
	xfs@oss.sgi.com, Dave Jones <davej@redhat.com>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: 3.14-rc2 XFS backtrace because irqs_disabled.
Date: Mon, 17 Feb 2014 17:57:35 +0100	[thread overview]
Message-ID: <20140217165735.GA29173@redhat.com> (raw)
In-Reply-To: <20140215184531.GA27314@redhat.com>

On 02/15, Oleg Nesterov wrote:
>
> On 02/15, Al Viro wrote:
> >
> > On Sat, Feb 15, 2014 at 06:43:45PM +0100, Oleg Nesterov wrote:
> > > > So basically we want a different condition for "can we just go ahead and
> > > > free that sucker", right?  Instead of "it's on the list, shan't free it"
> > > > it ought to be something like "it's on the list or it is referenced by
> > > > ksiginfo".  Locking will be interesting, though... ;-/
> > >
> > > I guess yes... send_sigqueue() checks list_empty() too, probably nobody else.
> >
> > The trouble being, we might end up with
> > 	Q picked by collect_signal and and stuff into ksiginfo
> > 	Q resubmitted by timer code
>
> In this case the timer code should simply inc ->si_overrun and do nothing.
>
> IOW, list_empty() should be turned into is_queued(), and is_queued()
> should be true until dismiss_siginfo() which should also do
> do_schedule_next_timer(). I think.

No, this is even more complicated. We also need do_schedule_next_timer()
to calculate ->si_overrun we are going to report, I missed this...

Looks like, this is all is really nasty. Actually, I think siginfo on
stack is not that bad if we are going to do handle_signal() or restart,
perhaps we can do the extra kmalloc/memcpy/kfree for do_coredump().
Something like below.

Oleg.


diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 9e5de68..52f16f9 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -684,6 +684,52 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
 #endif /* CONFIG_X86_32 */
 
+static noinline int process_signal(struct pt_regs *regs, siginfo_t **pinfo)
+{
+	struct ksignal ksig;
+
+	switch (get_signal(&ksig)) {
+	case SIG_DUMP:
+		*pinfo = kmalloc(sizeof(siginfo_t), GFP_KERNEL);
+		if (*pinfo)
+			copy_siginfo(*pinfo, &ksig.info);
+
+	case SIG_EXIT:
+		return ksig.info.si_signo;
+
+	default:
+		handle_signal(&ksig, regs);
+		break;
+
+	case 0:
+		/* Did we come from a system call? */
+		if (syscall_get_nr(current, regs) >= 0) {
+			/* Restart the system call - no handlers present */
+			switch (syscall_get_error(current, regs)) {
+			case -ERESTARTNOHAND:
+			case -ERESTARTSYS:
+			case -ERESTARTNOINTR:
+				regs->ax = regs->orig_ax;
+				regs->ip -= 2;
+				break;
+
+			case -ERESTART_RESTARTBLOCK:
+				regs->ax = NR_restart_syscall;
+				regs->ip -= 2;
+				break;
+			}
+		}
+
+		/*
+		 * If there's no signal to deliver, we just put the saved sigmask
+		 * back.
+		 */
+		restore_saved_sigmask();
+	}
+
+	return 0;
+}
+
 /*
  * Note that 'init' is a special process: it doesn't get signals it doesn't
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -691,37 +737,16 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
  */
 static void do_signal(struct pt_regs *regs)
 {
-	struct ksignal ksig;
+	siginfo_t *info = NULL;
+	int sig = process_signal(regs, &info);
 
-	if (get_signal(&ksig)) {
-		/* Whee! Actually deliver the signal.  */
-		handle_signal(&ksig, regs);
-		return;
-	}
-
-	/* Did we come from a system call? */
-	if (syscall_get_nr(current, regs) >= 0) {
-		/* Restart the system call - no handlers present */
-		switch (syscall_get_error(current, regs)) {
-		case -ERESTARTNOHAND:
-		case -ERESTARTSYS:
-		case -ERESTARTNOINTR:
-			regs->ax = regs->orig_ax;
-			regs->ip -= 2;
-			break;
-
-		case -ERESTART_RESTARTBLOCK:
-			regs->ax = NR_restart_syscall;
-			regs->ip -= 2;
-			break;
+	if (sig) {
+		if (info) {
+			do_coredump(info);
+			kfree(info);
 		}
+		do_group_exit(sig);
 	}
-
-	/*
-	 * If there's no signal to deliver, we just put the saved sigmask
-	 * back.
-	 */
-	restore_saved_sigmask();
 }
 
 /*
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 2ac423b..33b5e04 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -285,6 +285,9 @@ struct ksignal {
 	int sig;
 };
 
+#define SIG_EXIT	-1
+#define SIG_DUMP	-2
+
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
 extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
 extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
@@ -299,7 +302,7 @@ extern void exit_signals(struct task_struct *tsk);
 	struct ksignal *p = (ksig);				\
 	p->sig = get_signal_to_deliver(&p->info, &p->ka,	\
 					signal_pt_regs(), NULL);\
-	p->sig > 0;						\
+	p->sig;							\
 })
 
 extern struct kmem_cache *sighand_cachep;
diff --git a/kernel/signal.c b/kernel/signal.c
index 52f881d..8a4c4a3 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2353,22 +2353,11 @@ relock:
 			if (print_fatal_signals)
 				print_fatal_signal(info->si_signo);
 			proc_coredump_connector(current);
-			/*
-			 * If it was able to dump core, this kills all
-			 * other threads in the group and synchronizes with
-			 * their demise.  If we lost the race with another
-			 * thread getting here, it set group_exit_code
-			 * first and our do_group_exit call below will use
-			 * that value and ignore the one we pass it.
-			 */
-			do_coredump(info);
+			return SIG_DUMP;
 		}
 
-		/*
-		 * Death signals, no core dump.
-		 */
-		do_group_exit(info->si_signo);
-		/* NOTREACHED */
+		return SIG_EXIT;
+
 	}
 	spin_unlock_irq(&sighand->siglock);
 	return signr;

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

WARNING: multiple messages have this Message-ID (diff)
From: Oleg Nesterov <oleg@redhat.com>
To: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Dave Chinner <david@fromorbit.com>, Dave Jones <davej@redhat.com>,
	Eric Sandeen <sandeen@sandeen.net>,
	Linux Kernel <linux-kernel@vger.kernel.org>,
	xfs@oss.sgi.com
Subject: Re: 3.14-rc2 XFS backtrace because irqs_disabled.
Date: Mon, 17 Feb 2014 17:57:35 +0100	[thread overview]
Message-ID: <20140217165735.GA29173@redhat.com> (raw)
In-Reply-To: <20140215184531.GA27314@redhat.com>

On 02/15, Oleg Nesterov wrote:
>
> On 02/15, Al Viro wrote:
> >
> > On Sat, Feb 15, 2014 at 06:43:45PM +0100, Oleg Nesterov wrote:
> > > > So basically we want a different condition for "can we just go ahead and
> > > > free that sucker", right?  Instead of "it's on the list, shan't free it"
> > > > it ought to be something like "it's on the list or it is referenced by
> > > > ksiginfo".  Locking will be interesting, though... ;-/
> > >
> > > I guess yes... send_sigqueue() checks list_empty() too, probably nobody else.
> >
> > The trouble being, we might end up with
> > 	Q picked by collect_signal and and stuff into ksiginfo
> > 	Q resubmitted by timer code
>
> In this case the timer code should simply inc ->si_overrun and do nothing.
>
> IOW, list_empty() should be turned into is_queued(), and is_queued()
> should be true until dismiss_siginfo() which should also do
> do_schedule_next_timer(). I think.

No, this is even more complicated. We also need do_schedule_next_timer()
to calculate ->si_overrun we are going to report, I missed this...

Looks like, this is all is really nasty. Actually, I think siginfo on
stack is not that bad if we are going to do handle_signal() or restart,
perhaps we can do the extra kmalloc/memcpy/kfree for do_coredump().
Something like below.

Oleg.


diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 9e5de68..52f16f9 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -684,6 +684,52 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
 #endif /* CONFIG_X86_32 */
 
+static noinline int process_signal(struct pt_regs *regs, siginfo_t **pinfo)
+{
+	struct ksignal ksig;
+
+	switch (get_signal(&ksig)) {
+	case SIG_DUMP:
+		*pinfo = kmalloc(sizeof(siginfo_t), GFP_KERNEL);
+		if (*pinfo)
+			copy_siginfo(*pinfo, &ksig.info);
+
+	case SIG_EXIT:
+		return ksig.info.si_signo;
+
+	default:
+		handle_signal(&ksig, regs);
+		break;
+
+	case 0:
+		/* Did we come from a system call? */
+		if (syscall_get_nr(current, regs) >= 0) {
+			/* Restart the system call - no handlers present */
+			switch (syscall_get_error(current, regs)) {
+			case -ERESTARTNOHAND:
+			case -ERESTARTSYS:
+			case -ERESTARTNOINTR:
+				regs->ax = regs->orig_ax;
+				regs->ip -= 2;
+				break;
+
+			case -ERESTART_RESTARTBLOCK:
+				regs->ax = NR_restart_syscall;
+				regs->ip -= 2;
+				break;
+			}
+		}
+
+		/*
+		 * If there's no signal to deliver, we just put the saved sigmask
+		 * back.
+		 */
+		restore_saved_sigmask();
+	}
+
+	return 0;
+}
+
 /*
  * Note that 'init' is a special process: it doesn't get signals it doesn't
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -691,37 +737,16 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
  */
 static void do_signal(struct pt_regs *regs)
 {
-	struct ksignal ksig;
+	siginfo_t *info = NULL;
+	int sig = process_signal(regs, &info);
 
-	if (get_signal(&ksig)) {
-		/* Whee! Actually deliver the signal.  */
-		handle_signal(&ksig, regs);
-		return;
-	}
-
-	/* Did we come from a system call? */
-	if (syscall_get_nr(current, regs) >= 0) {
-		/* Restart the system call - no handlers present */
-		switch (syscall_get_error(current, regs)) {
-		case -ERESTARTNOHAND:
-		case -ERESTARTSYS:
-		case -ERESTARTNOINTR:
-			regs->ax = regs->orig_ax;
-			regs->ip -= 2;
-			break;
-
-		case -ERESTART_RESTARTBLOCK:
-			regs->ax = NR_restart_syscall;
-			regs->ip -= 2;
-			break;
+	if (sig) {
+		if (info) {
+			do_coredump(info);
+			kfree(info);
 		}
+		do_group_exit(sig);
 	}
-
-	/*
-	 * If there's no signal to deliver, we just put the saved sigmask
-	 * back.
-	 */
-	restore_saved_sigmask();
 }
 
 /*
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 2ac423b..33b5e04 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -285,6 +285,9 @@ struct ksignal {
 	int sig;
 };
 
+#define SIG_EXIT	-1
+#define SIG_DUMP	-2
+
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
 extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
 extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
@@ -299,7 +302,7 @@ extern void exit_signals(struct task_struct *tsk);
 	struct ksignal *p = (ksig);				\
 	p->sig = get_signal_to_deliver(&p->info, &p->ka,	\
 					signal_pt_regs(), NULL);\
-	p->sig > 0;						\
+	p->sig;							\
 })
 
 extern struct kmem_cache *sighand_cachep;
diff --git a/kernel/signal.c b/kernel/signal.c
index 52f881d..8a4c4a3 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2353,22 +2353,11 @@ relock:
 			if (print_fatal_signals)
 				print_fatal_signal(info->si_signo);
 			proc_coredump_connector(current);
-			/*
-			 * If it was able to dump core, this kills all
-			 * other threads in the group and synchronizes with
-			 * their demise.  If we lost the race with another
-			 * thread getting here, it set group_exit_code
-			 * first and our do_group_exit call below will use
-			 * that value and ignore the one we pass it.
-			 */
-			do_coredump(info);
+			return SIG_DUMP;
 		}
 
-		/*
-		 * Death signals, no core dump.
-		 */
-		do_group_exit(info->si_signo);
-		/* NOTREACHED */
+		return SIG_EXIT;
+
 	}
 	spin_unlock_irq(&sighand->siglock);
 	return signr;


  reply	other threads:[~2014-02-17 16:57 UTC|newest]

Thread overview: 132+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-11 17:27 3.14-rc2 XFS backtrace because irqs_disabled Dave Jones
2014-02-11 17:27 ` Dave Jones
2014-02-11 21:08 ` Dave Chinner
2014-02-11 21:08   ` Dave Chinner
2014-02-11 21:49   ` Eric Sandeen
2014-02-11 21:49     ` Eric Sandeen
2014-02-12  0:44     ` Dave Jones
2014-02-12  0:44       ` Dave Jones
2014-02-12  1:09       ` Al Viro
2014-02-12  1:09         ` Al Viro
2014-02-12  2:52         ` Linus Torvalds
2014-02-12  2:52           ` Linus Torvalds
2014-02-12  4:03           ` Dave Jones
2014-02-12  4:03             ` Dave Jones
2014-02-12  4:22             ` Al Viro
2014-02-12  4:22               ` Al Viro
2014-02-12  5:40               ` Dave Chinner
2014-02-12  5:40                 ` Dave Chinner
2014-02-12  5:50                 ` Dave Jones
2014-02-12  5:50                   ` Dave Jones
2014-02-12  6:10                   ` Dave Chinner
2014-02-12  6:10                     ` Dave Chinner
2014-02-12  6:31                     ` Dave Chinner
2014-02-12  6:31                       ` Dave Chinner
2014-02-12  6:59                       ` Linus Torvalds
2014-02-12  6:59                         ` Linus Torvalds
2014-02-12  8:13                         ` Tejun Heo
2014-02-12  8:13                           ` Tejun Heo
2014-02-12 12:44                           ` Steven Rostedt
2014-02-12 12:44                             ` Steven Rostedt
2014-02-12  8:35                         ` Dave Chinner
2014-02-12  8:35                           ` Dave Chinner
2014-02-12 12:50                           ` Steven Rostedt
2014-02-12 12:50                             ` Steven Rostedt
2014-02-12 12:40                         ` Steven Rostedt
2014-02-12 12:40                           ` Steven Rostedt
2014-02-12 13:29                           ` Peter Zijlstra
2014-02-12 13:29                             ` Peter Zijlstra
2014-02-12 14:25                     ` Dave Jones
2014-02-12 14:25                       ` Dave Jones
2014-02-12 21:14                       ` Dave Chinner
2014-02-12 21:14                         ` Dave Chinner
2014-02-12 15:57                     ` Eric Sandeen
2014-02-12 15:57                       ` Eric Sandeen
2014-02-12  6:28                 ` Linus Torvalds
2014-02-12  6:28                   ` Linus Torvalds
2014-02-12  7:18                   ` Dave Chinner
2014-02-12  7:18                     ` Dave Chinner
2014-02-14  0:24                     ` Dave Chinner
2014-02-14  0:24                       ` Dave Chinner
2014-02-14 16:01                       ` Dave Jones
2014-02-14 16:01                         ` Dave Jones
2014-02-15 22:23                         ` Dave Chinner
2014-02-15 22:23                           ` Dave Chinner
2014-02-15 22:28                           ` Dave Jones
2014-02-15 22:28                             ` Dave Jones
2014-02-15 22:43                             ` Linus Torvalds
2014-02-15 22:43                               ` Linus Torvalds
2014-02-15 23:50                       ` Linus Torvalds
2014-02-15 23:50                         ` Linus Torvalds
2014-02-15 23:50                         ` Linus Torvalds
2014-02-18  1:27                         ` Dave Chinner
2014-02-18  1:27                           ` Dave Chinner
2014-02-18  1:27                           ` Dave Chinner
2014-02-12 11:39                   ` Al Viro
2014-02-12 11:39                     ` Al Viro
2014-02-12 20:13                     ` Linus Torvalds
2014-02-12 20:13                       ` Linus Torvalds
2014-02-12 21:14                       ` Al Viro
2014-02-12 21:14                         ` Al Viro
2014-02-12 21:32                         ` Linus Torvalds
2014-02-12 21:32                           ` Linus Torvalds
2014-02-12 21:44                           ` Al Viro
2014-02-12 21:44                             ` Al Viro
2014-02-13 20:51                             ` Al Viro
2014-02-13 20:51                               ` Al Viro
2014-02-14  0:09                               ` Al Viro
2014-02-14  0:09                                 ` Al Viro
2014-02-14 13:25                               ` Christoph Hellwig
2014-02-14 13:25                                 ` Christoph Hellwig
2014-02-14 13:29                                 ` Richard Weinberger
2014-02-14 13:29                                   ` Richard Weinberger
2014-02-14 15:20                                   ` Al Viro
2014-02-14 15:20                                     ` Al Viro
2014-02-14 16:08                                     ` Oleg Nesterov
2014-02-14 16:08                                       ` Oleg Nesterov
2014-02-13 17:40                           ` Oleg Nesterov
2014-02-13 17:40                             ` Oleg Nesterov
2014-02-13 17:58                             ` Linus Torvalds
2014-02-13 17:58                               ` Linus Torvalds
2014-02-13 18:10                               ` Oleg Nesterov
2014-02-13 18:10                                 ` Oleg Nesterov
2014-02-13 18:37                                 ` Oleg Nesterov
2014-02-13 18:37                                   ` Oleg Nesterov
2014-02-15  5:25                               ` Al Viro
2014-02-15  5:25                                 ` Al Viro
2014-02-15 14:27                                 ` Oleg Nesterov
2014-02-15 14:27                                   ` Oleg Nesterov
2014-02-15 15:22                                   ` Al Viro
2014-02-15 15:22                                     ` Al Viro
2014-02-15 15:33                                     ` Oleg Nesterov
2014-02-15 15:33                                       ` Oleg Nesterov
2014-02-15 15:36                                     ` Al Viro
2014-02-15 15:36                                       ` Al Viro
2014-02-15 15:58                                       ` Al Viro
2014-02-15 15:58                                         ` Al Viro
2014-02-15 16:59                                         ` Al Viro
2014-02-15 16:59                                           ` Al Viro
2014-02-15 17:43                                         ` Oleg Nesterov
2014-02-15 17:43                                           ` Oleg Nesterov
2014-02-15 18:05                                           ` Al Viro
2014-02-15 18:05                                             ` Al Viro
2014-02-15 18:45                                             ` Oleg Nesterov
2014-02-15 18:45                                               ` Oleg Nesterov
2014-02-17 16:57                                               ` Oleg Nesterov [this message]
2014-02-17 16:57                                                 ` Oleg Nesterov
2014-02-17 17:40                                                 ` Al Viro
2014-02-17 17:40                                                   ` Al Viro
2014-02-17 17:46                                                   ` Oleg Nesterov
2014-02-17 17:46                                                     ` Oleg Nesterov
2014-02-17 17:54                                                     ` Al Viro
2014-02-17 17:54                                                       ` Al Viro
2014-02-14 16:13                           ` Christoph Hellwig
2014-02-14 16:13                             ` Christoph Hellwig
2014-02-14 16:16                             ` Al Viro
2014-02-14 16:16                               ` Al Viro
2014-02-14 16:18                               ` Al Viro
2014-02-14 16:18                                 ` Al Viro
2014-02-14 16:19                               ` Christoph Hellwig
2014-02-14 16:19                                 ` Christoph Hellwig
2014-02-15 14:46                                 ` Oleg Nesterov
2014-02-15 14:46                                   ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140217165735.GA29173@redhat.com \
    --to=oleg@redhat.com \
    --cc=davej@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sandeen@sandeen.net \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@ZenIV.linux.org.uk \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.