All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [RFC] Waitqueue-free gatekeeper wakeup
@ 2011-07-18 11:52 Jan Kiszka
  2011-07-20 16:28 ` Philippe Gerum
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Kiszka @ 2011-07-18 11:52 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: Xenomai core

Hi Philippe,

trying to decouple the PREEMPT-RT gatekeeper wakeup path from XNATOMIC
(to fix the remaining races there), I wondered why we need a waitqueue
here at all.

What about an approach like below, i.e. waking up the gatekeeper
directly via wake_up_process? That could even be called from interrupt
context. We should be able to avoid missing a wakeup by setting the task
state to INTERRUPTIBLE before signaling the semaphore.

Am I missing something?

Jan


diff --git a/include/nucleus/sched.h b/include/nucleus/sched.h
index e251329..df8853b 100644
--- a/include/nucleus/sched.h
+++ b/include/nucleus/sched.h
@@ -111,7 +111,6 @@ typedef struct xnsched {
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
 	struct task_struct *gatekeeper;
-	wait_queue_head_t gkwaitq;
 	struct semaphore gksync;
 	struct xnthread *gktarget;
 #endif
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index f6b1e16..238317a 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -92,7 +92,6 @@ static struct __lostagerq {
 #define LO_SIGGRP_REQ 2
 #define LO_SIGTHR_REQ 3
 #define LO_UNMAP_REQ  4
-#define LO_GKWAKE_REQ 5
 		int type;
 		struct task_struct *task;
 		int arg;
@@ -759,9 +758,6 @@ static void lostage_handler(void *cookie)
 	int cpu, reqnum, type, arg, sig, sigarg;
 	struct __lostagerq *rq;
 	struct task_struct *p;
-#ifdef CONFIG_PREEMPT_RT
-	struct xnsched *sched;
-#endif
 
 	cpu = smp_processor_id();
 	rq = &lostagerq[cpu];
@@ -819,13 +815,6 @@ static void lostage_handler(void *cookie)
 		case LO_SIGGRP_REQ:
 			kill_proc(p->pid, arg, 1);
 			break;
-
-#ifdef CONFIG_PREEMPT_RT
-		case LO_GKWAKE_REQ:
-			sched = xnpod_sched_slot(cpu);
-			wake_up_interruptible_sync(&sched->gkwaitq);
-			break;
-#endif
 		}
 	}
 }
@@ -873,7 +862,6 @@ static inline int normalize_priority(int prio)
 static int gatekeeper_thread(void *data)
 {
 	struct task_struct *this_task = current;
-	DECLARE_WAITQUEUE(wait, this_task);
 	int cpu = (long)data;
 	struct xnsched *sched = xnpod_sched_slot(cpu);
 	struct xnthread *target;
@@ -886,12 +874,10 @@ static int gatekeeper_thread(void *data)
 	set_cpus_allowed(this_task, cpumask);
 	set_linux_task_priority(this_task, MAX_RT_PRIO - 1);
 
-	init_waitqueue_head(&sched->gkwaitq);
-	add_wait_queue_exclusive(&sched->gkwaitq, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
 	up(&sched->gksync);	/* Sync with xnshadow_mount(). */
 
 	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
 		up(&sched->gksync); /* Make the request token available. */
 		schedule();
 
@@ -937,6 +923,7 @@ static int gatekeeper_thread(void *data)
 			xnlock_put_irqrestore(&nklock, s);
 			xnpod_schedule();
 		}
+		set_current_state(TASK_INTERRUPTIBLE);
 	}
 
 	return 0;
@@ -1014,23 +1001,9 @@ redo:
 	thread->gksched = sched;
 	xnthread_set_info(thread, XNATOMIC);
 	set_current_state(TASK_INTERRUPTIBLE | TASK_ATOMICSWITCH);
-#ifndef CONFIG_PREEMPT_RT
-	/*
-	 * We may not hold the preemption lock across calls to
-	 * wake_up_*() services over fully preemptible kernels, since
-	 * tasks might sleep when contending for spinlocks. The wake
-	 * up call for the gatekeeper will happen later, over an APC
-	 * we kick in do_schedule_event() on the way out for the
-	 * hardening task.
-	 *
-	 * We could delay the wake up call over non-RT 2.6 kernels as
-	 * well, but not when running over 2.4 (scheduler innards
-	 * would not allow this, causing weirdnesses when hardening
-	 * tasks). So we always do the early wake up when running
-	 * non-RT, which includes 2.4.
-	 */
-	wake_up_interruptible_sync(&sched->gkwaitq);
-#endif
+
+	wake_up_process(sched->gatekeeper);
+
 	schedule();
 
 	/*

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Xenomai-core] [RFC] Waitqueue-free gatekeeper wakeup
  2011-07-18 11:52 [Xenomai-core] [RFC] Waitqueue-free gatekeeper wakeup Jan Kiszka
@ 2011-07-20 16:28 ` Philippe Gerum
  0 siblings, 0 replies; 2+ messages in thread
From: Philippe Gerum @ 2011-07-20 16:28 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Xenomai core

