[Xenomai-git] Gilles Chanteperdrix : nucleus: defer selector block deletion to an APC.
Module: xenomai-2.4 Branch: master Commit: 3d4e22a501b33979f3be98d6ed2e3947f2361567 URL: http://git.xenomai.org/?p=xenomai-2.4.git;a=commit;h=3d4e22a501b33979f3be98d6ed2e3947f2361567 Author: Gilles Chanteperdrix Date: Thu Nov 5 23:49:43 2009 +0100 nucleus: defer selector block deletion to an APC. Avoid creating reschedulings in the middle of xnpod_delete_thread. --- include/nucleus/select.h |5 +++ ksrc/nucleus/module.c| 19 +++-- ksrc/nucleus/pod.c |4 --- ksrc/nucleus/select.c| 64 ++ 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/include/nucleus/select.h b/include/nucleus/select.h index b098b63..20eefbe 100644 --- a/include/nucleus/select.h +++ b/include/nucleus/select.h @@ -41,6 +41,7 @@ struct xnselector { fd_set expected; fd_set pending; } fds [XNSELECT_MAX_TYPES]; + xnholder_t destroy_link; xnqueue_t bindings; /* only used by xnselector_destroy */ }; @@ -106,6 +107,10 @@ int xnselect(struct xnselector *selector, void xnselector_destroy(struct xnselector *selector); +int xnselect_mount(void); + +int xnselect_umount(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c index bc3bc59..cde32f9 100644 --- a/ksrc/nucleus/module.c +++ b/ksrc/nucleus/module.c @@ -34,6 +34,7 @@ #ifdef CONFIG_XENO_OPT_PERVASIVE #include #endif /* CONFIG_XENO_OPT_PERVASIVE */ +#include #include MODULE_DESCRIPTION("Xenomai nucleus"); @@ -1171,11 +1172,18 @@ int __init __xeno_sys_init(void) goto cleanup_arch; #endif /* CONFIG_XENO_OPT_PIPE */ +#ifdef CONFIG_XENO_OPT_SELECT + err = xnselect_mount(); + + if (err) + goto cleanup_pipe; +#endif /* CONFIG_XENO_OPT_SELECT */ + #ifdef CONFIG_XENO_OPT_PERVASIVE err = xnshadow_mount(); if (err) - goto cleanup_pipe; + goto cleanup_select; err = xnheap_mount(); @@ -1201,10 +1209,15 @@ int __init __xeno_sys_init(void) xnshadow_cleanup(); - cleanup_pipe: - + cleanup_select: #endif /* CONFIG_XENO_OPT_PERVASIVE */ +#ifdef CONFIG_XENO_OPT_SELECT + xnselect_umount(); + + cleanup_pipe: +#endif /* CONFIG_XENO_OPT_SELECT */ + #ifdef CONFIG_XENO_OPT_PIPE xnpipe_umount(); diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c index bee6a04..386f86a 100644 --- a/ksrc/nucleus/pod.c +++ b/ksrc/nucleus/pod.c @@ -1208,8 +1208,6 @@ void xnpod_delete_thread(xnthread_t *thread) #ifdef CONFIG_XENO_OPT_SELECT if (thread->selector) { xnselector_destroy(thread->selector); - xnheap_schedule_free(&kheap, thread->selector, -(xnholder_t *)thread->selector); thread->selector = NULL; } #endif /* CONFIG_XENO_OPT_SELECT */ @@ -1293,8 +1291,6 @@ void xnpod_abort_thread(xnthread_t *thread) if (!xnpod_current_p(thread)) xnpod_suspend_thread(thread, XNDORMANT, XN_INFINITE, XN_RELATIVE, NULL); xnpod_delete_thread(thread); - /* FIXME: in case thread has a selector, the xnfree(selector) - happens with nklock locked. */ xnlock_put_irqrestore(&nklock, s); } diff --git a/ksrc/nucleus/select.c b/ksrc/nucleus/select.c index 502e7f6..d63503f 100644 --- a/ksrc/nucleus/select.c +++ b/ksrc/nucleus/select.c @@ -53,6 +53,9 @@ #include #include /* For hweight_long */ +static xnqueue_t xnselectors; +static int xnselect_apc; + #define link2binding(baddr, memb) \ container_of(baddr, struct xnselect_binding, memb) @@ -388,28 +391,67 @@ EXPORT_SYMBOL(xnselect); */ void xnselector_destroy(struct xnselector *selector) { - xnholder_t *holder; spl_t s; + inith(&selector->destroy_link); xnlock_get_irqsave(&nklock, s); - while ((holder = getq(&selector->bindings))) { - struct xnselect_binding *binding; - struct xnselect *fd; + appendq(&xnselectors, &selector->destroy_link); + xnlock_put_irqrestore(&nklock, s); + + rthal_apc_schedule(xnselect_apc); +} +EXPORT_SYMBOL_GPL(xnselector_destroy); + +static void xnselector_destroy_loop(void *cookie) +{ + struct xnselector *selector; + xnholder_t *holder; + int resched; + spl_t s; - binding = link2binding(holder, slink); - fd = binding->fd; - removeq(&fd->bindings, &binding->link); + xnlock_get_irqsave(&nklock, s); + while ((holder = getq(&xnselectors))) { + selector = container_of(holder, struct xnselector, destroy_link); + while ((holder = getq(&selector->bindings))) { + struct xnselect_binding *binding; + struct xnselect *fd; + + binding = link2bindi
[Xenomai-git] Gilles Chanteperdrix : nucleus: defer selector block deletion to an APC.
Module: xenomai-gch Branch: for-2.4 Commit: 3d4e22a501b33979f3be98d6ed2e3947f2361567 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=3d4e22a501b33979f3be98d6ed2e3947f2361567 Author: Gilles Chanteperdrix Date: Thu Nov 5 23:49:43 2009 +0100 nucleus: defer selector block deletion to an APC. Avoid creating reschedulings in the middle of xnpod_delete_thread. --- include/nucleus/select.h |5 +++ ksrc/nucleus/module.c| 19 +++-- ksrc/nucleus/pod.c |4 --- ksrc/nucleus/select.c| 64 ++ 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/include/nucleus/select.h b/include/nucleus/select.h index b098b63..20eefbe 100644 --- a/include/nucleus/select.h +++ b/include/nucleus/select.h @@ -41,6 +41,7 @@ struct xnselector { fd_set expected; fd_set pending; } fds [XNSELECT_MAX_TYPES]; + xnholder_t destroy_link; xnqueue_t bindings; /* only used by xnselector_destroy */ }; @@ -106,6 +107,10 @@ int xnselect(struct xnselector *selector, void xnselector_destroy(struct xnselector *selector); +int xnselect_mount(void); + +int xnselect_umount(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c index bc3bc59..cde32f9 100644 --- a/ksrc/nucleus/module.c +++ b/ksrc/nucleus/module.c @@ -34,6 +34,7 @@ #ifdef CONFIG_XENO_OPT_PERVASIVE #include #endif /* CONFIG_XENO_OPT_PERVASIVE */ +#include #include MODULE_DESCRIPTION("Xenomai nucleus"); @@ -1171,11 +1172,18 @@ int __init __xeno_sys_init(void) goto cleanup_arch; #endif /* CONFIG_XENO_OPT_PIPE */ +#ifdef CONFIG_XENO_OPT_SELECT + err = xnselect_mount(); + + if (err) + goto cleanup_pipe; +#endif /* CONFIG_XENO_OPT_SELECT */ + #ifdef CONFIG_XENO_OPT_PERVASIVE err = xnshadow_mount(); if (err) - goto cleanup_pipe; + goto cleanup_select; err = xnheap_mount(); @@ -1201,10 +1209,15 @@ int __init __xeno_sys_init(void) xnshadow_cleanup(); - cleanup_pipe: - + cleanup_select: #endif /* CONFIG_XENO_OPT_PERVASIVE */ +#ifdef CONFIG_XENO_OPT_SELECT + xnselect_umount(); + + cleanup_pipe: +#endif /* CONFIG_XENO_OPT_SELECT */ + #ifdef CONFIG_XENO_OPT_PIPE xnpipe_umount(); diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c index bee6a04..386f86a 100644 --- a/ksrc/nucleus/pod.c +++ b/ksrc/nucleus/pod.c @@ -1208,8 +1208,6 @@ void xnpod_delete_thread(xnthread_t *thread) #ifdef CONFIG_XENO_OPT_SELECT if (thread->selector) { xnselector_destroy(thread->selector); - xnheap_schedule_free(&kheap, thread->selector, -(xnholder_t *)thread->selector); thread->selector = NULL; } #endif /* CONFIG_XENO_OPT_SELECT */ @@ -1293,8 +1291,6 @@ void xnpod_abort_thread(xnthread_t *thread) if (!xnpod_current_p(thread)) xnpod_suspend_thread(thread, XNDORMANT, XN_INFINITE, XN_RELATIVE, NULL); xnpod_delete_thread(thread); - /* FIXME: in case thread has a selector, the xnfree(selector) - happens with nklock locked. */ xnlock_put_irqrestore(&nklock, s); } diff --git a/ksrc/nucleus/select.c b/ksrc/nucleus/select.c index 502e7f6..d63503f 100644 --- a/ksrc/nucleus/select.c +++ b/ksrc/nucleus/select.c @@ -53,6 +53,9 @@ #include #include /* For hweight_long */ +static xnqueue_t xnselectors; +static int xnselect_apc; + #define link2binding(baddr, memb) \ container_of(baddr, struct xnselect_binding, memb) @@ -388,28 +391,67 @@ EXPORT_SYMBOL(xnselect); */ void xnselector_destroy(struct xnselector *selector) { - xnholder_t *holder; spl_t s; + inith(&selector->destroy_link); xnlock_get_irqsave(&nklock, s); - while ((holder = getq(&selector->bindings))) { - struct xnselect_binding *binding; - struct xnselect *fd; + appendq(&xnselectors, &selector->destroy_link); + xnlock_put_irqrestore(&nklock, s); + + rthal_apc_schedule(xnselect_apc); +} +EXPORT_SYMBOL_GPL(xnselector_destroy); + +static void xnselector_destroy_loop(void *cookie) +{ + struct xnselector *selector; + xnholder_t *holder; + int resched; + spl_t s; - binding = link2binding(holder, slink); - fd = binding->fd; - removeq(&fd->bindings, &binding->link); + xnlock_get_irqsave(&nklock, s); + while ((holder = getq(&xnselectors))) { + selector = container_of(holder, struct xnselector, destroy_link); + while ((holder = getq(&selector->bindings))) { + struct xnselect_binding *binding; + struct xnselect *fd; + + binding = link2bind
[Xenomai-git] Gilles Chanteperdrix : nucleus: defer selector block deletion to an APC.
Module: xenomai-gch Branch: for-head Commit: 36247dec656766b6eebb481462c5019097892e05 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=36247dec656766b6eebb481462c5019097892e05 Author: Gilles Chanteperdrix Date: Thu Nov 5 23:49:43 2009 +0100 nucleus: defer selector block deletion to an APC. Avoid creating reschedulings in the middle of xnpod_delete_thread. --- include/nucleus/select.h |5 +++ ksrc/nucleus/module.c| 18 ++-- ksrc/nucleus/pod.c |4 -- ksrc/nucleus/select.c| 69 - 4 files changed, 75 insertions(+), 21 deletions(-) diff --git a/include/nucleus/select.h b/include/nucleus/select.h index b098b63..20eefbe 100644 --- a/include/nucleus/select.h +++ b/include/nucleus/select.h @@ -41,6 +41,7 @@ struct xnselector { fd_set expected; fd_set pending; } fds [XNSELECT_MAX_TYPES]; + xnholder_t destroy_link; xnqueue_t bindings; /* only used by xnselector_destroy */ }; @@ -106,6 +107,10 @@ int xnselect(struct xnselector *selector, void xnselector_destroy(struct xnselector *selector); +int xnselect_mount(void); + +int xnselect_umount(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c index 141276a..620ee9b 100644 --- a/ksrc/nucleus/module.c +++ b/ksrc/nucleus/module.c @@ -33,6 +33,7 @@ #ifdef CONFIG_XENO_OPT_PIPE #include #endif /* CONFIG_XENO_OPT_PIPE */ +#include #include MODULE_DESCRIPTION("Xenomai nucleus"); @@ -115,10 +116,16 @@ int __init __xeno_sys_init(void) goto cleanup_proc; #endif /* CONFIG_XENO_OPT_PIPE */ +#ifdef CONFIG_XENO_OPT_SELECT + ret = xnselect_mount(); + if (ret) + goto cleanup_pipe; +#endif /* CONFIG_XENO_OPT_SELECT */ + #ifdef CONFIG_XENO_OPT_PERVASIVE ret = xnshadow_mount(); if (ret) - goto cleanup_pipe; + goto cleanup_select; ret = xnheap_mount(); if (ret) @@ -151,10 +158,15 @@ int __init __xeno_sys_init(void) xnshadow_cleanup(); - cleanup_pipe: - + cleanup_select: #endif /* CONFIG_XENO_OPT_PERVASIVE */ +#ifdef CONFIG_XENO_OPT_SELECT + xnselect_umount(); + + cleanup_pipe: +#endif CONFIG_XENO_OPT_SELECT + #ifdef CONFIG_XENO_OPT_PIPE xnpipe_umount(); diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c index 77c69fd..7daf0f7 100644 --- a/ksrc/nucleus/pod.c +++ b/ksrc/nucleus/pod.c @@ -1190,8 +1190,6 @@ void xnpod_delete_thread(xnthread_t *thread) #ifdef CONFIG_XENO_OPT_SELECT if (thread->selector) { xnselector_destroy(thread->selector); - xnheap_schedule_free(&kheap, thread->selector, -(xnholder_t *)thread->selector); thread->selector = NULL; } #endif /* CONFIG_XENO_OPT_SELECT */ @@ -1284,8 +1282,6 @@ void xnpod_abort_thread(xnthread_t *thread) XN_INFINITE, XN_RELATIVE, NULL); xnthread_set_info(thread, XNABORT); xnpod_delete_thread(thread); - /* FIXME: in case thread has a selector, the xnfree(selector) - happens with nklock locked. */ xnlock_put_irqrestore(&nklock, s); } EXPORT_SYMBOL_GPL(xnpod_abort_thread); diff --git a/ksrc/nucleus/select.c b/ksrc/nucleus/select.c index 10355bf..fd56bfb 100644 --- a/ksrc/nucleus/select.c +++ b/ksrc/nucleus/select.c @@ -53,6 +53,9 @@ #include #include /* For hweight_long */ +static xnqueue_t xnselectors; +static int xnselect_apc; + #define link2binding(baddr, memb) \ container_of(baddr, struct xnselect_binding, memb) @@ -388,29 +391,67 @@ EXPORT_SYMBOL_GPL(xnselect); */ void xnselector_destroy(struct xnselector *selector) { - xnholder_t *holder; spl_t s; + inith(&selector->destroy_link); xnlock_get_irqsave(&nklock, s); - while ((holder = getq(&selector->bindings))) { - struct xnselect_binding *binding; - struct xnselect *fd; - spl_t dummy; + appendq(&xnselectors, &selector->destroy_link); + xnlock_put_irqrestore(&nklock, s); - binding = link2binding(holder, slink); - fd = binding->fd; - removeq(&fd->bindings, &binding->link); - xnlock_clear_irqon(&nklock); + rthal_apc_schedule(xnselect_apc); +} +EXPORT_SYMBOL_GPL(xnselector_destroy); - xnfree(binding); +static void xnselector_destroy_loop(void *cookie) +{ + struct xnselector *selector; + xnholder_t *holder; + int resched; + spl_t s; - xnlock_get_irqsave(&nklock, dummy); + xnlock_get_irqsave(&nklock, s); + while ((holder = getq(&xnselectors))) { + selector = container_of(holder, struct xnselector, destroy_link); + while ((holder = ge