All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: linux-kernel@vger.kernel.org, io-uring@vger.kernel.org
Cc: peterz@infradead.org, oleg@redhat.com, tglx@linutronix.de,
	Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 4/6] kernel: add support for TIF_NOTIFY_SIGNAL
Date: Mon,  5 Oct 2020 09:04:36 -0600	[thread overview]
Message-ID: <20201005150438.6628-5-axboe@kernel.dk> (raw)
In-Reply-To: <20201005150438.6628-1-axboe@kernel.dk>

This adds TIF_NOTIFY_SIGNAL handling in the generic code, which if set,
will return true if signal_pending() is used in a wait loop. That causes
an exit of the loop so that notify_signal tracehooks can be run. If the
wait loop is currently inside a system call, the system call is restarted
once task_work has been processed.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 include/linux/entry-common.h |  6 +++++-
 include/linux/entry-kvm.h    |  4 ++--
 include/linux/sched/signal.h | 19 +++++++++++++++++--
 include/linux/tracehook.h    | 27 +++++++++++++++++++++++++++
 kernel/entry/common.c        |  5 ++++-
 kernel/entry/kvm.c           |  3 +++
 6 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h
index ccfcc4769925..0929385b9d8d 100644
--- a/include/linux/entry-common.h
+++ b/include/linux/entry-common.h
@@ -37,6 +37,10 @@
 # define _TIF_UPROBE			(0)
 #endif
 
+#ifndef _TIF_NOTIFY_SIGNAL
+# define _TIF_NOTIFY_SIGNAL		(0)
+#endif
+
 /*
  * TIF flags handled in syscall_enter_from_usermode()
  */
@@ -69,7 +73,7 @@
 
 #define EXIT_TO_USER_MODE_WORK						\
 	(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE |		\
-	 _TIF_NEED_RESCHED | _TIF_PATCH_PENDING |			\
+	 _TIF_NEED_RESCHED | _TIF_PATCH_PENDING | _TIF_NOTIFY_SIGNAL |	\
 	 ARCH_EXIT_TO_USER_MODE_WORK)
 
 /**
diff --git a/include/linux/entry-kvm.h b/include/linux/entry-kvm.h
index 0cef17afb41a..9b93f8584ff7 100644
--- a/include/linux/entry-kvm.h
+++ b/include/linux/entry-kvm.h
@@ -11,8 +11,8 @@
 # define ARCH_XFER_TO_GUEST_MODE_WORK	(0)
 #endif
 
-#define XFER_TO_GUEST_MODE_WORK					\
-	(_TIF_NEED_RESCHED | _TIF_SIGPENDING |			\
+#define XFER_TO_GUEST_MODE_WORK						\
+	(_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL |	\
 	 _TIF_NOTIFY_RESUME | ARCH_XFER_TO_GUEST_MODE_WORK)
 
 struct kvm_vcpu;
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index e6f34d8fbf4d..3117ff205a14 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -360,6 +360,15 @@ static inline int task_sigpending(struct task_struct *p)
 
 static inline int signal_pending(struct task_struct *p)
 {
+#ifdef TIF_NOTIFY_SIGNAL
+	/*
+	 * TIF_NOTIFY_SIGNAL isn't really a signal, but it requires the same
+	 * behavior in terms of ensuring that we break out of wait loops
+	 * so that notify signal callbacks can be processed.
+	 */
+	if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL)))
+		return 1;
+#endif
 	return task_sigpending(p);
 }
 
@@ -506,10 +515,16 @@ extern int set_user_sigmask(const sigset_t __user *umask, size_t sigsetsize);
 
 static inline void restore_saved_sigmask_unless(bool interrupted)
 {
-	if (interrupted)
+	if (interrupted) {
+#ifdef TIF_NOTIFY_SIGNAL
+		WARN_ON(!test_thread_flag(TIF_SIGPENDING) &&
+			!test_thread_flag(TIF_NOTIFY_SIGNAL));
+#else
 		WARN_ON(!test_thread_flag(TIF_SIGPENDING));
-	else
+#endif
+	} else {
 		restore_saved_sigmask();
+	}
 }
 
 static inline sigset_t *sigmask_to_save(void)
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index b480e1a07ed8..bec952f51439 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -198,4 +198,31 @@ static inline void tracehook_notify_resume(struct pt_regs *regs)
 	blkcg_maybe_throttle_current();
 }
 
