Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 
0003 #ifndef LINUX_RESUME_USER_MODE_H
0004 #define LINUX_RESUME_USER_MODE_H
0005 
0006 #include <linux/sched.h>
0007 #include <linux/task_work.h>
0008 #include <linux/memcontrol.h>
0009 #include <linux/blk-cgroup.h>
0010 
0011 /**
0012  * set_notify_resume - cause resume_user_mode_work() to be called
0013  * @task:       task that will call resume_user_mode_work()
0014  *
0015  * Calling this arranges that @task will call resume_user_mode_work()
0016  * before returning to user mode.  If it's already running in user mode,
0017  * it will enter the kernel and call resume_user_mode_work() soon.
0018  * If it's blocked, it will not be woken.
0019  */
0020 static inline void set_notify_resume(struct task_struct *task)
0021 {
0022     if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
0023         kick_process(task);
0024 }
0025 
0026 
0027 /**
0028  * resume_user_mode_work - Perform work before returning to user mode
0029  * @regs:       user-mode registers of @current task
0030  *
0031  * This is called when %TIF_NOTIFY_RESUME has been set.  Now we are
0032  * about to return to user mode, and the user state in @regs can be
0033  * inspected or adjusted.  The caller in arch code has cleared
0034  * %TIF_NOTIFY_RESUME before the call.  If the flag gets set again
0035  * asynchronously, this will be called again before we return to
0036  * user mode.
0037  *
0038  * Called without locks.
0039  */
0040 static inline void resume_user_mode_work(struct pt_regs *regs)
0041 {
0042     clear_thread_flag(TIF_NOTIFY_RESUME);
0043     /*
0044      * This barrier pairs with task_work_add()->set_notify_resume() after
0045      * hlist_add_head(task->task_works);
0046      */
0047     smp_mb__after_atomic();
0048     if (unlikely(task_work_pending(current)))
0049         task_work_run();
0050 
0051 #ifdef CONFIG_KEYS_REQUEST_CACHE
0052     if (unlikely(current->cached_requested_key)) {
0053         key_put(current->cached_requested_key);
0054         current->cached_requested_key = NULL;
0055     }
0056 #endif
0057 
0058     mem_cgroup_handle_over_high();
0059     blkcg_maybe_throttle_current();
0060 
0061     rseq_handle_notify_resume(NULL, regs);
0062 }
0063 
0064 #endif /* LINUX_RESUME_USER_MODE_H */