Linux:task work mechanism

Source: Internet
Author: User
Tags cas signal handler

The task work mechanism can add tasks to the specified process in the kernel, which are executed when the process returns to the user state, using the context of the process. These APIs include the following:

    • Task_work_add
    • Task_work_cancel
    • Task_work_run

A field in the Process object task_struct is used to store these pending task list headers, Task_works, which contains a next pointer and a function pointer that needs to be executed.

/** * struct CALLBACK_HEAD-CALLBACK structure for use with RCU and task_work * @next: Next update requests in a list * @func: Actual update function to call after the grace period. */a struct Callback_head {211         struct callback_head *next;212         Void (*func) (struct Callback_head * Head); 213};
4 5 static struct Callback_head work_exited;/ * All we need are->next = = NULL * /6 7/**8* Task_work_add-ask the @task to execute @work->func ()9* @task: The task which should run the callback10* @work: The callback to run11* @notify: Send the notification if True12 *13* Queue @work for Task_work_run () below and notify the @task if @notify.14* fails if the @task is exiting/exited and thus it can ' t process this @work.15* Otherwise @work->func () would be called if the @task returns from kernel16* mode or exits.17 *18* This was like the signal handler which runs in kernel mode, but it doesn ' t19* Try to wake up the @task.20 *21st* RETURNS:22* 0 if succeeds Or-esrch.23 */Task_work_add (struct task_struct *task, struct callback_head *work, bool notify) + struct callback _head *head; Access_once do {head = Task->task_works), if (unlikely (head = = &A mp;work_exited)) Return-esrch; Work->next = head; (Cmpxchg (&task->task_works, head, work)! = head); if (notify) PNS Set_notify_resume (Task); return 0; 39}

Main work:

1. A linked list element is added as an unlocked form via CAs. (The new element is in the original linked list header)

2. The Set_notify_resume function sets a _tif_notify_resume tag to the specified process.

Task_work_run Execution Time

The token check of the current process before returning to the user state, if the relevant tag is set to call Do_notify_resume

595 int_signal:596         testl $_tif_do_notify_mask,%edx597         jz 1f598         movq%rsp,%rdi          # &ptregs arg1599         xorl%esi,%esi          # oldset-arg2600 call         do_notify_resume601 1:      movl $_tif_work_mask,% edi602 int_restore_rest:603         restore_rest604         disable_interrupts (clbr_none) 605         trace_irqs_off606         jmp int_with_check607         cfi_endproc608 END (System_call)

The above file is Entry_64.s, and the tag is defined in THREAD_INFO.C

/* Work to does on interrupt/exception return */131 #define _tif_work_mask         (0x0000ffff &                                                   133          ~ (_tif_syscall_trace|_tif_syscall_audit|                       134            _tif_singlestep|_tif_seccomp|_tif_syscall_emu))
#define TIF_SYSCALL_TRACE 0/ * Syscall Trace Active * /#define TIF_NOTIFY_RESUME 1/ * Callback before returning to user * /#define Tif_sigpending 2/ * Signal pending * /#define TIF_NEED_RESCHED 3/ * Rescheduling necessary * /4 Tif_singlestep #define/ * reenable singlestep on user return*/#define TIF_SYSCALL_EMU 6/ * Syscall emulation active * /#define TIF_SYSCALL_AUDIT 7/ * Syscall Auditing Active * /8 Tif_seccomp #define/ * Secure Computing * /#define TIF_MCE_NOTIFY 10/ * Notify userspace of an MCE * *#define TIF_USER_RETURN_NOTIFY 11/ * Notify kernel of userspace return * /#define TIF_UPROBE 12/ * breakpointed or singlestepping * /Bayi #define TIF_NOTSC 16/ * TSC isn't accessible in userland * /17 Tif_ia32 #define/ * IA32 compatibility process * /#define Tif_fork 18/ * Ret_from_fork * /#define TIF_NOHZ 19/ * in adaptive nohz mode * /#define Tif_memdie 20/ * is terminating due to OOM killer * /#define TIF_POLLING_NRFLAG 21/ * Idle is polling for tif_need_resched * /#define TIF_IO_BITMAP 22/* uses I/o bitmap */#define TIF_FORCED_TF 24/ * True if TF in eflags artificially * /#define TIF_BLOCKSTEP 25/ * Set when we want DEBUGCTLMSR_BTF * /#define Tif_lazy_mmu_updates 27/ * task is updating the MMU lazily * /#define Tif_syscall_tracepoint 28/ * Syscall tracepoint instrumentation * /#define TIF_ADDR32 29/ * 32-bit address space on bits * /#define TIF_X32 30/ * 32-bit native x86-64 binary * /94