+/*
+ * called by exit_to_user_mode_loop() if ti_work & _TIF_NOTIFY_SIGNAL. This
+ * is currently used by TWA_SIGNAL based task_work, which requires breaking
+ * wait loops to ensure that task_work is noticed and run.
+ */
+static inline void tracehook_notify_signal(void)
+{
+#ifdef TIF_NOTIFY_SIGNAL
+	clear_thread_flag(TIF_NOTIFY_SIGNAL);
+	smp_mb__after_atomic();
+	if (current->task_works)
+		task_work_run();
+#endif
+}
+
+/*
+ * Called when we have work to process from exit_to_user_mode_loop()
+ */
+static inline void set_notify_signal(struct task_struct *task)
+{
+#ifdef TIF_NOTIFY_SIGNAL
+	if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_SIGNAL) &&
+	    !wake_up_state(task, TASK_INTERRUPTIBLE))
+		kick_process(task);
+#endif
+}
+
 #endif	/* <linux/tracehook.h> */
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index 0c0cc3cf3eba..6cf9f4fa0f6e 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -140,7 +140,7 @@ bool __weak arch_do_signal(struct pt_regs *regs) { return true; }
 static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 					    unsigned long ti_work)
 {
-	bool restart_sys = ti_work & _TIF_SIGPENDING;
+	bool restart_sys = ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL);
 
 	/*
 	 * Before returning to user space ensure that all pending work
@@ -159,6 +159,9 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 		if (ti_work & _TIF_PATCH_PENDING)
 			klp_update_patch_state(current);
 
+		if (ti_work & _TIF_NOTIFY_SIGNAL)
+			tracehook_notify_signal();
+
 		if ((ti_work & _TIF_SIGPENDING) && arch_do_signal(regs))
 			restart_sys = false;
 
diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index b6678a5e3cf6..49972ee99aff 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -8,6 +8,9 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 	do {
 		int ret;
 
+		if (ti_work & _TIF_NOTIFY_SIGNAL)
+			tracehook_notify_signal();
+
 		if (ti_work & _TIF_SIGPENDING) {
 			kvm_handle_signal_exit(vcpu);
 			return -EINTR;
-- 
2.28.0


  parent reply	other threads:[~2020-10-05 15:05 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-05 15:04 [PATCHSET RFC v3 0/6] Add support for TIF_NOTIFY_SIGNAL Jens Axboe
2020-10-05 15:04 ` [PATCH 1/6] tracehook: clear TIF_NOTIFY_RESUME in tracehook_notify_resume() Jens Axboe
2020-10-08 12:37   ` Oleg Nesterov
2020-10-08 13:36     ` Jens Axboe
2020-10-05 15:04 ` [PATCH 2/6] kernel: add task_sigpending() helper Jens Axboe
2020-10-08 12:58   ` Oleg Nesterov
2020-10-08 13:36     ` Jens Axboe
2020-10-08 13:24   ` Oleg Nesterov
2020-10-08 13:38     ` Jens Axboe
2020-10-05 15:04 ` [PATCH 3/6] kernel: split syscall restart from signal handling Jens Axboe
2020-10-08 14:21   ` Oleg Nesterov
2020-10-08 14:31     ` Jens Axboe
2020-10-08 14:41       ` Jens Axboe
2020-10-08 14:45       ` Oleg Nesterov
2020-10-08 14:47         ` Jens Axboe
2020-10-05 15:04 ` Jens Axboe [this message]
2020-10-08 13:53   ` [PATCH 4/6] kernel: add support for TIF_NOTIFY_SIGNAL Oleg Nesterov
2020-10-08 14:07     ` Jens Axboe
2020-10-08 14:27       ` Oleg Nesterov
2020-10-05 15:04 ` [PATCH 5/6] x86: define _TIF_NOTIFY_SIGNAL Jens Axboe
2020-10-05 15:04 ` [PATCH 6/6] task_work: use TIF_NOTIFY_SIGNAL if available Jens Axboe
2020-10-08 14:56 ` [PATCHSET RFC v3 0/6] Add support for TIF_NOTIFY_SIGNAL Oleg Nesterov
2020-10-08 15:00   ` Jens Axboe
2020-10-09  8:01   ` Miroslav Benes
2020-10-09 15:21     ` Jens Axboe
2020-10-10 16:53       ` Jens Axboe
2020-10-12 17:27         ` Miroslav Benes
2020-10-13 19:39           ` Jens Axboe
2020-10-13 23:34             ` Thomas Gleixner
2020-10-13 23:37               ` Jens Axboe

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=20201005150438.6628-5-axboe@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=io-uring@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /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.