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

Commit 5a8da0ea authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds
Browse files

signals: x86 TS_RESTORE_SIGMASK



Replace TIF_RESTORE_SIGMASK with TS_RESTORE_SIGMASK and define our own
set_restore_sigmask() function.  This saves the costly SMP-safe set_bit
operation, which we do not need for the sigmask flag since TIF_SIGPENDING
always has to be set too.

Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f3de272b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	set_restore_sigmask();
	return -ERESTARTNOHAND;
}

+8 −9
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ sys_sigsuspend(int history0, int history1, old_sigset_t mask)

	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	set_restore_sigmask();

	return -ERESTARTNOHAND;
}
@@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *regs)
	if (!user_mode(regs))
		return;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;
@@ -612,13 +612,12 @@ static void do_signal(struct pt_regs *regs)
		/* Whee! Actually deliver the signal.  */
		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
			/*
			 * a signal was successfully delivered; the saved
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag
			 * clear the TS_RESTORE_SIGMASK flag.
			 */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);
			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
		}
		return;
	}
@@ -645,8 +644,8 @@ static void do_signal(struct pt_regs *regs)
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
@@ -665,7 +664,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
	}

	/* deal with pending signal delivery */
	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
	if (thread_info_flags & _TIF_SIGPENDING)
		do_signal(regs);

	if (thread_info_flags & _TIF_HRTICK_RESCHED)
+9 −7
Original line number Diff line number Diff line
@@ -427,7 +427,7 @@ static void do_signal(struct pt_regs *regs)
	if (!user_mode(regs))
		return;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
	if (current_thread_info()->status & TS_RESTORE_SIGMASK)
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;
@@ -444,11 +444,13 @@ static void do_signal(struct pt_regs *regs)

		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
			/* a signal was successfully delivered; the saved
			/*
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag */
			clear_thread_flag(TIF_RESTORE_SIGMASK);
			 * clear the TS_RESTORE_SIGMASK flag.
			 */
			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
		}
		return;
	}
@@ -476,8 +478,8 @@ static void do_signal(struct pt_regs *regs)
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
@@ -498,7 +500,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
#endif /* CONFIG_X86_MCE */

	/* deal with pending signal delivery */
	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
	if (thread_info_flags & _TIF_SIGPENDING)
		do_signal(regs);

	if (thread_info_flags & _TIF_HRTICK_RESCHED)
+11 −2
Original line number Diff line number Diff line
@@ -131,7 +131,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_EMU		5	/* syscall emulation active */
#define TIF_SYSCALL_AUDIT	6	/* syscall auditing active */
#define TIF_SECCOMP		7	/* secure computing */
#define TIF_RESTORE_SIGMASK	8	/* restore signal mask in do_signal() */
#define TIF_HRTICK_RESCHED	9	/* reprogram hrtick timer */
#define TIF_MEMDIE		16
#define TIF_DEBUG		17	/* uses debug registers */
@@ -151,7 +150,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP		(1 << TIF_SECCOMP)
#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
#define _TIF_HRTICK_RESCHED	(1 << TIF_HRTICK_RESCHED)
#define _TIF_DEBUG		(1 << TIF_DEBUG)
#define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
@@ -188,9 +186,20 @@ static inline struct thread_info *current_thread_info(void)
					   this quantum (SMP) */
#define TS_POLLING		0x0002	/* True if in idle loop
					   and not sleeping */
#define TS_RESTORE_SIGMASK	0x0004	/* restore signal mask in do_signal() */

#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)

#ifndef __ASSEMBLY__
#define HAVE_SET_RESTORE_SIGMASK	1
static inline void set_restore_sigmask(void)
{
	struct thread_info *ti = current_thread_info();
	ti->status |= TS_RESTORE_SIGMASK;
	set_bit(TIF_SIGPENDING, &ti->flags);
}
#endif	/* !__ASSEMBLY__ */

#endif /* __KERNEL__ */

#endif /* _ASM_THREAD_INFO_H */
+11 −2
Original line number Diff line number Diff line
@@ -109,7 +109,6 @@ static inline struct thread_info *stack_thread_info(void)
#define TIF_IRET		5	/* force IRET */
#define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
#define TIF_SECCOMP		8	/* secure computing */
#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal */
#define TIF_MCE_NOTIFY		10	/* notify userspace of an MCE */
#define TIF_HRTICK_RESCHED	11	/* reprogram hrtick timer */
/* 16 free */
@@ -133,7 +132,6 @@ static inline struct thread_info *stack_thread_info(void)
#define _TIF_IRET		(1 << TIF_IRET)
#define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP		(1 << TIF_SECCOMP)
#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
#define _TIF_MCE_NOTIFY		(1 << TIF_MCE_NOTIFY)
#define _TIF_HRTICK_RESCHED	(1 << TIF_HRTICK_RESCHED)
#define _TIF_IA32		(1 << TIF_IA32)
@@ -178,9 +176,20 @@ static inline struct thread_info *stack_thread_info(void)
#define TS_COMPAT		0x0002	/* 32bit syscall active */
#define TS_POLLING		0x0004	/* true if in idle loop
					   and not sleeping */
#define TS_RESTORE_SIGMASK	0x0008	/* restore signal mask in do_signal() */

#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)

#ifndef __ASSEMBLY__
#define HAVE_SET_RESTORE_SIGMASK	1
static inline void set_restore_sigmask(void)
{
	struct thread_info *ti = current_thread_info();
	ti->status |= TS_RESTORE_SIGMASK;
	set_bit(TIF_SIGPENDING, &ti->flags);
}
#endif	/* !__ASSEMBLY__ */

#endif /* __KERNEL__ */

#endif /* _ASM_THREAD_INFO_H */