That is, _tif_work_mask means except for (_tif_syscall_trace, _tif_syscall_audit, _tif_singlestep, _tif_seccomp, _TIF_SYSCALL_ All tags outside of EMU). Nature includes the _tif_notify_resume mark.

Do_notify_resume function
729/*730* Notification of userspace execution resumption731*-triggered by the Tif_work_mask flags732 */733 __visible void734 do_notify_resume (struct pt_regs *regs, void *unused, __u32 thread_info_flags) 735 {736 User_e XIT (); 737 738 #ifdef config_x86_mce739/ * Notify userspace of pending MCEs * /740 if (Thread_info_flags & _tif_mce_notify) 741 mce_notify_process (); 742 #endif/ * config_x86_64 && config_x86_mce * *743 744 if (Thread_info_flags & _tif_uprobe) 745 uprobe_notify_resume (regs); 746 747/ * deal with pending signal delivery * /748 if (Thread_info_flags & _tif_sigpending) 749 do_signal (regs); 751 if (Thread_inf O_flags & _tif_notify_resume) {752 clear_thread_flag (tif_notify_resume); 753 Tracehook_ Notify_resume (regs); 754}755 if (Thread_info_flags & _tif_user_return_notify) 756 fire_ User_return_notifiers (); 757 758 user_enter (); 759}

You can see the call to the Tracehook_notify_resume function in it, as well as some other functions that are related to signal processing.

Tracehook_notify_resume
174/**175* Tracehook_notify_resume-report when on-to-return to user mode176* @regs: User-mode Registers of @current task177 *178* This was called when%tif_notify_resume had been set. Now we is179* About-to-return-to-user mode, and the user state in @regs can180* inspected or adjusted. The caller in arch code have cleared181*%tif_notify_resume before the call. IF the flag gets set again182* Asynchronously, this'll be called again before we return to183* User mode.184 *185* called without locks.186 */187 static inline void Tracehook_notify_resume (struct pt_regs *regs) 188 {189/*190* The caller just cleared Tif_notify_resume. This barrier191* Pairs with Task_work_add ()->set_notify_resume () after192* Hlist_add_head (task->task_works);193 */194 smp_mb__after_atomic (); 195 if (Unlikely (Current->task_works)) 196 task_work_run (); 19 7}

A task needs to be executed if the task_works of the process object is not NULL.

Task_work_run
77/**78* Task_work_run-execute The works added by Task_work_add ()79 *80* Flush the pending works. Should is used by the core kernel code.81* Called before the task returns to the User-mode or stops, or when82* it exits. In the latter case Task_work_add () can no longer add the83* New work after Task_work_run () returns.84 */Task_work_run void (void), task_struct *task = current; Callback_head *work, *he AD, *next; for (;;) {91/*92* WORK->FUNC () can do Task_work_add (), does not set93* work_exited unless the list is empty.94 */Access_once (task->task_works); hea D =!work && (task->flags & pf_exiting)? 98 &work_exited:NULL;                         Cmpxchg (&task->task_works, work, head)! = Work), 101 if (!work) 102 break;103/*104* Synchronize with Task_work_cancel (). It can ' t remove105* The first entry = = Work, Cmpxchg (Task_works) should106* fail, but it can play with *work and other entries.107 */108 raw_spin_unlock_wait (&task->pi_lock); 109 smp_mb (); 110 111/ * Reverse the list to run the works in FIFO order * /The head = null;113 do {next = work->next;115                 Work->next = head;116 Head = work;117 work = next;118 119 = head;121 do {122 next = Wo                         rk->next;123 Work->func (work), 124 work = next;125 Cond_resched (); 126} while (work); 127}128}

1. Get the Task_works linked list without a lock via CAs

2. Because the original linked list is added to the list by the element in reverse chronological order (see TASK_WORK_ADD), the list is reversed once

3. After the list is reversed, the list is traversed, and the task function that executes each element is Work->func (work)

Linux:task work mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.