On Mon, 2011-07-18 at 13:52 +0200, Jan Kiszka wrote:
> Hi Philippe,
> 
> trying to decouple the PREEMPT-RT gatekeeper wakeup path from XNATOMIC
> (to fix the remaining races there), I wondered why we need a waitqueue
> here at all.
> 
> What about an approach like below, i.e. waking up the gatekeeper
> directly via wake_up_process? That could even be called from interrupt
> context. We should be able to avoid missing a wakeup by setting the task
> state to INTERRUPTIBLE before signaling the semaphore.
> 
> Am I missing something?

No, I think this should work. IIRC, the wait queue dates back when we
did not have a strong synchro between the hardening code and the gk via
the request token, i.e. the initial implementation over 2.4 kernels. So
it is about time to question this.

> 
> Jan
> 
> 
> diff --git a/include/nucleus/sched.h b/include/nucleus/sched.h
> index e251329..df8853b 100644
> --- a/include/nucleus/sched.h
> +++ b/include/nucleus/sched.h
> @@ -111,7 +111,6 @@ typedef struct xnsched {
>  
>  #ifdef CONFIG_XENO_OPT_PERVASIVE
>  	struct task_struct *gatekeeper;
> -	wait_queue_head_t gkwaitq;
>  	struct semaphore gksync;
>  	struct xnthread *gktarget;
>  #endif
> diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
> index f6b1e16..238317a 100644
> --- a/ksrc/nucleus/shadow.c
> +++ b/ksrc/nucleus/shadow.c
> @@ -92,7 +92,6 @@ static struct __lostagerq {
>  #define LO_SIGGRP_REQ 2
>  #define LO_SIGTHR_REQ 3
>  #define LO_UNMAP_REQ  4
> -#define LO_GKWAKE_REQ 5
>  		int type;
>  		struct task_struct *task;
>  		int arg;
> @@ -759,9 +758,6 @@ static void lostage_handler(void *cookie)
>  	int cpu, reqnum, type, arg, sig, sigarg;
>  	struct __lostagerq *rq;
>  	struct task_struct *p;
> -#ifdef CONFIG_PREEMPT_RT
> -	struct xnsched *sched;
> -#endif
>  
>  	cpu = smp_processor_id();
>  	rq = &lostagerq[cpu];
> @@ -819,13 +815,6 @@ static void lostage_handler(void *cookie)
>  		case LO_SIGGRP_REQ:
>  			kill_proc(p->pid, arg, 1);
>  			break;
> -
> -#ifdef CONFIG_PREEMPT_RT
> -		case LO_GKWAKE_REQ:
> -			sched = xnpod_sched_slot(cpu);
> -			wake_up_interruptible_sync(&sched->gkwaitq);
> -			break;
> -#endif
>  		}
>  	}
>  }
> @@ -873,7 +862,6 @@ static inline int normalize_priority(int prio)
>  static int gatekeeper_thread(void *data)
>  {
>  	struct task_struct *this_task = current;
> -	DECLARE_WAITQUEUE(wait, this_task);
>  	int cpu = (long)data;
>  	struct xnsched *sched = xnpod_sched_slot(cpu);
>  	struct xnthread *target;
> @@ -886,12 +874,10 @@ static int gatekeeper_thread(void *data)
>  	set_cpus_allowed(this_task, cpumask);
>  	set_linux_task_priority(this_task, MAX_RT_PRIO - 1);
>  
> -	init_waitqueue_head(&sched->gkwaitq);
> -	add_wait_queue_exclusive(&sched->gkwaitq, &wait);
> +	set_current_state(TASK_INTERRUPTIBLE);
>  	up(&sched->gksync);	/* Sync with xnshadow_mount(). */
>  
>  	for (;;) {
> -		set_current_state(TASK_INTERRUPTIBLE);
>  		up(&sched->gksync); /* Make the request token available. */
>  		schedule();
>  
> @@ -937,6 +923,7 @@ static int gatekeeper_thread(void *data)
>  			xnlock_put_irqrestore(&nklock, s);
>  			xnpod_schedule();
>  		}
> +		set_current_state(TASK_INTERRUPTIBLE);
>  	}
>  
>  	return 0;
> @@ -1014,23 +1001,9 @@ redo:
>  	thread->gksched = sched;
>  	xnthread_set_info(thread, XNATOMIC);
>  	set_current_state(TASK_INTERRUPTIBLE | TASK_ATOMICSWITCH);
> -#ifndef CONFIG_PREEMPT_RT
> -	/*
> -	 * We may not hold the preemption lock across calls to
> -	 * wake_up_*() services over fully preemptible kernels, since
> -	 * tasks might sleep when contending for spinlocks. The wake
> -	 * up call for the gatekeeper will happen later, over an APC
> -	 * we kick in do_schedule_event() on the way out for the
> -	 * hardening task.
> -	 *
> -	 * We could delay the wake up call over non-RT 2.6 kernels as
> -	 * well, but not when running over 2.4 (scheduler innards
> -	 * would not allow this, causing weirdnesses when hardening
> -	 * tasks). So we always do the early wake up when running
> -	 * non-RT, which includes 2.4.
> -	 */
> -	wake_up_interruptible_sync(&sched->gkwaitq);
> -#endif
> +
> +	wake_up_process(sched->gatekeeper);
> +
>  	schedule();
>  
>  	/*
> 

-- 
Philippe.




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-07-20 16:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-18 11:52 [Xenomai-core] [RFC] Waitqueue-free gatekeeper wakeup Jan Kiszka
2011-07-20 16:28 ` Philippe Gerum

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.