mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	ptrace: relocate set_current_state(TASK_TRACED) in ptrace_stop()
In ptrace_stop(), after arch hook is done, the task state and jobctl bits are updated while holding siglock. The ordering requirement there is that TASK_TRACED is set before JOBCTL_TRAPPING is cleared to prevent ptracer waiting on TRAPPING doesn't end up waking up TRACED is actually set and sees TASK_RUNNING in wait(2). Move set_current_state(TASK_TRACED) to the top of the block and reorganize comments. This makes the ordering more obvious (TASK_TRACED before other updates) and helps future updates to group stop participation. This patch doesn't cause any functional change. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
This commit is contained in:
		
							parent
							
								
									755e276b33
								
							
						
					
					
						commit
						81be24b8cd
					
				
					 1 changed files with 13 additions and 15 deletions
				
			
		|  | @ -1732,6 +1732,18 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | |||
| 			return; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We're committing to trapping.  TRACED should be visible before | ||||
| 	 * TRAPPING is cleared; otherwise, the tracer might fail do_wait(). | ||||
| 	 * Also, transition to TRACED and updates to ->jobctl should be | ||||
| 	 * atomic with respect to siglock and should be done after the arch | ||||
| 	 * hook as siglock is released and regrabbed across it. | ||||
| 	 */ | ||||
| 	set_current_state(TASK_TRACED); | ||||
| 
 | ||||
| 	current->last_siginfo = info; | ||||
| 	current->exit_code = exit_code; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If @why is CLD_STOPPED, we're trapping to participate in a group | ||||
| 	 * stop.  Do the bookkeeping.  Note that if SIGCONT was delievered | ||||
|  | @ -1742,21 +1754,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | |||
| 	if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING)) | ||||
| 		gstop_done = task_participate_group_stop(current); | ||||
| 
 | ||||
| 	current->last_siginfo = info; | ||||
| 	current->exit_code = exit_code; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * TRACED should be visible before TRAPPING is cleared; otherwise, | ||||
| 	 * the tracer might fail do_wait(). | ||||
| 	 */ | ||||
| 	set_current_state(TASK_TRACED); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We're committing to trapping.  Clearing JOBCTL_TRAPPING and | ||||
| 	 * transition to TASK_TRACED should be atomic with respect to | ||||
| 	 * siglock.  This should be done after the arch hook as siglock is | ||||
| 	 * released and regrabbed across it. | ||||
| 	 */ | ||||
| 	/* entering a trap, clear TRAPPING */ | ||||
| 	task_clear_jobctl_trapping(current); | ||||
| 
 | ||||
| 	spin_unlock_irq(¤t->sighand->siglock); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Tejun Heo
						Tejun Heo