Re: [Xenomai-core] [PATCH] xnpipe: fix state tracking of Linux side

2008-10-17 Thread Jan Kiszka
Philippe Gerum wrote:
> Jan Kiszka wrote:
>> Jan Kiszka wrote:
>>> The state tracking of Linux tasks queue on xnpipe events was fairly
>>> broken. An easy way to corrupt some xnpipe_state_t object was to kill a
>>> Linux task blocked on opening a /dev/rtpX device (this left the state
>>> object queued in xnpipe_sleep, and hell broke loose on next queuing).
>>>
>>> Another problem that popped up after reworking xnpipe queuing was a
>>> stalled XNPIPE_USER_CONN after receiving a signal in xnpipe_open.
>>>
>>> The following patch addresses both issues, appears to run fine so far
>>> (at least the test case no longer triggers), and also cleans up some
>>> redundant nklock acquisitions/releases. Nevertheless, I may miss some
>>> corner case that might have triggered the original design. So please
>>> check carefully.
>> While fighting over a single bit elsewhere, let's not forget this open
>> issue:
> 
> I did not forget this issue. It is close to the top of stack now.
> 
>  Customer asks for a solution of the hard lock-up he faced, and
>> /me would like to know if this fix comes with no obvious regressions.
>>
> 
> The patch looks sane, but I want to run a few tests that have been developed
> over time to chase bugs in that code, before giving the patch a go. ETA: 
> tomorrow.
> 

Great, thanks.

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH] xnpipe: fix state tracking of Linux side

2008-10-17 Thread Philippe Gerum
Jan Kiszka wrote:
> Jan Kiszka wrote:
>> The state tracking of Linux tasks queue on xnpipe events was fairly
>> broken. An easy way to corrupt some xnpipe_state_t object was to kill a
>> Linux task blocked on opening a /dev/rtpX device (this left the state
>> object queued in xnpipe_sleep, and hell broke loose on next queuing).
>>
>> Another problem that popped up after reworking xnpipe queuing was a
>> stalled XNPIPE_USER_CONN after receiving a signal in xnpipe_open.
>>
>> The following patch addresses both issues, appears to run fine so far
>> (at least the test case no longer triggers), and also cleans up some
>> redundant nklock acquisitions/releases. Nevertheless, I may miss some
>> corner case that might have triggered the original design. So please
>> check carefully.
> 
> While fighting over a single bit elsewhere, let's not forget this open
> issue:

I did not forget this issue. It is close to the top of stack now.

 Customer asks for a solution of the hard lock-up he faced, and
> /me would like to know if this fix comes with no obvious regressions.
> 

The patch looks sane, but I want to run a few tests that have been developed
over time to chase bugs in that code, before giving the patch a go. ETA: 
tomorrow.

