rpms/kernel/devel kernel-2.6.spec, 1.3237, 1.3238 linux-2.6-utrace.patch, 1.64, 1.65

Roland McGrath (roland) fedora-extras-commits at redhat.com
Mon Jun 25 08:34:50 UTC 2007


Author: roland

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv1405

Modified Files:
	kernel-2.6.spec linux-2.6-utrace.patch 
Log Message:
- utrace update (06c303cccb93e7ca3a95923e69b4d82733c1cf00)


Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.3237
retrieving revision 1.3238
diff -u -r1.3237 -r1.3238
--- kernel-2.6.spec	25 Jun 2007 08:30:16 -0000	1.3237
+++ kernel-2.6.spec	25 Jun 2007 08:34:13 -0000	1.3238
@@ -2093,6 +2093,7 @@
 * Mon Jun 25 2007 Roland McGrath <roland at redhat.com>
 - Let spec-file ApplyPatch function pass extra args to patch.
 - Re-enable utrace patch with -F2, needed after nearby CFS change.
+- utrace update (06c303cccb93e7ca3a95923e69b4d82733c1cf00)
 
 * Sun Jun 24 2007 Dave Jones <davej at redhat.com>
 - Fix 64 bit overflow in CFS.

linux-2.6-utrace.patch:

Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- linux-2.6-utrace.patch	17 Jun 2007 19:45:32 -0000	1.64
+++ linux-2.6-utrace.patch	25 Jun 2007 08:34:13 -0000	1.65
@@ -1693,7 +1693,7 @@
  #include <linux/timer.h>
  #include <linux/mm.h>
  #include <linux/smp.h>
-@@ -335,7 +335,7 @@ void __kprobes do_single_step(struct pt_
+@@ -338,7 +338,7 @@ void __kprobes do_single_step(struct pt_
  					SIGTRAP) == NOTIFY_STOP){
  		return;
  	}
@@ -1702,7 +1702,7 @@
  		force_sig(SIGTRAP, current);
  }
  
-@@ -436,7 +436,7 @@ static void illegal_op(struct pt_regs * 
+@@ -439,7 +439,7 @@ static void illegal_op(struct pt_regs * 
  		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
  			return;
  		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
@@ -12968,7 +12968,7 @@
  			 * For a WNOHANG return, clear out all the fields
 --- linux-2.6/kernel/utrace.c
 +++ linux-2.6/kernel/utrace.c
-@@ -0,0 +1,2222 @@
+@@ -0,0 +1,2263 @@
 +/*
 + * utrace infrastructure interface for debugging user processes
 + *
@@ -13278,7 +13278,6 @@
 +			 * which will call release_task itself.
 +			 */
 +			read_unlock(&tasklist_lock);
-+
 +	}
 +
 +	/*
@@ -13356,10 +13355,12 @@
 +
 +	case TASK_STOPPED:
 +		/*
-+		 * If it will call utrace_report_jctl but have not gotten
++		 * If it will call utrace_report_jctl but has not gotten
 +		 * through it yet, then don't consider it quiescent yet.
 +		 * utrace_report_jctl will take target->utrace->lock and
-+		 * clear UTRACE_EVENT(JCTL) once it finishes.
++		 * clear UTRACE_EVENT(JCTL) once it finishes.  After that,
++		 * it is considered quiescent; when it wakes up, it will go
++		 * through utrace_get_signal before doing anything else.
 +		 */
 +		if (!(target->utrace_flags & UTRACE_EVENT(JCTL)))
 +			break;
@@ -13458,6 +13459,8 @@
 +		 * Check this first; a race with reaping may lead to restart.
 +		 */
 +		rcu_read_unlock();
++		if (!(flags & UTRACE_ATTACH_CREATE))
++			return ERR_PTR(-ENOENT);
 +		return ERR_PTR(-ESRCH);
 +	}
 +
