[Xenomai-git] Gilles Chanteperdrix : cobalt/mutex: invalidate autoinit mutex upon fork
Module: xenomai-gch Branch: for-forge Commit: db98e93b961bd5d4f4a894f92786cb97a6417fdc URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=db98e93b961bd5d4f4a894f92786cb97a6417fdc Author: Gilles ChanteperdrixDate: Sun Oct 11 19:13:53 2015 +0200 cobalt/mutex: invalidate autoinit mutex upon fork In order to avoid an EBUSY error because the same mutex is reinitialized by the child process. --- lib/cobalt/mutex.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index f613478..daf0e3a 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -60,6 +60,8 @@ static pthread_mutex_t cobalt_autoinit_mutex; void cobalt_mutex_init(void) { + struct cobalt_mutex_shadow *_mutex = + &((union cobalt_mutex_union *)_autoinit_mutex)->shadow_mutex; pthread_mutexattr_t rt_init_mattr; int err __attribute__((unused)); @@ -67,6 +69,7 @@ void cobalt_mutex_init(void) pthread_mutexattr_init(_init_mattr); pthread_mutexattr_setprotocol(_init_mattr, PTHREAD_PRIO_INHERIT); + _mutex->magic = ~COBALT_MUTEX_MAGIC; err = __COBALT(pthread_mutex_init(_autoinit_mutex, _init_mattr)); assert(err == 0); ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork
Module: xenomai-gch Branch: for-forge Commit: c1438a3814958924f43d5ac278a02a57a61cb701 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=c1438a3814958924f43d5ac278a02a57a61cb701 Author: Gilles ChanteperdrixDate: Sun Oct 11 23:29:47 2015 +0200 cobalt/process: avoid crash at fork When handle_cleanup_event() is called because a thread is calling exec after a fork from a Xenomai process, handle_taskexit_event() is called before remove_process(). However, handle_taskexit_event() calls clear_threadinfo(), so that later calls to cobalt_current_process() return NULL, causing crashes in cleanup functions relying on cobalt_current_process() or cobalt_ppd_get(), such as cobalt_mutex_reclaim(). --- kernel/cobalt/posix/process.c | 29 ++--- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index e7f8a93..6c6f868 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process) * upon return from detach_process() for the Cobalt * personality, so don't dereference it afterwards. */ - process->priv[xid] = NULL; + if (xid) + process->priv[xid] = NULL; __clear_bit(personality->xid, >permap); personality->ops.detach_process(priv); atomic_dec(>refcnt); @@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread *thread) xnlock_put_irqrestore(, s); } -static int handle_taskexit_event(struct task_struct *p) /* p == current */ +static void __handle_taskexit_event(struct task_struct *p) { struct cobalt_ppd *sys_ppd; struct xnthread *thread; @@ -1033,16 +1034,22 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ cobalt_umm_free(_kernel_ppd.umm, thread->u_window); thread->u_window = NULL; sys_ppd = cobalt_ppd_get(0); - if (atomic_dec_and_test(_ppd->refcnt)) + if (atomic_dec_and_test(_ppd->refcnt)) { remove_process(cobalt_current_process()); + } } +} + +static int handle_taskexit_event(struct task_struct *p) /* p == current */ +{ + __handle_taskexit_event(p); /* * __xnthread_cleanup() -> ... -> finalize_thread * handler. From that point, the TCB is dropped. Be careful of * not treading on stale memory within @thread. */ - __xnthread_cleanup(thread); + __xnthread_cleanup(xnthread_current()); clear_threadinfo(); @@ -1198,6 +1205,8 @@ static int handle_cleanup_event(struct mm_struct *mm) old = cobalt_set_process(process); sys_ppd = cobalt_ppd_get(0); if (sys_ppd != _kernel_ppd) { + bool running_exec; + /* * Detect a userland shadow running exec(), i.e. still * attached to the current linux task (no prior @@ -1208,12 +1217,18 @@ static int handle_cleanup_event(struct mm_struct *mm) * notifier manually for it. */ thread = xnthread_current(); - if (thread && (current->flags & PF_EXITING) == 0) { - handle_taskexit_event(current); + running_exec = thread && (current->flags & PF_EXITING) == 0; + if (running_exec) { + __handle_taskexit_event(current); ipipe_disable_notifier(current); } - if (atomic_dec_and_test(_ppd->refcnt)) + if (atomic_dec_and_test(_ppd->refcnt)) { remove_process(process); + if (running_exec) { + __xnthread_cleanup(thread); + clear_threadinfo(); + } + } } /* ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : rtnet: add option to enable debug asserts
Module: xenomai-gch Branch: for-forge Commit: 3953b6b06189e784aca665cb66a91c7189a94b46 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=3953b6b06189e784aca665cb66a91c7189a94b46 Author: Gilles ChanteperdrixDate: Sun Oct 11 19:11:18 2015 +0200 rtnet: add option to enable debug asserts --- kernel/drivers/net/Kconfig | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kernel/drivers/net/Kconfig b/kernel/drivers/net/Kconfig index 6e63437..caffc1f 100644 --- a/kernel/drivers/net/Kconfig +++ b/kernel/drivers/net/Kconfig @@ -1,9 +1,18 @@ menu "RTnet" config XENO_DRIVERS_NET - depends on m - select NET - tristate "RTnet, TCP/IP socket interface" +depends on m +select NET +tristate "RTnet, TCP/IP socket interface" + +config XENO_DRIVERS_RTNET_CHECKED +bool "Internal Bug Checks" +default n +---help--- +Switch on if you face crashes when RTnet is running or if you suspect +any other RTnet-related issues. This feature will add a few sanity +checks at critical points that will produce warnings on the kernel +console in case certain internal bugs are detected. source "drivers/xenomai/net/stack/Kconfig" source "drivers/xenomai/net/drivers/Kconfig" ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/mutex: propagate autoinit error
Module: xenomai-gch Branch: for-forge Commit: 7e07d9f70171175cef5be1740f040fe5779d10e5 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=7e07d9f70171175cef5be1740f040fe5779d10e5 Author: Gilles ChanteperdrixDate: Sun Oct 11 19:14:55 2015 +0200 cobalt/mutex: propagate autoinit error instead of using assert. --- lib/cobalt/mutex.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index daf0e3a..0b62f4d 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -212,12 +212,19 @@ static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) pthread_mutexattr_init(); pthread_mutexattr_settype(, type); err = __COBALT(pthread_mutex_lock(_autoinit_mutex)); - assert(err = 0); + if (err) { + ret = err; + goto out; + } if (_mutex->magic != COBALT_MUTEX_MAGIC) ret = __COBALT(pthread_mutex_init(mutex, )); err = __COBALT(pthread_mutex_unlock(_autoinit_mutex)); - assert(err == 0); + if (err) { + if (ret == 0) + ret = err; + } + out: pthread_mutexattr_destroy(); return ret; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : copperplate/regd: do not involve Cobalt before binding is done
Module: xenomai-3 Branch: next Commit: e44620495d0b8f0d029250b44dfeef4a47dcd155 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e44620495d0b8f0d029250b44dfeef4a47dcd155 Author: Philippe GerumDate: Thu Oct 15 09:59:21 2015 +0200 copperplate/regd: do not involve Cobalt before binding is done Some early code in sysregd wants to set the regular scheduling policy of the main thread prior to binding to the Cobalt core manually. Make sure to force a libc call for this, instead of going through a Cobalt syscall first. Functionally speaking, the effect will be the same since pthread_setschedparam() mirrors the request to the regular C library, which is what we'll need eventually. However we won't receive the scary warning about a syscall being denied for an unbound process from the Cobalt core when debug mode is enabled, e.g.: [Xenomai] syscall <7> denied to sysregd[22217] --- lib/copperplate/regd/regd.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/copperplate/regd/regd.c b/lib/copperplate/regd/regd.c index 25bd7a5..5d69d83 100644 --- a/lib/copperplate/regd/regd.c +++ b/lib/copperplate/regd/regd.c @@ -538,7 +538,7 @@ int main(int argc, char *const *argv) /* Force SCHED_OTHER. */ schedp.sched_priority = 0; - pthread_setschedparam(pthread_self(), SCHED_OTHER, ); + __STD(pthread_setschedparam(pthread_self(), SCHED_OTHER, )); memset(, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/sched: bypass scheduler lock in irq
Module: xenomai-gch Branch: for-forge Commit: 64619238e48be6a1839e9b7d3accd19bd1dcf226 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=64619238e48be6a1839e9b7d3accd19bd1dcf226 Author: Gilles ChanteperdrixDate: Sun Oct 11 19:10:23 2015 +0200 cobalt/sched: bypass scheduler lock in irq When preempting a relaxed thread, in case the thread is in the middle of a call to xnthread_relax(). --- kernel/cobalt/sched.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c index 56014e0..792bb80 100644 --- a/kernel/cobalt/sched.c +++ b/kernel/cobalt/sched.c @@ -322,7 +322,8 @@ struct xnsched *xnsched_finish_unlocked_switch(struct xnsched *sched) void xnsched_lock(void) { - struct xnthread *curr = xnthread_current(); + struct xnsched *sched = xnsched_current(); + struct xnthread *curr = sched->curr; /* * CAUTION: The fast xnthread_current() accessor carries the @@ -333,8 +334,16 @@ void xnsched_lock(void) * Either way, we don't need to grab the super lock. */ if (unlikely(curr == NULL || xnthread_test_state(curr, XNRELAX))) { + /* +* In IRQ: scheduler already locked, and we may have +* interrupted xnthread_relax() where the BUG_ON condition is +* temporarily false. +*/ + if (sched->lflags & XNINIRQ) + return; + irqoff_only(); - curr = _current()->rootcb; + curr = >rootcb; XENO_BUG_ON(COBALT, xnsched_current()->curr != curr); } @@ -344,9 +353,16 @@ EXPORT_SYMBOL_GPL(xnsched_lock); void xnsched_unlock(void) { - struct xnthread *curr = xnthread_current(); + struct xnsched *sched = xnsched_current(); + struct xnthread *curr = sched->curr; if (unlikely(curr == NULL || xnthread_test_state(curr, XNRELAX))) { + /* +* In IRQ +*/ + if (sched->lflags & XNINIRQ) + return; + irqoff_only(); curr = _current()->rootcb; } ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork
Module: xenomai-gch Branch: for-forge Commit: 91315a0947ac7d002af6ad0447d0e870d44a6bfa URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=91315a0947ac7d002af6ad0447d0e870d44a6bfa Author: Gilles ChanteperdrixDate: Sun Oct 11 23:29:47 2015 +0200 cobalt/process: avoid crash at fork When handle_cleanup_event() is called because a thread is calling exec after a fork from a Xenomai process, handle_taskexit_event() is called before remove_process(). However, handle_taskexit_event() calls clear_threadinfo(), so that later calls to cobalt_current_process() return NULL, causing crashes in cleanup functions relying on cobalt_current_process() or cobalt_ppd_get(), such as cobalt_mutex_reclaim(). --- kernel/cobalt/posix/process.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index e7f8a93..c5a3297 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process) * upon return from detach_process() for the Cobalt * personality, so don't dereference it afterwards. */ - process->priv[xid] = NULL; + if (xid) + process->priv[xid] = NULL; __clear_bit(personality->xid, >permap); personality->ops.detach_process(priv); atomic_dec(>refcnt); @@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread *thread) xnlock_put_irqrestore(, s); } -static int handle_taskexit_event(struct task_struct *p) /* p == current */ +static void __handle_taskexit_event(struct task_struct *p) { struct cobalt_ppd *sys_ppd; struct xnthread *thread; @@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ if (atomic_dec_and_test(_ppd->refcnt)) remove_process(cobalt_current_process()); } +} + +static int handle_taskexit_event(struct task_struct *p) /* p == current */ +{ + __handle_taskexit_event(p); /* * __xnthread_cleanup() -> ... -> finalize_thread * handler. From that point, the TCB is dropped. Be careful of * not treading on stale memory within @thread. */ - __xnthread_cleanup(thread); + __xnthread_cleanup(xnthread_current()); clear_threadinfo(); @@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm) old = cobalt_set_process(process); sys_ppd = cobalt_ppd_get(0); if (sys_ppd != _kernel_ppd) { + bool running_exec; + /* * Detect a userland shadow running exec(), i.e. still * attached to the current linux task (no prior @@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm) * notifier manually for it. */ thread = xnthread_current(); - if (thread && (current->flags & PF_EXITING) == 0) { - handle_taskexit_event(current); + running_exec = thread && (current->flags & PF_EXITING) == 0; + if (running_exec) { + __handle_taskexit_event(current); ipipe_disable_notifier(current); } if (atomic_dec_and_test(_ppd->refcnt)) remove_process(process); + if (running_exec) { + __xnthread_cleanup(thread); + clear_threadinfo(); + } } /* ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork
Module: xenomai-gch Branch: for-forge Commit: 2840c876f0cf9c5da7b47cafd70646ea9ed64a13 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=2840c876f0cf9c5da7b47cafd70646ea9ed64a13 Author: Gilles ChanteperdrixDate: Sun Oct 11 23:29:47 2015 +0200 cobalt/process: avoid crash at fork When handle_cleanup_event() is called because a thread is calling exec after a fork from a Xenomai process, handle_taskexit_event() is called before remove_process(). However, handle_taskexit_event() calls clear_threadinfo(), so that later calls to cobalt_current_process() return NULL, causing crashes in cleanup functions relying on cobalt_current_process() or cobalt_ppd_get(), such as cobalt_mutex_reclaim(). --- kernel/cobalt/posix/process.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index e7f8a93..08d1477 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process) * upon return from detach_process() for the Cobalt * personality, so don't dereference it afterwards. */ - process->priv[xid] = NULL; + if (xid) + process->priv[xid] = NULL; __clear_bit(personality->xid, >permap); personality->ops.detach_process(priv); atomic_dec(>refcnt); @@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread *thread) xnlock_put_irqrestore(, s); } -static int handle_taskexit_event(struct task_struct *p) /* p == current */ +static void __handle_taskexit_event(struct task_struct *p) { struct cobalt_ppd *sys_ppd; struct xnthread *thread; @@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ if (atomic_dec_and_test(_ppd->refcnt)) remove_process(cobalt_current_process()); } +} + +static int handle_taskexit_event(struct task_struct *p) /* p == current */ +{ + __handle_taskexit_event(p); /* * __xnthread_cleanup() -> ... -> finalize_thread * handler. From that point, the TCB is dropped. Be careful of * not treading on stale memory within @thread. */ - __xnthread_cleanup(thread); + __xnthread_cleanup(p); clear_threadinfo(); @@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm) old = cobalt_set_process(process); sys_ppd = cobalt_ppd_get(0); if (sys_ppd != _kernel_ppd) { + bool running_exec; + /* * Detect a userland shadow running exec(), i.e. still * attached to the current linux task (no prior @@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm) * notifier manually for it. */ thread = xnthread_current(); - if (thread && (current->flags & PF_EXITING) == 0) { - handle_taskexit_event(current); + running_exec = thread && (current->flags & PF_EXITING) == 0; + if (running_exec) { + __handle_taskexit_event(current); ipipe_disable_notifier(current); } if (atomic_dec_and_test(_ppd->refcnt)) remove_process(process); + if (running_exec) { + __xnthread_cleanup(thread); + clear_threadinfo(); + } } /* ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/sched: bypass scheduler lock in irq
Module: xenomai-3 Branch: next Commit: 9a8be3bd8fdaca6654a7db16c886af7d508f5477 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=9a8be3bd8fdaca6654a7db16c886af7d508f5477 Author: Gilles ChanteperdrixDate: Sun Oct 11 19:10:23 2015 +0200 cobalt/sched: bypass scheduler lock in irq When preempting a relaxed thread, in case the thread is in the middle of a call to xnthread_relax(). --- kernel/cobalt/sched.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c index 56014e0..792bb80 100644 --- a/kernel/cobalt/sched.c +++ b/kernel/cobalt/sched.c @@ -322,7 +322,8 @@ struct xnsched *xnsched_finish_unlocked_switch(struct xnsched *sched) void xnsched_lock(void) { - struct xnthread *curr = xnthread_current(); + struct xnsched *sched = xnsched_current(); + struct xnthread *curr = sched->curr; /* * CAUTION: The fast xnthread_current() accessor carries the @@ -333,8 +334,16 @@ void xnsched_lock(void) * Either way, we don't need to grab the super lock. */ if (unlikely(curr == NULL || xnthread_test_state(curr, XNRELAX))) { + /* +* In IRQ: scheduler already locked, and we may have +* interrupted xnthread_relax() where the BUG_ON condition is +* temporarily false. +*/ + if (sched->lflags & XNINIRQ) + return; + irqoff_only(); - curr = _current()->rootcb; + curr = >rootcb; XENO_BUG_ON(COBALT, xnsched_current()->curr != curr); } @@ -344,9 +353,16 @@ EXPORT_SYMBOL_GPL(xnsched_lock); void xnsched_unlock(void) { - struct xnthread *curr = xnthread_current(); + struct xnsched *sched = xnsched_current(); + struct xnthread *curr = sched->curr; if (unlikely(curr == NULL || xnthread_test_state(curr, XNRELAX))) { + /* +* In IRQ +*/ + if (sched->lflags & XNINIRQ) + return; + irqoff_only(); curr = _current()->rootcb; } ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : rtnet: add option to enable debug asserts
Module: xenomai-3 Branch: next Commit: b27d15bb77bdf9163d1eb60aa5c9d7741e609f75 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=b27d15bb77bdf9163d1eb60aa5c9d7741e609f75 Author: Gilles ChanteperdrixDate: Sun Oct 11 19:11:18 2015 +0200 rtnet: add option to enable debug asserts --- kernel/drivers/net/Kconfig | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kernel/drivers/net/Kconfig b/kernel/drivers/net/Kconfig index 6e63437..caffc1f 100644 --- a/kernel/drivers/net/Kconfig +++ b/kernel/drivers/net/Kconfig @@ -1,9 +1,18 @@ menu "RTnet" config XENO_DRIVERS_NET - depends on m - select NET - tristate "RTnet, TCP/IP socket interface" +depends on m +select NET +tristate "RTnet, TCP/IP socket interface" + +config XENO_DRIVERS_RTNET_CHECKED +bool "Internal Bug Checks" +default n +---help--- +Switch on if you face crashes when RTnet is running or if you suspect +any other RTnet-related issues. This feature will add a few sanity +checks at critical points that will produce warnings on the kernel +console in case certain internal bugs are detected. source "drivers/xenomai/net/stack/Kconfig" source "drivers/xenomai/net/drivers/Kconfig" ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork
Module: xenomai-3 Branch: next Commit: e30f30df631fff143233732cf21756fe2f29c7dc URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e30f30df631fff143233732cf21756fe2f29c7dc Author: Gilles ChanteperdrixDate: Sun Oct 11 23:29:47 2015 +0200 cobalt/process: avoid crash at fork When handle_cleanup_event() is called because a thread is calling exec after a fork from a Xenomai process, handle_taskexit_event() is called before remove_process(). However, handle_taskexit_event() calls clear_threadinfo(), so that later calls to cobalt_current_process() return NULL, causing crashes in cleanup functions relying on cobalt_current_process() or cobalt_ppd_get(), such as cobalt_mutex_reclaim(). --- kernel/cobalt/posix/process.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index e7f8a93..c5a3297 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process) * upon return from detach_process() for the Cobalt * personality, so don't dereference it afterwards. */ - process->priv[xid] = NULL; + if (xid) + process->priv[xid] = NULL; __clear_bit(personality->xid, >permap); personality->ops.detach_process(priv); atomic_dec(>refcnt); @@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread *thread) xnlock_put_irqrestore(, s); } -static int handle_taskexit_event(struct task_struct *p) /* p == current */ +static void __handle_taskexit_event(struct task_struct *p) { struct cobalt_ppd *sys_ppd; struct xnthread *thread; @@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ if (atomic_dec_and_test(_ppd->refcnt)) remove_process(cobalt_current_process()); } +} + +static int handle_taskexit_event(struct task_struct *p) /* p == current */ +{ + __handle_taskexit_event(p); /* * __xnthread_cleanup() -> ... -> finalize_thread * handler. From that point, the TCB is dropped. Be careful of * not treading on stale memory within @thread. */ - __xnthread_cleanup(thread); + __xnthread_cleanup(xnthread_current()); clear_threadinfo(); @@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm) old = cobalt_set_process(process); sys_ppd = cobalt_ppd_get(0); if (sys_ppd != _kernel_ppd) { + bool running_exec; + /* * Detect a userland shadow running exec(), i.e. still * attached to the current linux task (no prior @@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm) * notifier manually for it. */ thread = xnthread_current(); - if (thread && (current->flags & PF_EXITING) == 0) { - handle_taskexit_event(current); + running_exec = thread && (current->flags & PF_EXITING) == 0; + if (running_exec) { + __handle_taskexit_event(current); ipipe_disable_notifier(current); } if (atomic_dec_and_test(_ppd->refcnt)) remove_process(process); + if (running_exec) { + __xnthread_cleanup(thread); + clear_threadinfo(); + } } /* ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/sched: bypass scheduler lock in irq
Module: xenomai-gch Branch: for-forge Commit: 9a8be3bd8fdaca6654a7db16c886af7d508f5477 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=9a8be3bd8fdaca6654a7db16c886af7d508f5477 Author: Gilles ChanteperdrixDate: Sun Oct 11 19:10:23 2015 +0200 cobalt/sched: bypass scheduler lock in irq When preempting a relaxed thread, in case the thread is in the middle of a call to xnthread_relax(). --- kernel/cobalt/sched.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c index 56014e0..792bb80 100644 --- a/kernel/cobalt/sched.c +++ b/kernel/cobalt/sched.c @@ -322,7 +322,8 @@ struct xnsched *xnsched_finish_unlocked_switch(struct xnsched *sched) void xnsched_lock(void) { - struct xnthread *curr = xnthread_current(); + struct xnsched *sched = xnsched_current(); + struct xnthread *curr = sched->curr; /* * CAUTION: The fast xnthread_current() accessor carries the @@ -333,8 +334,16 @@ void xnsched_lock(void) * Either way, we don't need to grab the super lock. */ if (unlikely(curr == NULL || xnthread_test_state(curr, XNRELAX))) { + /* +* In IRQ: scheduler already locked, and we may have +* interrupted xnthread_relax() where the BUG_ON condition is +* temporarily false. +*/ + if (sched->lflags & XNINIRQ) + return; + irqoff_only(); - curr = _current()->rootcb; + curr = >rootcb; XENO_BUG_ON(COBALT, xnsched_current()->curr != curr); } @@ -344,9 +353,16 @@ EXPORT_SYMBOL_GPL(xnsched_lock); void xnsched_unlock(void) { - struct xnthread *curr = xnthread_current(); + struct xnsched *sched = xnsched_current(); + struct xnthread *curr = sched->curr; if (unlikely(curr == NULL || xnthread_test_state(curr, XNRELAX))) { + /* +* In IRQ +*/ + if (sched->lflags & XNINIRQ) + return; + irqoff_only(); curr = _current()->rootcb; } ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : rtnet: fix reference count issues
Module: xenomai-gch Branch: for-forge Commit: be3bda5cf3e3908a4207221788bbbf96d61adbe1 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=be3bda5cf3e3908a4207221788bbbf96d61adbe1 Author: Gilles ChanteperdrixDate: Sun Oct 11 16:04:40 2015 +0200 rtnet: fix reference count issues --- kernel/drivers/net/stack/include/rtskb.h|3 +-- kernel/drivers/net/stack/ipv4/ip_input.c|1 + kernel/drivers/net/stack/rtmac/rtmac_vnic.c |5 + kernel/drivers/net/stack/rtskb.c| 17 - 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/net/stack/include/rtskb.h b/kernel/drivers/net/stack/include/rtskb.h index a6ef860..7489aa6 100644 --- a/kernel/drivers/net/stack/include/rtskb.h +++ b/kernel/drivers/net/stack/include/rtskb.h @@ -242,7 +242,6 @@ struct rtskb_pool_lock_ops { struct rtskb_pool { struct rtskb_queue queue; const struct rtskb_pool_lock_ops *lock_ops; -unsigned lock_count; void *lock_cookie; }; @@ -736,7 +735,7 @@ extern unsigned int __rtskb_module_pool_init(struct rtskb_pool *pool, #define rtskb_module_pool_init(pool, size) \ __rtskb_module_pool_init(pool, size, THIS_MODULE) -extern int rtskb_pool_release(struct rtskb_pool *pool); +extern void rtskb_pool_release(struct rtskb_pool *pool); extern unsigned int rtskb_pool_extend(struct rtskb_pool *pool, unsigned int add_rtskbs); diff --git a/kernel/drivers/net/stack/ipv4/ip_input.c b/kernel/drivers/net/stack/ipv4/ip_input.c index c9c871e..2d2a751 100644 --- a/kernel/drivers/net/stack/ipv4/ip_input.c +++ b/kernel/drivers/net/stack/ipv4/ip_input.c @@ -88,6 +88,7 @@ static inline void rt_ip_local_deliver(struct rtskb *skb) if (err) { kfree_rtskb(skb); + rt_socket_dereference(sock); return; } } diff --git a/kernel/drivers/net/stack/rtmac/rtmac_vnic.c b/kernel/drivers/net/stack/rtmac/rtmac_vnic.c index 510e714..3bdb760 100644 --- a/kernel/drivers/net/stack/rtmac/rtmac_vnic.c +++ b/kernel/drivers/net/stack/rtmac/rtmac_vnic.c @@ -286,12 +286,9 @@ int rtmac_vnic_add(struct rtnet_device *rtdev, vnic_xmit_handler vnic_xmit) int rtmac_vnic_unregister(struct rtnet_device *rtdev) { struct rtmac_priv *mac_priv = rtdev->mac_priv; -int err; if (mac_priv->vnic) { - err = rtskb_pool_release(_priv->vnic_skb_pool); - if (err < 0) - return err; + rtskb_pool_release(_priv->vnic_skb_pool); unregister_netdev(mac_priv->vnic); free_netdev(mac_priv->vnic); mac_priv->vnic = NULL; diff --git a/kernel/drivers/net/stack/rtskb.c b/kernel/drivers/net/stack/rtskb.c index 8afd6a6..f560902 100644 --- a/kernel/drivers/net/stack/rtskb.c +++ b/kernel/drivers/net/stack/rtskb.c @@ -156,14 +156,11 @@ static struct rtskb *__rtskb_pool_dequeue(struct rtskb_pool *pool) struct rtskb_queue *queue = >queue; struct rtskb *skb; -if (pool->lock_count == 0 && !pool->lock_ops->trylock(pool->lock_cookie)) +if (!pool->lock_ops->trylock(pool->lock_cookie)) return NULL; skb = __rtskb_dequeue(queue); -if (skb == NULL) { - if (pool->lock_count == 0) /* This can only happen if pool has 0 packets */ +if (skb == NULL) pool->lock_ops->unlock(pool->lock_cookie); -} else - ++pool->lock_count; return skb; } @@ -187,8 +184,7 @@ static void __rtskb_pool_queue_tail(struct rtskb_pool *pool, struct rtskb *skb) struct rtskb_queue *queue = >queue; __rtskb_queue_tail(queue,skb); -if (--pool->lock_count == 0) - pool->lock_ops->unlock(pool->lock_cookie); +pool->lock_ops->unlock(pool->lock_cookie); } void rtskb_pool_queue_tail(struct rtskb_pool *pool, struct rtskb *skb) @@ -332,7 +328,6 @@ unsigned int rtskb_pool_init(struct rtskb_pool *pool, rtskb_pools_max = rtskb_pools; pool->lock_ops = lock_ops ?: _nop_pool_lock_ops; -pool->lock_count = 0; pool->lock_cookie = lock_cookie; return i; @@ -372,13 +367,10 @@ EXPORT_SYMBOL_GPL(__rtskb_module_pool_init); * __rtskb_pool_release * @pool: pool to release */ -int rtskb_pool_release(struct rtskb_pool *pool) +void rtskb_pool_release(struct rtskb_pool *pool) { struct rtskb *skb; -if (pool->lock_count) - return -EBUSY; - while ((skb = rtskb_dequeue(>queue)) != NULL) { rtdev_unmap_rtskb(skb); kmem_cache_free(rtskb_slab_pool, skb); @@ -386,7 +378,6 @@ int rtskb_pool_release(struct rtskb_pool *pool) } rtskb_pools--; -return 0; } EXPORT_SYMBOL_GPL(rtskb_pool_release); ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/mutex: propagate autoinit error
Module: xenomai-3 Branch: next Commit: 67ae83b2f26ff7550e3390781bf9fe10b3aef41b URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=67ae83b2f26ff7550e3390781bf9fe10b3aef41b Author: Gilles ChanteperdrixDate: Sun Oct 11 19:14:55 2015 +0200 cobalt/mutex: propagate autoinit error instead of using assert. --- lib/cobalt/mutex.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index daf0e3a..0b62f4d 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -212,12 +212,19 @@ static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex) pthread_mutexattr_init(); pthread_mutexattr_settype(, type); err = __COBALT(pthread_mutex_lock(_autoinit_mutex)); - assert(err = 0); + if (err) { + ret = err; + goto out; + } if (_mutex->magic != COBALT_MUTEX_MAGIC) ret = __COBALT(pthread_mutex_init(mutex, )); err = __COBALT(pthread_mutex_unlock(_autoinit_mutex)); - assert(err == 0); + if (err) { + if (ret == 0) + ret = err; + } + out: pthread_mutexattr_destroy(); return ret; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/process: avoid crash at fork
Module: xenomai-gch Branch: for-forge Commit: e30f30df631fff143233732cf21756fe2f29c7dc URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=e30f30df631fff143233732cf21756fe2f29c7dc Author: Gilles ChanteperdrixDate: Sun Oct 11 23:29:47 2015 +0200 cobalt/process: avoid crash at fork When handle_cleanup_event() is called because a thread is calling exec after a fork from a Xenomai process, handle_taskexit_event() is called before remove_process(). However, handle_taskexit_event() calls clear_threadinfo(), so that later calls to cobalt_current_process() return NULL, causing crashes in cleanup functions relying on cobalt_current_process() or cobalt_ppd_get(), such as cobalt_mutex_reclaim(). --- kernel/cobalt/posix/process.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index e7f8a93..c5a3297 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -200,7 +200,8 @@ static void remove_process(struct cobalt_process *process) * upon return from detach_process() for the Cobalt * personality, so don't dereference it afterwards. */ - process->priv[xid] = NULL; + if (xid) + process->priv[xid] = NULL; __clear_bit(personality->xid, >permap); personality->ops.detach_process(priv); atomic_dec(>refcnt); @@ -1006,7 +1007,7 @@ static void unregister_debugged_thread(struct xnthread *thread) xnlock_put_irqrestore(, s); } -static int handle_taskexit_event(struct task_struct *p) /* p == current */ +static void __handle_taskexit_event(struct task_struct *p) { struct cobalt_ppd *sys_ppd; struct xnthread *thread; @@ -1036,13 +1037,18 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ if (atomic_dec_and_test(_ppd->refcnt)) remove_process(cobalt_current_process()); } +} + +static int handle_taskexit_event(struct task_struct *p) /* p == current */ +{ + __handle_taskexit_event(p); /* * __xnthread_cleanup() -> ... -> finalize_thread * handler. From that point, the TCB is dropped. Be careful of * not treading on stale memory within @thread. */ - __xnthread_cleanup(thread); + __xnthread_cleanup(xnthread_current()); clear_threadinfo(); @@ -1198,6 +1204,8 @@ static int handle_cleanup_event(struct mm_struct *mm) old = cobalt_set_process(process); sys_ppd = cobalt_ppd_get(0); if (sys_ppd != _kernel_ppd) { + bool running_exec; + /* * Detect a userland shadow running exec(), i.e. still * attached to the current linux task (no prior @@ -1208,12 +1216,17 @@ static int handle_cleanup_event(struct mm_struct *mm) * notifier manually for it. */ thread = xnthread_current(); - if (thread && (current->flags & PF_EXITING) == 0) { - handle_taskexit_event(current); + running_exec = thread && (current->flags & PF_EXITING) == 0; + if (running_exec) { + __handle_taskexit_event(current); ipipe_disable_notifier(current); } if (atomic_dec_and_test(_ppd->refcnt)) remove_process(process); + if (running_exec) { + __xnthread_cleanup(thread); + clear_threadinfo(); + } } /* ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/mutex: invalidate autoinit mutex upon fork
Module: xenomai-gch Branch: for-forge Commit: e55f70bc55ea8f408eabaa9aee635a4b0547294d URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=e55f70bc55ea8f408eabaa9aee635a4b0547294d Author: Gilles ChanteperdrixDate: Sun Oct 11 19:13:53 2015 +0200 cobalt/mutex: invalidate autoinit mutex upon fork In order to avoid an EBUSY error because the same mutex is reinitialized by the child process. --- lib/cobalt/mutex.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c index f613478..daf0e3a 100644 --- a/lib/cobalt/mutex.c +++ b/lib/cobalt/mutex.c @@ -60,6 +60,8 @@ static pthread_mutex_t cobalt_autoinit_mutex; void cobalt_mutex_init(void) { + struct cobalt_mutex_shadow *_mutex = + &((union cobalt_mutex_union *)_autoinit_mutex)->shadow_mutex; pthread_mutexattr_t rt_init_mattr; int err __attribute__((unused)); @@ -67,6 +69,7 @@ void cobalt_mutex_init(void) pthread_mutexattr_init(_init_mattr); pthread_mutexattr_setprotocol(_init_mattr, PTHREAD_PRIO_INHERIT); + _mutex->magic = ~COBALT_MUTEX_MAGIC; err = __COBALT(pthread_mutex_init(_autoinit_mutex, _init_mattr)); assert(err == 0); ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : rtnet: fix reference count issues
Module: xenomai-3 Branch: next Commit: be3bda5cf3e3908a4207221788bbbf96d61adbe1 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=be3bda5cf3e3908a4207221788bbbf96d61adbe1 Author: Gilles ChanteperdrixDate: Sun Oct 11 16:04:40 2015 +0200 rtnet: fix reference count issues --- kernel/drivers/net/stack/include/rtskb.h|3 +-- kernel/drivers/net/stack/ipv4/ip_input.c|1 + kernel/drivers/net/stack/rtmac/rtmac_vnic.c |5 + kernel/drivers/net/stack/rtskb.c| 17 - 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/kernel/drivers/net/stack/include/rtskb.h b/kernel/drivers/net/stack/include/rtskb.h index a6ef860..7489aa6 100644 --- a/kernel/drivers/net/stack/include/rtskb.h +++ b/kernel/drivers/net/stack/include/rtskb.h @@ -242,7 +242,6 @@ struct rtskb_pool_lock_ops { struct rtskb_pool { struct rtskb_queue queue; const struct rtskb_pool_lock_ops *lock_ops; -unsigned lock_count; void *lock_cookie; }; @@ -736,7 +735,7 @@ extern unsigned int __rtskb_module_pool_init(struct rtskb_pool *pool, #define rtskb_module_pool_init(pool, size) \ __rtskb_module_pool_init(pool, size, THIS_MODULE) -extern int rtskb_pool_release(struct rtskb_pool *pool); +extern void rtskb_pool_release(struct rtskb_pool *pool); extern unsigned int rtskb_pool_extend(struct rtskb_pool *pool, unsigned int add_rtskbs); diff --git a/kernel/drivers/net/stack/ipv4/ip_input.c b/kernel/drivers/net/stack/ipv4/ip_input.c index c9c871e..2d2a751 100644 --- a/kernel/drivers/net/stack/ipv4/ip_input.c +++ b/kernel/drivers/net/stack/ipv4/ip_input.c @@ -88,6 +88,7 @@ static inline void rt_ip_local_deliver(struct rtskb *skb) if (err) { kfree_rtskb(skb); + rt_socket_dereference(sock); return; } } diff --git a/kernel/drivers/net/stack/rtmac/rtmac_vnic.c b/kernel/drivers/net/stack/rtmac/rtmac_vnic.c index 510e714..3bdb760 100644 --- a/kernel/drivers/net/stack/rtmac/rtmac_vnic.c +++ b/kernel/drivers/net/stack/rtmac/rtmac_vnic.c @@ -286,12 +286,9 @@ int rtmac_vnic_add(struct rtnet_device *rtdev, vnic_xmit_handler vnic_xmit) int rtmac_vnic_unregister(struct rtnet_device *rtdev) { struct rtmac_priv *mac_priv = rtdev->mac_priv; -int err; if (mac_priv->vnic) { - err = rtskb_pool_release(_priv->vnic_skb_pool); - if (err < 0) - return err; + rtskb_pool_release(_priv->vnic_skb_pool); unregister_netdev(mac_priv->vnic); free_netdev(mac_priv->vnic); mac_priv->vnic = NULL; diff --git a/kernel/drivers/net/stack/rtskb.c b/kernel/drivers/net/stack/rtskb.c index 8afd6a6..f560902 100644 --- a/kernel/drivers/net/stack/rtskb.c +++ b/kernel/drivers/net/stack/rtskb.c @@ -156,14 +156,11 @@ static struct rtskb *__rtskb_pool_dequeue(struct rtskb_pool *pool) struct rtskb_queue *queue = >queue; struct rtskb *skb; -if (pool->lock_count == 0 && !pool->lock_ops->trylock(pool->lock_cookie)) +if (!pool->lock_ops->trylock(pool->lock_cookie)) return NULL; skb = __rtskb_dequeue(queue); -if (skb == NULL) { - if (pool->lock_count == 0) /* This can only happen if pool has 0 packets */ +if (skb == NULL) pool->lock_ops->unlock(pool->lock_cookie); -} else - ++pool->lock_count; return skb; } @@ -187,8 +184,7 @@ static void __rtskb_pool_queue_tail(struct rtskb_pool *pool, struct rtskb *skb) struct rtskb_queue *queue = >queue; __rtskb_queue_tail(queue,skb); -if (--pool->lock_count == 0) - pool->lock_ops->unlock(pool->lock_cookie); +pool->lock_ops->unlock(pool->lock_cookie); } void rtskb_pool_queue_tail(struct rtskb_pool *pool, struct rtskb *skb) @@ -332,7 +328,6 @@ unsigned int rtskb_pool_init(struct rtskb_pool *pool, rtskb_pools_max = rtskb_pools; pool->lock_ops = lock_ops ?: _nop_pool_lock_ops; -pool->lock_count = 0; pool->lock_cookie = lock_cookie; return i; @@ -372,13 +367,10 @@ EXPORT_SYMBOL_GPL(__rtskb_module_pool_init); * __rtskb_pool_release * @pool: pool to release */ -int rtskb_pool_release(struct rtskb_pool *pool) +void rtskb_pool_release(struct rtskb_pool *pool) { struct rtskb *skb; -if (pool->lock_count) - return -EBUSY; - while ((skb = rtskb_dequeue(>queue)) != NULL) { rtdev_unmap_rtskb(skb); kmem_cache_free(rtskb_slab_pool, skb); @@ -386,7 +378,6 @@ int rtskb_pool_release(struct rtskb_pool *pool) } rtskb_pools--; -return 0; } EXPORT_SYMBOL_GPL(rtskb_pool_release); ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : rtnet/udp: fix sendmsg error path
Module: xenomai-3 Branch: next Commit: c829dc9fcd83e139487227c1487ea220f833ab30 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=c829dc9fcd83e139487227c1487ea220f833ab30 Author: Gilles ChanteperdrixDate: Sun Oct 11 16:04:00 2015 +0200 rtnet/udp: fix sendmsg error path --- kernel/drivers/net/stack/ipv4/udp/udp.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c b/kernel/drivers/net/stack/ipv4/udp/udp.c index 1e6d5d7..e2923d6 100644 --- a/kernel/drivers/net/stack/ipv4/udp/udp.c +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c @@ -564,8 +564,10 @@ ssize_t rt_udp_sendmsg(struct rtdm_fd *fd, const struct msghdr *msg, int msg_fla } else { rtdm_lock_get_irqsave(_socket_base_lock, context); -if (sock->prot.inet.state != TCP_ESTABLISHED) +if (sock->prot.inet.state != TCP_ESTABLISHED) { + rtdm_lock_put_irqrestore(_socket_base_lock, context); return -ENOTCONN; + } daddr = sock->prot.inet.daddr; dport = sock->prot.inet.dport; ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git