> TIA,
> Jan
> 
>> ---
>>  ksrc/nucleus/pipe.c |   64 
>> +++-
>>  1 file changed, 24 insertions(+), 40 deletions(-)
>>
>> Index: b/ksrc/nucleus/pipe.c
>> ===
>> --- a/ksrc/nucleus/pipe.c
>> +++ b/ksrc/nucleus/pipe.c
>> @@ -88,38 +88,39 @@ static inline void xnpipe_minor_free(int
>>  
>>  static inline void xnpipe_enqueue_wait(xnpipe_state_t *state, int mask)
>>  {
>> -spl_t s;
>> -
>> -xnlock_get_irqsave(&nklock, s);
>> -
>>  if (state->wcount++ == 0)
>>  appendq(&xnpipe_sleepq, &state->slink);
>>  
>>  __setbits(state->status, mask);
>> +}
>>  
>> -xnlock_put_irqrestore(&nklock, s);
>> +static inline void xnpipe_dequeue_wait(xnpipe_state_t *state, int mask)
>> +{
>> +if (testbits(state->status, mask)) {
>> +if (--state->wcount == 0)
>> +removeq(&xnpipe_sleepq, &state->slink);
>> +__clrbits(state->status, mask);
>> +}
>>  }
>>  
>>  /* Must be entered with nklock held. */
>> -#define xnpipe_wait(__state, __mask, __s, __cond)   \
>> -({  \
>> -wait_queue_head_t *__waitq; \
>> -DEFINE_WAIT(__wait);\
>> -int __sigpending;   \
>> -\
>> -if ((__mask) & XNPIPE_USER_WREAD)   \
>> -__waitq = &(__state)->readq;\
>> -else\
>> -__waitq = &(__state)->syncq;\
>> -\
>> -xnpipe_enqueue_wait(__state, __mask);   \
>> -xnlock_put_irqrestore(&nklock, __s);\
>> +#define xnpipe_wait(__state, __mask, __s, __cond)   \
>> +({  \
>> +wait_queue_head_t *__waitq; \
>> +DEFINE_WAIT(__wait);\
>> +int __sigpending;   \
>> +\
>> +if ((__mask) & XNPIPE_USER_WREAD)   \
>> +__waitq = &(__state)->readq;\
>> +else\
>> +__waitq = &(__state)->syncq;\
>> +\
>> +xnpipe_enqueue_wait(__state, __mask);   \
>> +xnlock_put_irqrestore(&nklock, __s);\
>>  \
>>  prepare_to_wait_exclusive(__waitq, &__wait, TASK_INTERRUPTIBLE);\
>>  \
>> -if (__cond) \
>> -xnpipe_dequeue_wait(__state, __mask);   \
>> -else\
>> +if (!__cond)\
>>  schedule(); \
>>  \
>>  finish_wait(__waitq, &__wait);  \
>> @@ -127,25 +128,11 @@ static inline void xnpipe_enqueue_wait(x
>>  \
>>  /* Restore the interrupt state initially set by the caller. */  \
>>

Re: [Xenomai-core] [PATCH] xnpipe: fix state tracking of Linux side

2008-10-17 Thread Jan Kiszka
Jan Kiszka wrote:
> The state tracking of Linux tasks queue on xnpipe events was fairly
> broken. An easy way to corrupt some xnpipe_state_t object was to kill a
> Linux task blocked on opening a /dev/rtpX device (this left the state
> object queued in xnpipe_sleep, and hell broke loose on next queuing).
> 
> Another problem that popped up after reworking xnpipe queuing was a
> stalled XNPIPE_USER_CONN after receiving a signal in xnpipe_open.
> 
> The following patch addresses both issues, appears to run fine so far
> (at least the test case no longer triggers), and also cleans up some
> redundant nklock acquisitions/releases. Nevertheless, I may miss some
> corner case that might have triggered the original design. So please
> check carefully.

While fighting over a single bit elsewhere, let's not forget this open
issue: Customer asks for a solution of the hard lock-up he faced, and
/me would like to know if this fix comes with no obvious regressions.

TIA,
Jan

> ---
>  ksrc/nucleus/pipe.c |   64 
> +++-
>  1 file changed, 24 insertions(+), 40 deletions(-)
> 
> Index: b/ksrc/nucleus/pipe.c
> ===
> --- a/ksrc/nucleus/pipe.c
> +++ b/ksrc/nucleus/pipe.c
> @@ -88,38 +88,39 @@ static inline void xnpipe_minor_free(int
>  
>  static inline void xnpipe_enqueue_wait(xnpipe_state_t *state, int mask)
>  {
> - spl_t s;
> -
> - xnlock_get_irqsave(&nklock, s);
> -
>   if (state->wcount++ == 0)
>   appendq(&xnpipe_sleepq, &state->slink);
>  
>   __setbits(state->status, mask);
> +}
>  
> - xnlock_put_irqrestore(&nklock, s);
> +static inline void xnpipe_dequeue_wait(xnpipe_state_t *state, int mask)
> +{
> + if (testbits(state->status, mask)) {
> + if (--state->wcount == 0)
> + removeq(&xnpipe_sleepq, &state->slink);
> + __clrbits(state->status, mask);
> + }
>  }
>  
>  /* Must be entered with nklock held. */
> -#define xnpipe_wait(__state, __mask, __s, __cond)\
> -({   \
> - wait_queue_head_t *__waitq; \
> - DEFINE_WAIT(__wait);\
> - int __sigpending;   \
> - \
> - if ((__mask) & XNPIPE_USER_WREAD)   \
> - __waitq = &(__state)->readq;\
> - else\
> - __waitq = &(__state)->syncq;\
> - \
> - xnpipe_enqueue_wait(__state, __mask);   \
> - xnlock_put_irqrestore(&nklock, __s);\
> +#define xnpipe_wait(__state, __mask, __s, __cond)\
> +({   \
> + wait_queue_head_t *__waitq; \
> + DEFINE_WAIT(__wait);\
> + int __sigpending;   \
> + \
> + if ((__mask) & XNPIPE_USER_WREAD)   \
> + __waitq = &(__state)->readq;\
> + else\
> + __waitq = &(__state)->syncq;\
> + \
> + xnpipe_enqueue_wait(__state, __mask);   \
> + xnlock_put_irqrestore(&nklock, __s);\
>   \
>   prepare_to_wait_exclusive(__waitq, &__wait, TASK_INTERRUPTIBLE);\
>   \
> - if (__cond) \
> - xnpipe_dequeue_wait(__state, __mask);   \
> - else\
> + if (!__cond)\
>   schedule(); \
>   \
>   finish_wait(__waitq, &__wait);  \
> @@ -127,25 +128,11 @@ static inline void xnpipe_enqueue_wait(x
>   \
>   /* Restore the interrupt state initially set by the caller. */  \
>   xnlock_get_irqsave(&nklock, __s);   \
> + xnpipe_dequeue_wait(__state, __mask);   \
>   \
>   __sigpending;   \
>  })
>  
> 

[Xenomai-core] [PATCH] xnpipe: fix state tracking of Linux side

2008-10-13 Thread Jan Kiszka
The state tracking of Linux tasks queue on xnpipe events was fairly
broken. An easy way to corrupt some xnpipe_state_t object was to kill a
Linux task blocked on opening a /dev/rtpX device (this left the state
object queued in xnpipe_sleep, and hell broke loose on next queuing).

Another problem that popped up after reworking xnpipe queuing was a
stalled XNPIPE_USER_CONN after receiving a signal in xnpipe_open.

The following patch addresses both issues, appears to run fine so far
(at least the test case no longer triggers), and also cleans up some
redundant nklock acquisitions/releases. Nevertheless, I may miss some
corner case that might have triggered the original design. So please
check carefully.

Jan

---
 ksrc/nucleus/pipe.c |   64 +++-
 1 file changed, 24 insertions(+), 40 deletions(-)

Index: b/ksrc/nucleus/pipe.c
===
--- a/ksrc/nucleus/pipe.c
+++ b/ksrc/nucleus/pipe.c
@@ -88,38 +88,39 @@ static inline void xnpipe_minor_free(int
 
 static inline void xnpipe_enqueue_wait(xnpipe_state_t *state, int mask)
 {
-   spl_t s;
-
-   xnlock_get_irqsave(&nklock, s);
-
if (state->wcount++ == 0)
appendq(&xnpipe_sleepq, &state->slink);
 
__setbits(state->status, mask);
+}
 
-   xnlock_put_irqrestore(&nklock, s);
+static inline void xnpipe_dequeue_wait(xnpipe_state_t *state, int mask)
+{
+   if (testbits(state->status, mask)) {
+   if (--state->wcount == 0)
+   removeq(&xnpipe_sleepq, &state->slink);
+   __clrbits(state->status, mask);
+   }
 }
 
 /* Must be entered with nklock held. */
-#define xnpipe_wait(__state, __mask, __s, __cond)  \
-({ \
-   wait_queue_head_t *__waitq; \
-   DEFINE_WAIT(__wait);\
-   int __sigpending;   \
-   \
-   if ((__mask) & XNPIPE_USER_WREAD)   \
-   __waitq = &(__state)->readq;\
-   else\
-   __waitq = &(__state)->syncq;\
-   \
-   xnpipe_enqueue_wait(__state, __mask);   \
-   xnlock_put_irqrestore(&nklock, __s);\
+#define xnpipe_wait(__state, __mask, __s, __cond)  \
+({ \
+   wait_queue_head_t *__waitq; \
+   DEFINE_WAIT(__wait);\
+   int __sigpending;   \
+   \
+   if ((__mask) & XNPIPE_USER_WREAD)   \
+   __waitq = &(__state)->readq;\
+   else\
+   __waitq = &(__state)->syncq;\
+   \
+   xnpipe_enqueue_wait(__state, __mask);   \
+   xnlock_put_irqrestore(&nklock, __s);\
\
prepare_to_wait_exclusive(__waitq, &__wait, TASK_INTERRUPTIBLE);\
\
-   if (__cond) \
-   xnpipe_dequeue_wait(__state, __mask);   \
-   else\
+   if (!__cond)\
schedule(); \
\
finish_wait(__waitq, &__wait);  \
@@ -127,25 +128,11 @@ static inline void xnpipe_enqueue_wait(x
\
/* Restore the interrupt state initially set by the caller. */  \
xnlock_get_irqsave(&nklock, __s);   \
+   xnpipe_dequeue_wait(__state, __mask);   \
\
__sigpending;   \
 })
 
-static inline void xnpipe_dequeue_wait(xnpipe_state_t *state, int mask)
-{
-   spl_t s;
-
-   xnlock_get_irqsave(&nklock, s);
-
-   if (testbits(state->status, mask)) {
-   if (--state->wcount == 0)
-   removeq(&xnpipe_sleepq, &state->slink);
-   __clrbits(st