@@ -14645,7 +14648,7 @@
 +
 +		/*
 +		 * Clear TIF_SIGPENDING if it no longer needs to be set.
-+		 * It may have been set as part of quiesence, and won't
++		 * It may have been set as part of quiescence, and won't
 +		 * ever have been cleared by another thread.  For other
 +		 * reports, we can just leave it set and will go through
 +		 * utrace_get_signal to reset things.  But here we are
@@ -14725,12 +14728,50 @@
 +	__releases(tsk->sighand->siglock)
 +	__acquires(tsk->sighand->siglock)
 +{
-+	struct utrace *utrace = tsk->utrace;
++	struct utrace *utrace;
 +	struct utrace_signal signal = { info, return_ka, 0 };
 +	struct k_sigaction *ka;
 +	unsigned long action, event;
 +
 +	/*
++	 * We could have been considered quiescent while we were in
++	 * TASK_STOPPED, and detached asynchronously.  If we woke up
++	 * and checked tsk->utrace_flags before that was finished,
++	 * we might be here with utrace already removed or in the
++	 * middle of being removed.
++	 */
++	rcu_read_lock();
++	utrace = rcu_dereference(tsk->utrace);
++	if (unlikely(utrace == NULL)) {
++		rcu_read_unlock();
++		return 0;
++	}
++	if (!(tsk->utrace_flags & UTRACE_EVENT(JCTL))) {
++		/*
++		 * It's possible we might have just been in TASK_STOPPED
++		 * and subject to the aforementioned race.
++		 *
++		 * RCU makes it safe to get the utrace->lock even if it's
++		 * being freed.  Once we have that lock, either an external
++		 * detach has finished and this struct has been freed, or
++		 * else we know we are excluding any other detach attempt.
++		 * Since we are no longer in TASK_STOPPED now, all we
++		 * needed the lock for was to order any quiesce() call after us.
++		 */
++		spin_unlock_irq(&tsk->sighand->siglock);
++		spin_lock(&utrace->lock);
++		if (unlikely(tsk->utrace != utrace)) {
++			spin_unlock(&utrace->lock);
++			rcu_read_unlock();
++			cond_resched();
++			return -1;
++		}
++		spin_unlock(&utrace->lock);
++		spin_lock_irq(&tsk->sighand->siglock);
++	}
++	rcu_read_unlock();
++
++	/*
 +	 * If a signal was injected previously, it could not use our
 +	 * stack space directly.  It had to allocate a data structure,
 +	 * which we can now copy out of and free.
@@ -15193,7 +15234,7 @@
 +}
 --- linux-2.6/kernel/ptrace.c
 +++ linux-2.6/kernel/ptrace.c
-@@ -18,476 +18,2003 @@
+@@ -18,476 +18,2008 @@
  #include <linux/ptrace.h>
  #include <linux/security.h>
  #include <linux/signal.h>
@@ -15726,7 +15767,12 @@
 +			retval = ptrace_update(task, state, /* XXX child death+other thread waits race could have freed state already */
 +					       UTRACE_ACTION_QUIESCE, 0);
 +			if (retval)
-+				BUG_ON(retval != -ESRCH);
++				/*
++				 * Anything is possible here.  It might not
++				 * really have been quiescent yet.  It
++				 * might have just woken up and died.
++				 */
++				BUG_ON(retval != -ESRCH && retval != -EALREADY);
 +			retval = 0;
 +
 +			/*
@@ -17597,7 +17643,7 @@
  		set_tsk_thread_flag(t, TIF_SIGPENDING);
  		return 1;
  	}
-@@ -533,8 +532,6 @@ static int check_kill_permission(int sig
+@@ -539,8 +538,6 @@ static int check_kill_permission(int sig
  	return security_task_kill(t, info, sig, 0);
  }
  
@@ -17606,7 +17652,7 @@
  
  /*
   * Handle magic process-wide effects of stop/continue signals.
-@@ -846,7 +843,7 @@ __group_complete_signal(int sig, struct 
+@@ -852,7 +849,7 @@ __group_complete_signal(int sig, struct 
  	 */
  	if (sig_fatal(p, sig) && !(p->signal->flags & SIGNAL_GROUP_EXIT) &&
  	    !sigismember(&t->real_blocked, sig) &&
@@ -17615,7 +17661,7 @@
  		/*
  		 * This signal will be fatal to the whole group.
  		 */
-@@ -1401,8 +1398,7 @@ void do_notify_parent(struct task_struct
+@@ -1407,8 +1404,7 @@ void do_notify_parent(struct task_struct
   	/* do_notify_parent_cldstop should have been called instead.  */
   	BUG_ON(tsk->state & (TASK_STOPPED|TASK_TRACED));
  
@@ -17625,7 +17671,7 @@
  
  	info.si_signo = sig;
  	info.si_errno = 0;
-@@ -1427,7 +1423,7 @@ void do_notify_parent(struct task_struct
+@@ -1433,7 +1429,7 @@ void do_notify_parent(struct task_struct
  
  	psig = tsk->parent->sighand;
  	spin_lock_irqsave(&psig->siglock, flags);
@@ -17634,7 +17680,7 @@
  	    (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
  	     (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
  		/*
-@@ -1455,20 +1451,13 @@ void do_notify_parent(struct task_struct
+@@ -1461,20 +1457,13 @@ void do_notify_parent(struct task_struct
  	spin_unlock_irqrestore(&psig->siglock, flags);
  }
  
@@ -17656,7 +17702,7 @@
  	info.si_signo = SIGCHLD;
  	info.si_errno = 0;
  	info.si_pid = tsk->pid;
-@@ -1493,6 +1482,15 @@ static void do_notify_parent_cldstop(str
+@@ -1499,6 +1488,15 @@ static void do_notify_parent_cldstop(str
   		BUG();
   	}
  
@@ -17672,7 +17718,7 @@
  	sighand = parent->sighand;
  	spin_lock_irqsave(&sighand->siglock, flags);
  	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
-@@ -1505,111 +1503,6 @@ static void do_notify_parent_cldstop(str
+@@ -1511,111 +1509,6 @@ static void do_notify_parent_cldstop(str
  	spin_unlock_irqrestore(&sighand->siglock, flags);
  }
  
@@ -17784,7 +17830,7 @@
  static void
  finish_stop(int stop_count)
  {
-@@ -1618,7 +1511,7 @@ finish_stop(int stop_count)
+@@ -1624,7 +1517,7 @@ finish_stop(int stop_count)
  	 * a group stop in progress and we are the last to stop,
  	 * report to the parent.  When ptraced, every thread reports itself.
  	 */
@@ -17793,7 +17839,7 @@
  		read_lock(&tasklist_lock);
  		do_notify_parent_cldstop(current, CLD_STOPPED);
  		read_unlock(&tasklist_lock);
-@@ -1745,44 +1638,24 @@ relock:
+@@ -1751,44 +1644,24 @@ relock:
  		    handle_group_stop())
  			goto relock;
  
@@ -17854,7 +17900,7 @@
  		if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
  			continue;
  		if (ka->sa.sa_handler != SIG_DFL) {
-@@ -1831,7 +1704,7 @@ relock:
+@@ -1837,7 +1710,7 @@ relock:
  				spin_lock_irq(&current->sighand->siglock);
  			}
  
@@ -17863,7 +17909,7 @@
  				/* It released the siglock.  */
  				goto relock;
  			}
-@@ -1858,13 +1731,13 @@ relock:
+@@ -1864,13 +1737,13 @@ relock:
  			 * first and our do_group_exit call below will use
  			 * that value and ignore the one we pass it.
  			 */
@@ -17879,7 +17925,7 @@
  		/* NOTREACHED */
  	}
  	spin_unlock_irq(&current->sighand->siglock);
-@@ -1876,7 +1749,6 @@ EXPORT_SYMBOL_GPL(dequeue_signal);
+@@ -1882,7 +1755,6 @@ EXPORT_SYMBOL_GPL(dequeue_signal);
  EXPORT_SYMBOL(flush_signals);
  EXPORT_SYMBOL(force_sig);
  EXPORT_SYMBOL(kill_proc);
@@ -19217,7 +19263,7 @@
 +{
 +	smp_mb();
 +	if (tsk_utrace_flags(tsk) & (UTRACE_EVENT(DEATH)
-+				     | UTRACE_ACTION_QUIESCE))
++				     | UTRACE_EVENT(QUIESCE)))
 +		utrace_report_death(tsk, death_cookie);
 +}
 +




More information about the fedora-extras-commits mailing list