[Xenomai-core] [PATCH v3 19/24] RTIPC: Drop unused wrapper around close_lock_count
From: Jan Kiszka CC: Philippe Gerum Signed-off-by: Jan Kiszka --- ksrc/drivers/ipc/internal.h |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/ksrc/drivers/ipc/internal.h b/ksrc/drivers/ipc/internal.h index 296a988..ed8c103 100644 --- a/ksrc/drivers/ipc/internal.h +++ b/ksrc/drivers/ipc/internal.h @@ -127,9 +127,4 @@ extern struct xnptree rtipc_ptree; #define rtipc_enter_atomic(lockctx)xnlock_get_irqsave(&nklock, (lockctx)) #define rtipc_leave_atomic(lockctx)xnlock_put_irqrestore(&nklock, (lockctx)) -static inline int rtipc_socket_locked(struct rtdm_dev_context *context) -{ - return atomic_read(&context->close_lock_count); -} - #endif /* !_RTIPC_INTERNAL_H */ -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 17/24] rttest: Resolved test device conflicts via separate name spaces
From: Jan Kiszka Usually, all devices of some RTDM class use the same naming scheme. But as test devices are different as they do not provide compatible APIs, let's give them separate name space for their device names. That finally resolves all the detection troubles that showed up once more than one test device was registered. To allow addressing old drivers with new user space and vice versa, a config switch is added to the former to select the naming scheme, and the latter will try to open under both names. Signed-off-by: Jan Kiszka --- include/rtdm/rttesting.h | 10 +++--- ksrc/drivers/testing/Config.in|2 ++ ksrc/drivers/testing/Kconfig |9 + ksrc/drivers/testing/irqbench.c |9 +++-- ksrc/drivers/testing/klat.c |8 +++- ksrc/drivers/testing/switchtest.c |7 ++- ksrc/drivers/testing/timerbench.c |7 ++- src/testsuite/irqbench/irqloop.c | 11 ++- src/testsuite/latency/latency.c | 12 +++- src/testsuite/switchtest/switchtest.c | 13 - 10 files changed, 77 insertions(+), 11 deletions(-) diff --git a/include/rtdm/rttesting.h b/include/rtdm/rttesting.h index ce0418e..56df43b 100644 --- a/include/rtdm/rttesting.h +++ b/include/rtdm/rttesting.h @@ -29,13 +29,14 @@ * Feel free to comment on this profile via the Xenomai mailing list * (xenomai-core@gna.org) or directly to the author (jan.kis...@web.de). * - * @b Profile @b Revision: 1 + * @b Profile @b Revision: 2 * @n * @n * @par Device Characteristics * @ref rtdm_device.device_flags "Device Flags": @c RTDM_NAMED_DEVICE @n * @n - * @ref rtdm_device.device_name "Device Name": @c "rttest", N >= 0 @n + * @ref rtdm_device.device_name "Device Name": @c "rttest[-]", + * N >= 0, optional subclass name to simplify device discovery @n * @n * @ref rtdm_device.device_class "Device Class": @c RTDM_CLASS_TESTING @n * @n @@ -61,7 +62,7 @@ #include -#define RTTST_PROFILE_VER 1 +#define RTTST_PROFILE_VER 2 typedef struct rttst_bench_res { long long avg; @@ -145,8 +146,11 @@ struct rttst_swtest_error { /*! * @name Sub-Classes of RTDM_CLASS_TESTING * @{ */ +/** subclass name: "tmbench" */ #define RTDM_SUBCLASS_TIMERBENCH 0 +/** subclass name: "irqbench" */ #define RTDM_SUBCLASS_IRQBENCH 1 +/** subclass name: "switchtst" */ #define RTDM_SUBCLASS_SWITCHTEST 2 /** @} */ diff --git a/ksrc/drivers/testing/Config.in b/ksrc/drivers/testing/Config.in index 07bd900..3552670 100644 --- a/ksrc/drivers/testing/Config.in +++ b/ksrc/drivers/testing/Config.in @@ -5,6 +5,8 @@ mainmenu_option next_comment comment 'Testing drivers' +bool 'Use legacy names for testing drivers' CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES $CONFIG_XENO_SKIN_RTDM + dep_tristate 'Timer benchmark driver' CONFIG_XENO_DRIVERS_TIMERBENCH $CONFIG_XENO_SKIN_RTDM dep_tristate 'IRQ benchmark driver' CONFIG_XENO_DRIVERS_IRQBENCH $CONFIG_XENO_SKIN_RTDM diff --git a/ksrc/drivers/testing/Kconfig b/ksrc/drivers/testing/Kconfig index 7ca2eb1..05d6a49 100644 --- a/ksrc/drivers/testing/Kconfig +++ b/ksrc/drivers/testing/Kconfig @@ -4,6 +4,15 @@ config XENO_TESTING_MODULE depends on MODULES def_tristate m +config XENO_DRIVERS_TESTING_LEGACY_NAMES + depends on XENO_SKIN_RTDM + bool "Use legacy names for testing drivers" + help + This lets the testing drivers register under legacy names + ("rttest") instead of the new scheme ("rttest-"). + Only enable this if you plan to use old userspace tools with the + drivers. + config XENO_DRIVERS_TIMERBENCH depends on XENO_SKIN_RTDM tristate "Timer benchmark driver" diff --git a/ksrc/drivers/testing/irqbench.c b/ksrc/drivers/testing/irqbench.c index 3dfb646..ab9686a 100644 --- a/ksrc/drivers/testing/irqbench.c +++ b/ksrc/drivers/testing/irqbench.c @@ -515,8 +515,13 @@ static int __init __irqbench_init(void) int err; do { - snprintf(device.device_name, RTDM_MAX_DEVNAME_LEN, "rttest%d", -start_index); + snprintf(device.device_name, RTDM_MAX_DEVNAME_LEN, +#ifdef CONFIG_XENO_DRIVERS_TESTING_LEGACY_NAMES +"rttest%d", +#else +"rttest-irqbench%d", +#endif + start_index); err = rtdm_dev_register(&device); start_index++; diff --git a/ksrc/drivers/testing/klat.c b/ksrc/drivers/testing/klat.c index 6070c26..ac4d680 100644 --- a/ksrc/drivers/testing/klat.c +++ b/ksrc/drivers/testing/klat.c @@ -99,7 +99,13 @@ static int __init klat_mod_init(void) pkt.config.freeze_max = freeze_max; for (dev_nr = 0; dev_nr < DEV_NR_MAX; dev_nr++) { - snprintf(devname, sizeof(devname), "rttest%d", dev_nr); + snprintf(devname, sizeof(devname), +#ifdef CONFIG_XENO_DRIVERS_TESTI
[Xenomai-core] [PATCH v3 20/24] RTDM: Document device close procedure
From: Jan Kiszka Interating over the close handler when it returns -EAGAIN or in case a pending reference to the device context exists is RTDM practice since day one. Documenting this is seriously overdue. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/rtdm/rtdm_driver.h | 11 +-- 1 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index 3f79abc..bd8a9d0 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -193,11 +193,18 @@ typedef int (*rtdm_socket_handler_t)(struct rtdm_dev_context *context, * * @param[in] context Context structure associated with opened device instance * @param[in] user_info Opaque pointer to information about user mode caller, - * NULL if kernel mode call + * NULL if kernel mode or deferred user mode call * * @return 0 on success. On failure return either -ENOSYS, to request that * this handler be called again from the opposite realtime/non-realtime - * context, or another negative error code. + * context, -EAGAIN to request a recall after a grace period, or a valid + * negative error code according to IEEE Std 1003.1. + * + * @note Drivers must be prepared for that case that the close handler is + * invoked more than once per open context (even if the handler already + * completed an earlier run successfully). The driver has to avoid releasing + * resources twice as well as returning false errors on successive close + * invocations. * * @see @c close() in IEEE Std 1003.1, * http://www.opengroup.org/onlinepubs/009695399 */ -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 14/24] irqbench: Fix x86-64 build
From: Jan Kiszka Signed-off-by: Jan Kiszka --- configure.in |2 +- src/testsuite/irqbench/Makefile.am |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 0228f51..9d6fe35 100644 --- a/configure.in +++ b/configure.in @@ -127,7 +127,7 @@ case "$build_for" in esac AC_MSG_RESULT([$XENO_TARGET_ARCH]) -AM_CONDITIONAL(XENO_LINUX_ARCH_I386,[test $XENO_LINUX_ARCH = i386]) +AM_CONDITIONAL(XENO_TARGET_ARCH_X86,[test $XENO_TARGET_ARCH = x86]) case "$XENO_TARGET_ARCH" in nios2) diff --git a/src/testsuite/irqbench/Makefile.am b/src/testsuite/irqbench/Makefile.am index 27c5ddb..3e531c7 100644 --- a/src/testsuite/irqbench/Makefile.am +++ b/src/testsuite/irqbench/Makefile.am @@ -5,7 +5,7 @@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) test_PROGRAMS = irqloop -if XENO_LINUX_ARCH_I386 +if XENO_TARGET_ARCH_X86 test_PROGRAMS += irqbench endif -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 05/24] RTDM: Deprecate open_rt, socket_rt, and close_rt
From: Jan Kiszka Support for RTDM device creation and destruction in RT context will be removed in the future. Start warning the users about this when loading a driver that makes use of it. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/rtdm/rtdm_driver.h | 12 +--- ksrc/skins/rtdm/API.CHANGES |2 ++ ksrc/skins/rtdm/device.c| 13 - 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index 45be404..7d5983c 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -328,7 +328,8 @@ typedef int (*rtdm_rt_handler_t)(struct rtdm_dev_context *context, struct rtdm_operations { /*! @name Common Operations * @{ */ - /** Close handler for real-time contexts (optional) */ + /** Close handler for real-time contexts (optional, deprecated) +* @deprecated Only use non-real-time close handler in new drivers. */ rtdm_close_handler_t close_rt; /** Close handler for non-real-time contexts (required) */ rtdm_close_handler_t close_nrt; @@ -468,14 +469,19 @@ struct rtdm_device { int socket_type; /** Named device instance creation for real-time contexts, -* optional if open_nrt is non-NULL, ignored for protocol devices */ +* optional (but deprecated) if open_nrt is non-NULL, ignored for +* protocol devices +* @deprecated Only use non-real-time open handler in new drivers. */ rtdm_open_handler_t open_rt; /** Named device instance creation for non-real-time contexts, * optional if open_rt is non-NULL, ignored for protocol devices */ rtdm_open_handler_t open_nrt; /** Protocol socket creation for real-time contexts, -* optional if socket_nrt is non-NULL, ignored for named devices */ +* optional (but deprecated) if socket_nrt is non-NULL, ignored for +* named devices +* @deprecated Only use non-real-time socket creation handler in new +* drivers. */ rtdm_socket_handler_t socket_rt; /** Protocol socket creation for non-real-time contexts, * optional if socket_rt is non-NULL, ignored for named devices */ diff --git a/ksrc/skins/rtdm/API.CHANGES b/ksrc/skins/rtdm/API.CHANGES index 84487f7..64a4b38 100644 --- a/ksrc/skins/rtdm/API.CHANGES +++ b/ksrc/skins/rtdm/API.CHANGES @@ -4,6 +4,8 @@ Scheduled modifications (unsorted): o Threaded IRQ handlers. o Support for deferring IRQ line re-enabling from handler to thread context. o Support for user-space drivers. + o Removal of open_rt, socket_rt, and close_rt, ie. support for device + creation and destruction in RT context. Revision 8: o Added rtdm_rt_capable. diff --git a/ksrc/skins/rtdm/device.c b/ksrc/skins/rtdm/device.c index e927ce7..3955bc0 100644 --- a/ksrc/skins/rtdm/device.c +++ b/ksrc/skins/rtdm/device.c @@ -219,6 +219,10 @@ int rtdm_dev_register(struct rtdm_device *device) XENO_ASSERT(RTDM, ANY_HANDLER(*device, open), xnlogerr("RTDM: missing open handler\n"); return -EINVAL;); + if (device->open_rt && + device->socket_rt != (void *)rtdm_no_support) + xnlogerr("RTDM: RT open handler is deprecated, " +"driver requires update.\n"); SET_DEFAULT_OP_IF_NULL(*device, open); SET_DEFAULT_OP(*device, socket); break; @@ -228,6 +232,10 @@ int rtdm_dev_register(struct rtdm_device *device) XENO_ASSERT(RTDM, ANY_HANDLER(*device, socket), xnlogerr("RTDM: missing socket handler\n"); return -EINVAL;); + if (device->socket_rt && + device->socket_rt != (void *)rtdm_no_support) + xnlogerr("RTDM: RT socket creation handler is " +"deprecated, driver requires update.\n"); SET_DEFAULT_OP_IF_NULL(*device, socket); SET_DEFAULT_OP(*device, open); break; @@ -242,7 +250,10 @@ int rtdm_dev_register(struct rtdm_device *device) xnlogerr("RTDM: missing non-RT close handler\n"); return -EINVAL; } - if (!device->ops.close_rt) + if (device->ops.close_rt) + xnlogerr("RTDM: RT close handler is deprecated, driver " +"requires update.\n"); + else device->ops.close_rt = (void *)rtdm_no_support; SET_DEFAULT_OP_IF_NULL(device->ops, ioctl); -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 04/24] Revert "rtdm: tag syscalls as conforming"
From: Jan Kiszka This reverts commit 13bfdd477ab880499d2e8f3b82c49ef4d2cccff0. We better let the driver trigger the confoming switch once it detects such a case by using the new service rtdm_rt_capable(). Always being comforming caused regressions for existing designs. CC: Philippe Gerum CC: Alexis Berlemont Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/syscall.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ksrc/skins/rtdm/syscall.c b/ksrc/skins/rtdm/syscall.c index d869887..80785ab 100644 --- a/ksrc/skins/rtdm/syscall.c +++ b/ksrc/skins/rtdm/syscall.c @@ -154,14 +154,14 @@ static xnsysent_t __systab[] = { [__rtdm_close] = {sys_rtdm_close, __xn_exec_current | __xn_exec_adaptive}, [__rtdm_ioctl] = - {sys_rtdm_ioctl, __xn_exec_conforming | __xn_exec_adaptive}, - [__rtdm_read] = {sys_rtdm_read, __xn_exec_conforming | __xn_exec_adaptive}, + {sys_rtdm_ioctl, __xn_exec_current | __xn_exec_adaptive}, + [__rtdm_read] = {sys_rtdm_read, __xn_exec_current | __xn_exec_adaptive}, [__rtdm_write] = - {sys_rtdm_write, __xn_exec_conforming | __xn_exec_adaptive}, + {sys_rtdm_write, __xn_exec_current | __xn_exec_adaptive}, [__rtdm_recvmsg] = - {sys_rtdm_recvmsg, __xn_exec_conforming | __xn_exec_adaptive}, + {sys_rtdm_recvmsg, __xn_exec_current | __xn_exec_adaptive}, [__rtdm_sendmsg] = - {sys_rtdm_sendmsg, __xn_exec_conforming | __xn_exec_adaptive}, + {sys_rtdm_sendmsg, __xn_exec_current | __xn_exec_adaptive}, }; static struct xnskin_props __props = { -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 01/24] RTDM: Fix potential NULL pointer dereference
From: Wolfgang Mauerer The rework in 95278926edc559d4 misses the case that context can be NULL, which can (and has) triggered a kernel oops. Take care of this case. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/core.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/ksrc/skins/rtdm/core.c b/ksrc/skins/rtdm/core.c index 8677c47..8cccf52 100644 --- a/ksrc/skins/rtdm/core.c +++ b/ksrc/skins/rtdm/core.c @@ -175,7 +175,7 @@ static int cleanup_instance(struct rtdm_device *device, xnlock_get_irqsave(&rt_fildes_lock, s); - if (unlikely(atomic_read(&context->close_lock_count) > 1)) { + if (context && unlikely(atomic_read(&context->close_lock_count) > 1)) { xnlock_put_irqrestore(&rt_fildes_lock, s); return -EAGAIN; } -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 03/24] RTDM: Bump API version and document changes
From: Jan Kiszka Signed-off-by: Jan Kiszka --- include/rtdm/rtdm.h |4 ++-- ksrc/skins/rtdm/API.CHANGES |6 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/rtdm/rtdm.h b/include/rtdm/rtdm.h index 6e02083..1e6e41e 100644 --- a/include/rtdm/rtdm.h +++ b/include/rtdm/rtdm.h @@ -31,7 +31,7 @@ * RT/non-RT systems like Xenomai. RTDM conforms to POSIX * semantics (IEEE Std 1003.1) where available and applicable. * - * @b API @b Revision: 7 + * @b API @b Revision: 8 */ /*! @@ -76,7 +76,7 @@ typedef struct task_struct rtdm_user_info_t; * @anchor api_versioning @name API Versioning * @{ */ /** Common user and driver API version */ -#define RTDM_API_VER 7 +#define RTDM_API_VER 8 /** Minimum API revision compatible with the current release */ #define RTDM_API_MIN_COMPAT_VER6 diff --git a/ksrc/skins/rtdm/API.CHANGES b/ksrc/skins/rtdm/API.CHANGES index ca9012b..84487f7 100644 --- a/ksrc/skins/rtdm/API.CHANGES +++ b/ksrc/skins/rtdm/API.CHANGES @@ -5,6 +5,12 @@ Scheduled modifications (unsorted): o Support for deferring IRQ line re-enabling from handler to thread context. o Support for user-space drivers. +Revision 8: + o Added rtdm_rt_capable. + +Revision 7: + o Added callbacks and services to enable select support. + Revision 6: o Added profile_version field to rtdm_device. o Requested IRQ lines are now enabled on return of rtdm_irq_request. -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 06/24] RTIPC: Fix memory leak on failing socket creation
From: Jan Kiszka CC: Philippe Gerum Signed-off-by: Jan Kiszka --- ksrc/drivers/ipc/rtipc.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/ksrc/drivers/ipc/rtipc.c b/ksrc/drivers/ipc/rtipc.c index d529912..563cc4e 100644 --- a/ksrc/drivers/ipc/rtipc.c +++ b/ksrc/drivers/ipc/rtipc.c @@ -143,6 +143,7 @@ static int rtipc_socket(struct rtdm_dev_context *context, { struct rtipc_protocol *proto; struct rtipc_private *p; + int ret; if (protocol < 0 || protocol >= IPCPROTO_MAX) return -EPROTONOSUPPORT; @@ -161,7 +162,11 @@ static int rtipc_socket(struct rtdm_dev_context *context, if (p->state == NULL) return -ENOMEM; - return proto->proto_ops.socket(p, user_info); + ret = proto->proto_ops.socket(p, user_info); + if (ret) + xnfree(p->state); + + return ret; } static int rtipc_close(struct rtdm_dev_context *context, -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 12/24] RTDM: Add rtdm_context_put()
From: Jan Kiszka As suggested by Philippe: This is an alias of rtdm_context_unlock(), but it is more intuitive to match it with rtdm_context_get() calls. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/rtdm/rtdm_driver.h |5 + ksrc/skins/rtdm/API.CHANGES |1 + ksrc/skins/rtdm/core.c | 29 + 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index 310df09..3f79abc 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -568,6 +568,11 @@ static inline void rtdm_context_unlock(struct rtdm_dev_context *context) atomic_dec(&context->close_lock_count); } +static inline void rtdm_context_put(struct rtdm_dev_context *context) +{ + rtdm_context_unlock(context); +} + /* --- clock services --- */ struct xntbase; extern struct xntbase *rtdm_tbase; diff --git a/ksrc/skins/rtdm/API.CHANGES b/ksrc/skins/rtdm/API.CHANGES index 64a4b38..73c1850 100644 --- a/ksrc/skins/rtdm/API.CHANGES +++ b/ksrc/skins/rtdm/API.CHANGES @@ -9,6 +9,7 @@ Scheduled modifications (unsorted): Revision 8: o Added rtdm_rt_capable. + o Added rtdm_context_put as logic match to rtdm_context_get Revision 7: o Added callbacks and services to enable select support. diff --git a/ksrc/skins/rtdm/core.c b/ksrc/skins/rtdm/core.c index ba4dc63..e04b3f6 100644 --- a/ksrc/skins/rtdm/core.c +++ b/ksrc/skins/rtdm/core.c @@ -50,14 +50,14 @@ EXPORT_SYMBOL(rtdm_tbase); DEFINE_XNLOCK(rt_fildes_lock); /** - * @brief Resolve file descriptor to device context + * @brief Retrieve and lock a device context * * @param[in] fd File descriptor * * @return Pointer to associated device context, or NULL on error * - * @note The device context has to be unlocked using rtdm_context_unlock() - * when it is no longer referenced. + * @note The device context has to be unlocked using rtdm_context_put() when + * it is no longer referenced. * * Environments: * @@ -612,7 +612,7 @@ void rtdm_context_lock(struct rtdm_dev_context *context); * * @param[in] context Device context * - * @note Every successful call to rtdm_context_get() must be matched by a + * @note Every call to rtdm_context_locked() must be matched by a * rtdm_context_unlock() invocation. * * Environments: @@ -629,6 +629,27 @@ void rtdm_context_lock(struct rtdm_dev_context *context); void rtdm_context_unlock(struct rtdm_dev_context *context); /** + * @brief Release a device context obtained via rtdm_context_get() + * + * @param[in] context Device context + * + * @note Every successful call to rtdm_context_get() must be matched by a + * rtdm_context_put() invocation. + * + * Environments: + * + * This service can be called from: + * + * - Kernel module initialization/cleanup code + * - Interrupt service routine + * - Kernel-based task + * - User-space task (RT, non-RT) + * + * Rescheduling: never. + */ +void rtdm_context_put(struct rtdm_dev_context *context); + +/** * @brief Open a device * * Refer to rt_dev_open() for parameters and return values -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 07/24] RTIPC: Drop support for RT socket creation/deletion
From: Jan Kiszka This is deprecated now, RT callers will automatically be migrated to NRT to perform the requests. Moreover, dropping it allows us to allocate resources from Linux instead of using the precious system heap. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- ksrc/drivers/ipc/rtipc.c |8 +++- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ksrc/drivers/ipc/rtipc.c b/ksrc/drivers/ipc/rtipc.c index 563cc4e..71629cb 100644 --- a/ksrc/drivers/ipc/rtipc.c +++ b/ksrc/drivers/ipc/rtipc.c @@ -158,13 +158,13 @@ static int rtipc_socket(struct rtdm_dev_context *context, p = rtdm_context_to_private(context); p->proto = proto; - p->state = xnmalloc(proto->proto_statesz); + p->state = kmalloc(proto->proto_statesz, GFP_KERNEL); if (p->state == NULL) return -ENOMEM; ret = proto->proto_ops.socket(p, user_info); if (ret) - xnfree(p->state); + kfree(p->state); return ret; } @@ -180,7 +180,7 @@ static int rtipc_close(struct rtdm_dev_context *context, if (ret) return ret; - xnfree(p->state); + kfree(p->state); return 0; } @@ -232,10 +232,8 @@ static struct rtdm_device device = { .device_name= "rtipc", .protocol_family= PF_RTIPC, .socket_type= SOCK_DGRAM, - .socket_rt = rtipc_socket, .socket_nrt = rtipc_socket, .ops = { - .close_rt = NULL, .close_nrt = rtipc_close, .recvmsg_rt = rtipc_recvmsg, .recvmsg_nrt= NULL, -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 02/24] RTDM: Add rtdm_rt_capable() service
From: Jan Kiszka This adds rtdm_rt_capable(), a function that can be used by drivers to detect callers that could issue a service request also from the (typically preferred) real-time context. If that is the case, the driver can trigger a restart of the request if the current context is not real-time. CC: Philippe Gerum CC: Alexis Berlemont Signed-off-by: Jan Kiszka --- include/rtdm/rtdm_driver.h |6 ++ ksrc/skins/rtdm/drvlib.c | 25 + 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index 0fc1496..45be404 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -1296,6 +1296,12 @@ static inline int rtdm_in_rt_context(void) { return (rthal_current_domain != rthal_root_domain); } + +static inline int rtdm_rt_capable(void) +{ + return xnpod_shadow_p(); +} + #endif /* !DOXYGEN_CPP */ int rtdm_exec_in_rt(struct rtdm_dev_context *context, diff --git a/ksrc/skins/rtdm/drvlib.c b/ksrc/skins/rtdm/drvlib.c index 3b04493..6e26501 100644 --- a/ksrc/skins/rtdm/drvlib.c +++ b/ksrc/skins/rtdm/drvlib.c @@ -2341,6 +2341,31 @@ int rtdm_strncpy_from_user(rtdm_user_info_t *user_info, char *dst, */ int rtdm_in_rt_context(void); +/** + * Test if the caller is capable of running in real-time context + * + * @return Non-zero is returned if the caller is able to execute in real-time + * context (independent of its current execution mode), 0 otherwise. + * + * @note This function can be used by drivers that provide different + * implementations for the same service depending on the execution mode of + * the caller. If a caller requests such a service in non-real-time context + * but is capable of running in real-time as well, it might be appropriate + * for the driver to reject the request via -ENOSYS so that RTDM can switch + * the caller and restart the request in real-time context. + * + * Environments: + * + * This service can be called from: + * + * - Kernel module initialization/cleanup code + * - Kernel-based task + * - User-space task (RT, non-RT) + * + * Rescheduling: never. + */ +int rtdm_rt_capable(void); + #endif /* DOXYGEN_CPP */ /** @} Utility Services */ -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 13/24] Fix historic msleep wrapping
From: Jan Kiszka Probably only an academic exercise: Fix the rounding bug in msleep wrapper for kernels < 2.4.28. Signed-off-by: Jan Kiszka --- include/asm-generic/wrappers.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/include/asm-generic/wrappers.h b/include/asm-generic/wrappers.h index 15d9837..64ec43f 100644 --- a/include/asm-generic/wrappers.h +++ b/include/asm-generic/wrappers.h @@ -197,7 +197,7 @@ do { \ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28) #define msleep(x) do { \ set_current_state(TASK_UNINTERRUPTIBLE); \ - schedule_timeout((x)*(HZ/1000)); \ + schedule_timeout(((x)*HZ)/1000); \ } while(0) #endif -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 16/24] irqbench: Auto-detect bases of port address and IRQ values
From: Jan Kiszka Signed-off-by: Jan Kiszka --- src/testsuite/irqbench/irqbench.c |2 +- src/testsuite/irqbench/irqloop.c |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/testsuite/irqbench/irqbench.c b/src/testsuite/irqbench/irqbench.c index 844f187..ca7a313 100644 --- a/src/testsuite/irqbench/irqbench.c +++ b/src/testsuite/irqbench/irqbench.c @@ -211,7 +211,7 @@ int main(int argc, char *argv[]) break; case 'a': - port_ioaddr = strtol(optarg, NULL, (strncmp(optarg, "0x", 2) == 0) ? 16 : 10); + port_ioaddr = strtol(optarg, NULL, 0); ioaddr_set = 1; break; diff --git a/src/testsuite/irqbench/irqloop.c b/src/testsuite/irqbench/irqloop.c index 3b4de4f..d4623b4 100644 --- a/src/testsuite/irqbench/irqloop.c +++ b/src/testsuite/irqbench/irqloop.c @@ -101,12 +101,12 @@ int main(int argc, char *argv[]) break; case 'a': - config.port_ioaddr = strtol(optarg, NULL, (strncmp(optarg, "0x", 2) == 0) ? 16 : 10); + config.port_ioaddr = strtol(optarg, NULL, 0); ioaddr_set = 1; break; case 'i': - config.port_irq = atoi(optarg); + config.port_irq = strtol(optarg, NULL, 0); irq_set = 1; break; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 15/24] irqbench: Refactor user space helpers
From: Jan Kiszka Indent according to our style, push irqbench's inner loop into separate function. No functional changes. Signed-off-by: Jan Kiszka --- src/testsuite/irqbench/irqbench.c | 480 ++--- src/testsuite/irqbench/irqloop.c | 303 2 files changed, 393 insertions(+), 390 deletions(-) diff --git a/src/testsuite/irqbench/irqbench.c b/src/testsuite/irqbench/irqbench.c index 6b22711..844f187 100644 --- a/src/testsuite/irqbench/irqbench.c +++ b/src/testsuite/irqbench/irqbench.c @@ -51,268 +51,266 @@ #define STAT(base) (base + 1) /* Status register */ #define CTRL(base) (base + 2) /* Control register */ -double tsc2ns_scale; -long long min_lat = LONG_MAX; -long long max_lat = LONG_MIN; -long long avg_lat = 0; -long outer_loops = 0; -int warmup = 1; -int terminate = 0; +static double tsc2ns_scale; +static long long min_lat = LONG_MAX; +static long long max_lat = LONG_MIN; +static long long avg_lat; +static long outer_loops; +static int warmup = 1; +static int terminate; +static unsigned long port_ioaddr = 0x3F8; +static int port_type = SERPORT; +static unsigned int toggle; +static long loop_avg; +static long long period = 10; +static int trigger_trace; static inline long long rdtsc(void) { -unsigned long long tsc; + unsigned long long tsc; -__asm__ __volatile__("rdtsc" : "=A" (tsc)); -return tsc; + __asm__ __volatile__("rdtsc" : "=A" (tsc)); + return tsc; } - static long tsc2ns(long long tsc) { -if ((tsc > LONG_MAX) || (tsc < LONG_MIN)) { -fprintf(stderr, "irqbench: overflow (%lld ns)!\n", -(long long)(tsc2ns_scale * (double)tsc)); -exit(2); -} -return (long)(tsc2ns_scale * (double)tsc); + if (tsc > LONG_MAX || tsc < LONG_MIN) { + fprintf(stderr, "irqbench: overflow (%lld ns)!\n", + (long long)(tsc2ns_scale * (double)tsc)); + exit(2); + } + return (long)(tsc2ns_scale * (double)tsc); } - static inline long long ns2tsc(long long ns) { -return (long long)(((double)ns) / tsc2ns_scale); + return (long long)(((double)ns) / tsc2ns_scale); } - -void calibrate_tsc(void) +static void calibrate_tsc(void) { -FILE *proc; -char *lineptr = NULL; -size_t len; -double cpu_mhz; - -proc = fopen("/proc/cpuinfo", "r"); -if (proc == NULL) { -perror("irqbench: Unable to open /proc/cpuinfo"); -exit(1); -} - -while (getline(&lineptr, &len, proc) != -1) -if (strncmp(lineptr, "cpu MHz", 7) == 0) { -sscanf(strchr(lineptr, ':') + 1, "%lf", &cpu_mhz); -break; -} - -if (lineptr) -free(lineptr); -fclose(proc); - -printf("CPU frequency: %.3lf MHz\n", cpu_mhz); - -tsc2ns_scale = 1000.0 / cpu_mhz; + FILE *proc; + char *lineptr = NULL; + size_t len; + double cpu_mhz; + + proc = fopen("/proc/cpuinfo", "r"); + if (proc == NULL) { + perror("irqbench: Unable to open /proc/cpuinfo"); + exit(1); + } + + while (getline(&lineptr, &len, proc) != -1) + if (strncmp(lineptr, "cpu MHz", 7) == 0) { + sscanf(strchr(lineptr, ':') + 1, "%lf", &cpu_mhz); + break; + } + + if (lineptr) + free(lineptr); + fclose(proc); + + printf("CPU frequency: %.3lf MHz\n", cpu_mhz); + + tsc2ns_scale = 1000.0 / cpu_mhz; } - -void sighand(int signal) +static void sighand(int signal) { -if (warmup) -exit(0); -else -terminate = 1; + if (warmup) + exit(0); + else + terminate = 1; } +static void do_inner_loop(void) +{ + long long start, delay, timeout; + long lat; + + __asm__ __volatile__("cli"); + + if (port_type == SERPORT) { + start = rdtsc(); + + toggle ^= MCR_RTS; + outb(toggle, MCR(port_ioaddr)); + + timeout = start + period * 100; + while ((inb(MSR(port_ioaddr)) & MSR_DELTA) == 0 && + rdtsc() < timeout); + + delay = rdtsc() - start; + } else { + int status = inb(STAT(port_ioaddr)); + + outb(0x08, DATA(port_ioaddr)); + + start = rdtsc(); + + outb(0x00, DATA(port_ioaddr)); + + timeout = start + period * 100; + while (inb(STAT(port_ioaddr)) == status && + rdtsc() < timeout); + + delay = rdtsc() - start; + } + + if (!warmup) { + lat = tsc2ns(delay); + + loop_avg += lat; + if (lat < min_lat) + min_lat = lat; + if (lat > max_lat) { + max_lat = lat; + if (trigger_trace) { +
[Xenomai-core] [PATCH v3 10/24] Analogy: Drop support for opening/closing in real-time
From: Jan Kiszka This is deprected now, RT callers will automatically be switched to non-RT. CC: Alexis Berlemont Signed-off-by: Jan Kiszka --- ksrc/drivers/analogy/rtdm_interface.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/ksrc/drivers/analogy/rtdm_interface.c b/ksrc/drivers/analogy/rtdm_interface.c index f769e4a..99abf2f 100644 --- a/ksrc/drivers/analogy/rtdm_interface.c +++ b/ksrc/drivers/analogy/rtdm_interface.c @@ -227,11 +227,9 @@ static struct rtdm_device rtdm_devs[A4L_NB_DEVICES] = .context_size = sizeof(struct a4l_dummy_context), .device_name = "", - .open_rt = a4l_rt_open, .open_nrt = a4l_rt_open, .ops = { - .close_rt = a4l_rt_close, .ioctl_rt = a4l_rt_ioctl, .read_rt = a4l_rt_read, .write_rt = a4l_rt_write, -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 23/24] RTDM: Early fd release with poll-free context reference tracking
From: Jan Kiszka Two changes in one as they are tightly related: Once close is called, remove the file descriptor from open table, allowing its reuse while close for the previous user proceeds. The second and major part of the patch avoids time-based polling while waiting for context references to be dropped. This specifically helps in scenarios where references can be held for a longer time beyond the first close. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/rtdm/rtdm_driver.h | 16 - ksrc/skins/rtdm/core.c | 168 ++- ksrc/skins/rtdm/device.c | 45 ++-- ksrc/skins/rtdm/internal.h |8 +-- 4 files changed, 170 insertions(+), 67 deletions(-) diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index bd8a9d0..c856568 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -379,6 +379,7 @@ struct rtdm_operations { struct rtdm_devctx_reserved { void *owner; + struct list_head cleanup; }; /** @@ -560,19 +561,28 @@ int rtdm_dev_unregister(struct rtdm_device *device, unsigned int poll_delay); struct rtdm_dev_context *rtdm_context_get(int fd); #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */ + +#define CONTEXT_IS_LOCKED(context) \ + (atomic_read(&(context)->close_lock_count) > 1 || \ +(test_bit(RTDM_CLOSING, &(context)->context_flags) && \ + atomic_read(&(context)->close_lock_count) > 0)) + static inline void rtdm_context_lock(struct rtdm_dev_context *context) { - XENO_ASSERT(RTDM, atomic_read(&context->close_lock_count) > 0, + XENO_ASSERT(RTDM, CONTEXT_IS_LOCKED(context), /* just warn if context was a dangling pointer */); atomic_inc(&context->close_lock_count); } +extern int rtdm_apc; + static inline void rtdm_context_unlock(struct rtdm_dev_context *context) { - XENO_ASSERT(RTDM, atomic_read(&context->close_lock_count) > 0, + XENO_ASSERT(RTDM, CONTEXT_IS_LOCKED(context), /* just warn if context was a dangling pointer */); smp_mb__before_atomic_dec(); - atomic_dec(&context->close_lock_count); + if (unlikely(atomic_dec_and_test(&context->close_lock_count))) + rthal_apc_schedule(rtdm_apc); } static inline void rtdm_context_put(struct rtdm_dev_context *context) diff --git a/ksrc/skins/rtdm/core.c b/ksrc/skins/rtdm/core.c index e04b3f6..bf905df 100644 --- a/ksrc/skins/rtdm/core.c +++ b/ksrc/skins/rtdm/core.c @@ -26,7 +26,7 @@ * @{ */ -#include +#include #include #include @@ -35,7 +35,7 @@ #include "rtdm/internal.h" -#define CLOSURE_RETRY_PERIOD 100 /* ms */ +#define CLOSURE_RETRY_PERIOD_MS100 #define FD_BITMAP_SIZE ((RTDM_FD_MAX + BITS_PER_LONG-1) / BITS_PER_LONG) @@ -44,6 +44,10 @@ struct rtdm_fildes fildes_table[RTDM_FD_MAX] = static unsigned long used_fildes[FD_BITMAP_SIZE]; int open_fildes; /* number of used descriptors */ +static DECLARE_WORK_FUNC(close_callback); +static DECLARE_DELAYED_WORK_NODATA(close_work, close_callback); +static LIST_HEAD(cleanup_queue); + xntbase_t *rtdm_tbase; EXPORT_SYMBOL(rtdm_tbase); @@ -81,8 +85,7 @@ struct rtdm_dev_context *rtdm_context_get(int fd) xnlock_get_irqsave(&rt_fildes_lock, s); context = fildes_table[fd].context; - if (unlikely(!context || -test_bit(RTDM_CLOSING, &context->context_flags))) { + if (unlikely(!context)) { xnlock_put_irqrestore(&rt_fildes_lock, s); return NULL; } @@ -106,8 +109,10 @@ static int create_instance(struct rtdm_device *device, int fd; spl_t s; - /* Reset to NULL so that we can always use cleanup_instance to revert - also partially successful allocations */ + /* +* Reset to NULL so that we can always use cleanup_files/instance to +* revert also partially successful allocations. +*/ *context_ptr = NULL; *fildes_ptr = NULL; @@ -155,7 +160,7 @@ static int create_instance(struct rtdm_device *device, context->fd = fd; context->ops = &device->ops; - atomic_set(&context->close_lock_count, 0); + atomic_set(&context->close_lock_count, 1); #ifdef CONFIG_XENO_OPT_PERVASIVE ppd = xnshadow_ppd_get(__rtdm_muxid); @@ -163,31 +168,34 @@ static int create_instance(struct rtdm_device *device, context->reserved.owner = ppd ? container_of(ppd, struct rtdm_process, ppd) : NULL; + INIT_LIST_HEAD(&context->reserved.cleanup); return 0; } -static int cleanup_instance(struct rtdm_device *device, - struct rtdm_dev_context *context, - struct rtdm_fildes *fildes, int nrt_mem) +static void __cleanup_fildes(struct rtdm_fildes *fildes) { - spl_t s; - - xnlock_get_irqsave(&rt_fildes_lock, s); + clear_bit((fil
[Xenomai-core] [PATCH v3 11/24] RTDM: Instrument rtdm_context_lock/unlock to detect misuses
From: Jan Kiszka rtdm_context_lock must only be called on context structures that are already locked, and rtdm_context_unlock must be kept in balance with rtdm_context_get/rtdm_context_lock. Try to check for mistakes by requiring non-null clock_lock_count on entry of both services. Also fix a typo and clarify the use cases and restrictions of rtdm_context_lock. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/rtdm/rtdm_driver.h |4 ksrc/skins/rtdm/core.c | 10 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index 7d5983c..310df09 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -555,11 +555,15 @@ struct rtdm_dev_context *rtdm_context_get(int fd); #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */ static inline void rtdm_context_lock(struct rtdm_dev_context *context) { + XENO_ASSERT(RTDM, atomic_read(&context->close_lock_count) > 0, + /* just warn if context was a dangling pointer */); atomic_inc(&context->close_lock_count); } static inline void rtdm_context_unlock(struct rtdm_dev_context *context) { + XENO_ASSERT(RTDM, atomic_read(&context->close_lock_count) > 0, + /* just warn if context was a dangling pointer */); smp_mb__before_atomic_dec(); atomic_dec(&context->close_lock_count); } diff --git a/ksrc/skins/rtdm/core.c b/ksrc/skins/rtdm/core.c index 8cccf52..ba4dc63 100644 --- a/ksrc/skins/rtdm/core.c +++ b/ksrc/skins/rtdm/core.c @@ -87,7 +87,7 @@ struct rtdm_dev_context *rtdm_context_get(int fd) return NULL; } - rtdm_context_lock(context); + atomic_inc(&context->close_lock_count); xnlock_put_irqrestore(&rt_fildes_lock, s); @@ -328,7 +328,7 @@ again: } set_bit(RTDM_CLOSING, &context->context_flags); - rtdm_context_lock(context); + atomic_inc(&context->close_lock_count); xnlock_put_irqrestore(&rt_fildes_lock, s); @@ -588,7 +588,11 @@ EXPORT_SYMBOL(rtdm_select_bind); * @param[in] context Device context * * @note rtdm_context_get() automatically increments the lock counter. You - * only need to call this function in special scenrios. + * only need to call this function in special scenarios, e.g. when keeping + * additional references to the context structure that have different + * lifetimes. Only use rtdm_context_lock() on contexts that are currently + * locked via an earlier rtdm_context_get()/rtdm_contex_lock() or while + * running a device operation handler. * * Environments: * -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 22/24] Add legacy kernel support for delayed_work
From: Jan Kiszka Note that the kernel 2.4 version of schedule_delayed_work is not universally usable. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/asm-generic/wrappers.h |3 +++ include/compat/linux/workqueue.h | 13 + 2 files changed, 16 insertions(+), 0 deletions(-) diff --git a/include/asm-generic/wrappers.h b/include/asm-generic/wrappers.h index d864397..7513781 100644 --- a/include/asm-generic/wrappers.h +++ b/include/asm-generic/wrappers.h @@ -192,6 +192,7 @@ do { \ #define DECLARE_WORK(n,f,d)struct tq_struct n = __WORK_INITIALIZER(n, f, d) #define DECLARE_WORK_NODATA(n, f) DECLARE_WORK(n, f, NULL) #define DECLARE_WORK_FUNC(f) void f(void *cookie) +#define DECLARE_DELAYED_WORK_NODATA(n, f) DECLARE_WORK(n, f, NULL) /* Msleep is unknown before 2.4.28 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28) @@ -436,9 +437,11 @@ unsigned long find_next_bit(const unsigned long *addr, #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) #define DECLARE_WORK_NODATA(f, n) DECLARE_WORK(f, n, NULL) #define DECLARE_WORK_FUNC(f) void f(void *cookie) +#define DECLARE_DELAYED_WORK_NODATA(n, f) DECLARE_DELAYED_WORK(n, f, NULL) #else /* >= 2.6.20 */ #define DECLARE_WORK_NODATA(f, n) DECLARE_WORK(f, n) #define DECLARE_WORK_FUNC(f) void f(struct work_struct *work) +#define DECLARE_DELAYED_WORK_NODATA(n, f) DECLARE_DELAYED_WORK(n, f) #endif /* >= 2.6.20 */ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */ diff --git a/include/compat/linux/workqueue.h b/include/compat/linux/workqueue.h index 3ac37aa..6fad03c 100644 --- a/include/compat/linux/workqueue.h +++ b/include/compat/linux/workqueue.h @@ -28,4 +28,17 @@ #define schedule_work(x) schedule_task(x) #define flush_scheduled_work() flush_scheduled_tasks() +/* + * WARNING: This is not identical to 2.6 schedule_delayed_work as it delayes + * the caller to schedule the task after the specified delay. That's fine for + * our current use cases, though. + */ +#define schedule_delayed_work(work, delay) do {\ + if (delay) {\ + set_current_state(TASK_UNINTERRUPTIBLE);\ + schedule_timeout(delay);\ + } \ + schedule_task(work);\ +} while (0) + #endif /* _XENO_COMPAT_LINUX_WORKQUEUE_H */ -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 21/24] Add list_first_entry wrapper for older kernels
From: Jan Kiszka CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/asm-generic/wrappers.h |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/include/asm-generic/wrappers.h b/include/asm-generic/wrappers.h index 64ec43f..d864397 100644 --- a/include/asm-generic/wrappers.h +++ b/include/asm-generic/wrappers.h @@ -559,6 +559,11 @@ static inline void wrap_proc_dir_entry_owner(struct proc_dir_entry *entry) #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */ #endif /* CONFIG_PROC_FS */ +#ifndef list_first_entry +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) #define rthal_irq_descp(irq) (irq_desc + (irq)) #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) */ -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 18/24] testing: Clean up Kconfig rules
From: Jan Kiszka To exclude modules from built-in, make them depend on 'm' is sufficient. Signed-off-by: Jan Kiszka --- ksrc/drivers/testing/Config.in |2 +- ksrc/drivers/testing/Kconfig | 14 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/ksrc/drivers/testing/Config.in b/ksrc/drivers/testing/Config.in index 3552670..215c38d 100644 --- a/ksrc/drivers/testing/Config.in +++ b/ksrc/drivers/testing/Config.in @@ -15,6 +15,6 @@ dep_tristate 'Context switches test driver' CONFIG_XENO_DRIVERS_SWITCHTEST $CONF dep_tristate 'Kernel-only latency measurement module' CONFIG_XENO_DRIVERS_KLATENCY $CONFIG_XENO_DRIVERS_TIMERBENCH m -dep_tristate 'User-space real-time signals testing module' CONFIG_XENO_DRIVERS_SIGTEST $CONFIG_MODULES m +dep_tristate 'User-space real-time signals testing module' CONFIG_XENO_DRIVERS_SIGTEST m endmenu diff --git a/ksrc/drivers/testing/Kconfig b/ksrc/drivers/testing/Kconfig index 05d6a49..883ede1 100644 --- a/ksrc/drivers/testing/Kconfig +++ b/ksrc/drivers/testing/Kconfig @@ -1,9 +1,5 @@ menu "Testing drivers" -config XENO_TESTING_MODULE -depends on MODULES - def_tristate m - config XENO_DRIVERS_TESTING_LEGACY_NAMES depends on XENO_SKIN_RTDM bool "Use legacy names for testing drivers" @@ -22,7 +18,7 @@ config XENO_DRIVERS_TIMERBENCH See testsuite/latency for a possible front-end. config XENO_DRIVERS_KLATENCY - depends on XENO_DRIVERS_TIMERBENCH && XENO_TESTING_MODULE + depends on XENO_DRIVERS_TIMERBENCH && m tristate "Kernel-only latency measurement module" help Kernel module for kernel-only latency measurement. @@ -44,9 +40,9 @@ config XENO_DRIVERS_SWITCHTEST FPU switches. config XENO_DRIVERS_SIGTEST - depends on XENO_TESTING_MODULE - tristate "User-space real-time signals testing module" - help - Elementary skin for unit testing user-space real-time signals. + depends on m + tristate "User-space real-time signals testing module" + help + Elementary skin for unit testing user-space real-time signals. endmenu -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 24/24] RTDM: Add basic unit test
From: Jan Kiszka This unit test for RTDM validates deferred device closing and driver deregistration due to pending references. Further tests can be added in the future. CC: Philippe Gerum Signed-off-by: Jan Kiszka --- include/rtdm/rttesting.h|9 ++ ksrc/drivers/testing/Config.in |2 + ksrc/drivers/testing/Kconfig|6 ++ ksrc/drivers/testing/Makefile | 12 +++- ksrc/drivers/testing/rtdmtest.c | 191 +++ src/testsuite/unit/Makefile.am | 17 - src/testsuite/unit/rtdm.c | 114 +++ 7 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 ksrc/drivers/testing/rtdmtest.c create mode 100644 src/testsuite/unit/rtdm.c diff --git a/include/rtdm/rttesting.h b/include/rtdm/rttesting.h index 56df43b..2f001c2 100644 --- a/include/rtdm/rttesting.h +++ b/include/rtdm/rttesting.h @@ -141,6 +141,10 @@ struct rttst_swtest_error { unsigned fp_val; }; +#define RTTST_RTDM_NORMAL_CLOSE0 +#define RTTST_RTDM_DEFER_CLOSE_HANDLER 1 +#define RTTST_RTDM_DEFER_CLOSE_CONTEXT 2 + #define RTIOC_TYPE_TESTING RTDM_CLASS_TESTING /*! @@ -152,6 +156,8 @@ struct rttst_swtest_error { #define RTDM_SUBCLASS_IRQBENCH 1 /** subclass name: "switchtst" */ #define RTDM_SUBCLASS_SWITCHTEST 2 +/** subclase name: "rtdm" */ +#define RTDM_SUBCLASS_RTDMTEST 3 /** @} */ /*! @@ -208,6 +214,9 @@ struct rttst_swtest_error { #define RTTST_RTIOC_SWTEST_SET_PAUSE \ _IOW(RTIOC_TYPE_TESTING, 0x38, unsigned long) + +#define RTTST_RTIOC_RTDM_DEFER_CLOSE \ + _IOW(RTIOC_TYPE_TESTING, 0x40, unsigned long) /** @} */ /** @} */ diff --git a/ksrc/drivers/testing/Config.in b/ksrc/drivers/testing/Config.in index 215c38d..4f81cf9 100644 --- a/ksrc/drivers/testing/Config.in +++ b/ksrc/drivers/testing/Config.in @@ -17,4 +17,6 @@ dep_tristate 'Kernel-only latency measurement module' CONFIG_XENO_DRIVERS_KLATEN dep_tristate 'User-space real-time signals testing module' CONFIG_XENO_DRIVERS_SIGTEST m +dep_tristate 'RTDM unit tests driver' CONFIG_XENO_DRIVERS_RTDMTEST $CONFIG_XENO_SKIN_RTDM m + endmenu diff --git a/ksrc/drivers/testing/Kconfig b/ksrc/drivers/testing/Kconfig index 883ede1..28504dc 100644 --- a/ksrc/drivers/testing/Kconfig +++ b/ksrc/drivers/testing/Kconfig @@ -45,4 +45,10 @@ config XENO_DRIVERS_SIGTEST help Elementary skin for unit testing user-space real-time signals. +config XENO_DRIVERS_RTDMTEST + depends on XENO_SKIN_RTDM && m + tristate "RTDM unit tests driver" + help + Kernel driver for performing RTDM unit tests. + endmenu diff --git a/ksrc/drivers/testing/Makefile b/ksrc/drivers/testing/Makefile index 7878cd5..17a6cf1 100644 --- a/ksrc/drivers/testing/Makefile +++ b/ksrc/drivers/testing/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_XENO_DRIVERS_IRQBENCH) += xeno_irqbench.o obj-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += xeno_switchtest.o obj-$(CONFIG_XENO_DRIVERS_KLATENCY) += xeno_klat.o obj-$(CONFIG_XENO_DRIVERS_SIGTEST)+= xeno_sigtest.o +obj-$(CONFIG_XENO_DRIVERS_RTDMTEST) += xeno_rtdmtest.o xeno_timerbench-y := timerbench.o @@ -20,6 +21,8 @@ xeno_klat-y := klat.o xeno_sigtest-y := sigtest_module.o +xeno_rtdmtest-y := rtdmtest.o + EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai else @@ -33,6 +36,7 @@ obj-$(CONFIG_XENO_DRIVERS_IRQBENCH) += xeno_irqbench.o obj-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += xeno_switchtest.o obj-$(CONFIG_XENO_DRIVERS_KLATENCY) += xeno_klat.o obj-$(CONFIG_XENO_DRIVERS_SIGTEST)+= xeno_sigtest.o +obj-$(CONFIG_XENO_DRIVERS_RTDMTEST) += xeno_rtdmtest.o xeno_timerbench-objs := timerbench.o @@ -44,8 +48,11 @@ xeno_klat-objs := klat.o xeno_sigtest-objs := sigtest_module.o +xeno_rtdmtest-objs := rtdmtest.o + export-objs := $(xeno_timerbench-objs) $(xeno_irqbench-objs) \ - $(xeno_switchtest-objs) $(xeno_klat-objs) $(xeno_sigtest-objs) + $(xeno_switchtest-objs) $(xeno_klat-objs) $(xeno_sigtest-objs) \ + $(xeno_rtdmtest-objs) EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai -I$(TOPDIR)/include/xenomai/compat @@ -66,4 +73,7 @@ xeno_klat.o: $(xeno_klat-objs) xeno_sigtest.o: $(xeno_sigtest-objs) $(LD) -r -o $@ $(xeno_sigtest-objs) +xeno_rtdmtest.o: $(xeno_rtdmtest-objs) + $(LD) -r -o $@ $(xeno_rtdmtest-objs) + endif diff --git a/ksrc/drivers/testing/rtdmtest.c b/ksrc/drivers/testing/rtdmtest.c new file mode 100644 index 000..12540de --- /dev/null +++ b/ksrc/drivers/testing/rtdmtest.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2010 Jan Kiszka . + * + * Xenomai is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Xenomai is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even
[Xenomai-core] [PATCH v3 08/24] RTCAN: Drop support for socket creation/deletion in real-time
From: Jan Kiszka This is deprecated now, RT callers will automatically be migrated to NRT to perform the requests. CC: Wolfgang Grandegger Signed-off-by: Jan Kiszka --- ksrc/drivers/can/rtcan_raw.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/ksrc/drivers/can/rtcan_raw.c b/ksrc/drivers/can/rtcan_raw.c index 0cf0bb9..9ee0950 100644 --- a/ksrc/drivers/can/rtcan_raw.c +++ b/ksrc/drivers/can/rtcan_raw.c @@ -999,11 +999,9 @@ static struct rtdm_device rtcan_proto_raw_dev = { protocol_family:PF_CAN, socket_type:SOCK_RAW, -socket_rt: rtcan_raw_socket, socket_nrt: rtcan_raw_socket, ops: { -close_rt: rtcan_raw_close, close_nrt: rtcan_raw_close, ioctl_rt: rtcan_raw_ioctl, -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH v3 00/24] [git pull v3] RTDM fixes and reworks
The following changes since commit 113ea4d56e8b215cb56ae7673013163ea5a5987d: Gilles Chanteperdrix (1): switchtest: increase stack sizes are available in the git repository at: git://git.xenomai.org/xenomai-jki.git for-upstream Changes in v3: - extended RTDM unit test to check for returned file descriptor number Changes in v2: - compat support for rttest device names - documented RTDM close procedure - internal rework of the close procedure - basic RTDM unit test, so far targeting at the close rework - some additional small cleanup patches Jan Kiszka (23): RTDM: Add rtdm_rt_capable() service RTDM: Bump API version and document changes Revert "rtdm: tag syscalls as conforming" RTDM: Deprecate open_rt, socket_rt, and close_rt RTIPC: Fix memory leak on failing socket creation RTIPC: Drop support for RT socket creation/deletion RTCAN: Drop support for socket creation/deletion in real-time 16550A: Drop support for device opening/closing in real-time Analogy: Drop support for opening/closing in real-time RTDM: Instrument rtdm_context_lock/unlock to detect misuses RTDM: Add rtdm_context_put() Fix historic msleep wrapping irqbench: Fix x86-64 build irqbench: Refactor user space helpers irqbench: Auto-detect bases of port address and IRQ values rttest: Resolved test device conflicts via separate name spaces testing: Clean up Kconfig rules RTIPC: Drop unused wrapper around close_lock_count RTDM: Document device close procedure Add list_first_entry wrapper for older kernels Add legacy kernel support for delayed_work RTDM: Early fd release with poll-free context reference tracking RTDM: Add basic unit test Wolfgang Mauerer (1): RTDM: Fix potential NULL pointer dereference configure.in |2 +- include/asm-generic/wrappers.h| 10 +- include/compat/linux/workqueue.h | 13 + include/rtdm/rtdm.h |4 +- include/rtdm/rtdm_driver.h| 50 +++- include/rtdm/rttesting.h | 19 ++- ksrc/drivers/analogy/rtdm_interface.c |2 - ksrc/drivers/can/rtcan_raw.c |2 - ksrc/drivers/ipc/internal.h |5 - ksrc/drivers/ipc/rtipc.c | 13 +- ksrc/drivers/serial/16550A.c | 51 +--- ksrc/drivers/testing/Config.in|6 +- ksrc/drivers/testing/Kconfig | 27 ++- ksrc/drivers/testing/Makefile | 12 +- ksrc/drivers/testing/irqbench.c |9 +- ksrc/drivers/testing/klat.c |8 +- ksrc/drivers/testing/rtdmtest.c | 191 + ksrc/drivers/testing/switchtest.c |7 +- ksrc/drivers/testing/timerbench.c |7 +- ksrc/skins/rtdm/API.CHANGES |9 + ksrc/skins/rtdm/core.c| 207 ++ ksrc/skins/rtdm/device.c | 58 - ksrc/skins/rtdm/drvlib.c | 25 ++ ksrc/skins/rtdm/internal.h|8 +- ksrc/skins/rtdm/syscall.c | 10 +- src/testsuite/irqbench/Makefile.am|2 +- src/testsuite/irqbench/irqbench.c | 480 - src/testsuite/irqbench/irqloop.c | 312 +++-- src/testsuite/latency/latency.c | 12 +- src/testsuite/switchtest/switchtest.c | 13 +- src/testsuite/unit/Makefile.am| 17 ++- src/testsuite/unit/rtdm.c | 114 32 files changed, 1155 insertions(+), 550 deletions(-) create mode 100644 ksrc/drivers/testing/rtdmtest.c create mode 100644 src/testsuite/unit/rtdm.c Jan Kiszka (23): RTDM: Add rtdm_rt_capable() service RTDM: Bump API version and document changes Revert "rtdm: tag syscalls as conforming" RTDM: Deprecate open_rt, socket_rt, and close_rt RTIPC: Fix memory leak on failing socket creation RTIPC: Drop support for RT socket creation/deletion RTCAN: Drop support for socket creation/deletion in real-time 16550A: Drop support for device opening/closing in real-time Analogy: Drop support for opening/closing in real-time RTDM: Instrument rtdm_context_lock/unlock to detect misuses RTDM: Add rtdm_context_put() Fix historic msleep wrapping irqbench: Fix x86-64 build irqbench: Refactor user space helpers irqbench: Auto-detect bases of port address and IRQ values rttest: Resolved test device conflicts via separate name spaces testing: Clean up Kconfig rules RTIPC: Drop unused wrapper around close_lock_count RTDM: Document device close procedure Add list_first_entry wrapper for older kernels Add legacy kernel support for delayed_work RTDM: Early fd release with poll-free context reference tracking RTDM: Add basic unit test Wolfgang Mauerer (1): RTDM: Fix potential NULL pointer dereference configure.in |2 +- include/asm-generic/wrappers.h| 10 +- include/compat/linux/workqueue.h |
[Xenomai-core] [PATCH v3 09/24] 16550A: Drop support for device opening/closing in real-time
From: Jan Kiszka This is deprected now, RT callers will automatically be switched to non-RT. Along this, simplify the allocation logic for the RX timestamp history buffer. We only support allocations from non-RT now and migrate RT callers as required. Signed-off-by: Jan Kiszka --- ksrc/drivers/serial/16550A.c | 51 +++-- 1 files changed, 14 insertions(+), 37 deletions(-) diff --git a/ksrc/drivers/serial/16550A.c b/ksrc/drivers/serial/16550A.c index db8a515..4c46d86 100644 --- a/ksrc/drivers/serial/16550A.c +++ b/ksrc/drivers/serial/16550A.c @@ -297,7 +297,7 @@ static int rt_16550_interrupt(rtdm_irq_t * irq_context) static int rt_16550_set_config(struct rt_16550_context *ctx, const struct rtser_config *config, - uint64_t ** in_history_ptr) + uint64_t **in_history_ptr) { rtdm_lockctx_t lock_ctx; unsigned long base = ctx->base_addr; @@ -537,12 +537,7 @@ int rt_16550_close(struct rtdm_dev_context *context, rt_16550_cleanup_ctx(ctx); - if (in_history) { - if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) - kfree(in_history); - else - rtdm_free(in_history); - } + kfree(in_history); return 0; } @@ -602,40 +597,24 @@ int rt_16550_ioctl(struct rtdm_dev_context *context, if (testbits(config->config_mask, RTSER_SET_TIMESTAMP_HISTORY)) { - if (test_bit(RTDM_CREATED_IN_NRT, -&context->context_flags) - && rtdm_in_rt_context()) { - /* Already fail here if we MAY allocate or - release a non-RT buffer in RT context. */ - return -EPERM; - } + /* +* Reflect the call to non-RT as we will likely +* allocate or free the buffer. +*/ + if (rtdm_in_rt_context()) + return -ENOSYS; if (testbits(config->timestamp_history, -RTSER_RX_TIMESTAMP_HISTORY)) { - if (test_bit(RTDM_CREATED_IN_NRT, -&context->context_flags)) - hist_buf = - kmalloc(IN_BUFFER_SIZE * - sizeof(nanosecs_abs_t), - GFP_KERNEL); - else - hist_buf = - rtdm_malloc(IN_BUFFER_SIZE * - sizeof(nanosecs_abs_t)); - if (!hist_buf) - return -ENOMEM; - } +RTSER_RX_TIMESTAMP_HISTORY)) + hist_buf = kmalloc(IN_BUFFER_SIZE * + sizeof(nanosecs_abs_t), + GFP_KERNEL); } rt_16550_set_config(ctx, config, &hist_buf); - if (hist_buf) { - if (test_bit(RTDM_CREATED_IN_NRT, -&context->context_flags)) - kfree(hist_buf); - else - rtdm_free(hist_buf); - } + if (hist_buf) + kfree(hist_buf); break; } @@ -1107,11 +1086,9 @@ static const struct rtdm_device __initdata device_tmpl = { .context_size = sizeof(struct rt_16550_context), .device_name= "", - .open_rt= rt_16550_open, .open_nrt = rt_16550_open, .ops = { - .close_rt = rt_16550_close, .close_nrt = rt_16550_close, .ioctl_rt = rt_16550_ioctl, -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 02/24] RTDM: Add rtdm_rt_capable() service
On Sun, 2010-04-18 at 15:12 +0200, Jan Kiszka wrote: > From: Jan Kiszka > > This adds rtdm_rt_capable(), a function that can be used by drivers to > detect callers that could issue a service request also from the > (typically preferred) real-time context. If that is the case, the driver > can trigger a restart of the request if the current context is not > real-time. > > CC: Philippe Gerum > CC: Alexis Berlemont > Signed-off-by: Jan Kiszka > --- > include/rtdm/rtdm_driver.h |6 ++ > ksrc/skins/rtdm/drvlib.c | 25 + > 2 files changed, 31 insertions(+), 0 deletions(-) > > diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h > index 0fc1496..45be404 100644 > --- a/include/rtdm/rtdm_driver.h > +++ b/include/rtdm/rtdm_driver.h > @@ -1296,6 +1296,12 @@ static inline int rtdm_in_rt_context(void) > { > return (rthal_current_domain != rthal_root_domain); > } > + > +static inline int rtdm_rt_capable(void) > +{ > + return xnpod_shadow_p(); > +} > + This won't do what your comment states; xnpod_shadow_p() would always return false on behalf of a relaxed shadow, since it tests the status bits of the current Xenomai thread, which has to be the root one in that case. xnpod_shadow_p is to be used in primary context only, to distinguish between kernel-based and userland Xenomai callers. What you want is probably something like: static inline int rtdm_rt_capable(void) { return xnshadow_thread(current) != NULL; } > #endif /* !DOXYGEN_CPP */ > > int rtdm_exec_in_rt(struct rtdm_dev_context *context, > diff --git a/ksrc/skins/rtdm/drvlib.c b/ksrc/skins/rtdm/drvlib.c > index 3b04493..6e26501 100644 > --- a/ksrc/skins/rtdm/drvlib.c > +++ b/ksrc/skins/rtdm/drvlib.c > @@ -2341,6 +2341,31 @@ int rtdm_strncpy_from_user(rtdm_user_info_t > *user_info, char *dst, > */ > int rtdm_in_rt_context(void); > > +/** > + * Test if the caller is capable of running in real-time context > + * > + * @return Non-zero is returned if the caller is able to execute in real-time > + * context (independent of its current execution mode), 0 otherwise. > + * > + * @note This function can be used by drivers that provide different > + * implementations for the same service depending on the execution mode of > + * the caller. If a caller requests such a service in non-real-time context > + * but is capable of running in real-time as well, it might be appropriate > + * for the driver to reject the request via -ENOSYS so that RTDM can switch > + * the caller and restart the request in real-time context. > + * > + * Environments: > + * > + * This service can be called from: > + * > + * - Kernel module initialization/cleanup code > + * - Kernel-based task > + * - User-space task (RT, non-RT) > + * > + * Rescheduling: never. > + */ > +int rtdm_rt_capable(void); > + > #endif /* DOXYGEN_CPP */ > > /** @} Utility Services */ -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 02/24] RTDM: Add rtdm_rt_capable() service
On Sun, 2010-04-18 at 15:26 +0200, Philippe Gerum wrote: > On Sun, 2010-04-18 at 15:12 +0200, Jan Kiszka wrote: > > From: Jan Kiszka > > > > This adds rtdm_rt_capable(), a function that can be used by drivers to > > detect callers that could issue a service request also from the > > (typically preferred) real-time context. If that is the case, the driver > > can trigger a restart of the request if the current context is not > > real-time. > > > > CC: Philippe Gerum > > CC: Alexis Berlemont > > Signed-off-by: Jan Kiszka > > --- > > include/rtdm/rtdm_driver.h |6 ++ > > ksrc/skins/rtdm/drvlib.c | 25 + > > 2 files changed, 31 insertions(+), 0 deletions(-) > > > > diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h > > index 0fc1496..45be404 100644 > > --- a/include/rtdm/rtdm_driver.h > > +++ b/include/rtdm/rtdm_driver.h > > @@ -1296,6 +1296,12 @@ static inline int rtdm_in_rt_context(void) > > { > > return (rthal_current_domain != rthal_root_domain); > > } > > + > > +static inline int rtdm_rt_capable(void) > > +{ > > + return xnpod_shadow_p(); > > +} > > + > > This won't do what your comment states; xnpod_shadow_p() would always > return false on behalf of a relaxed shadow, since it tests the status > bits of the current Xenomai thread, which has to be the root one in that > case. xnpod_shadow_p is to be used in primary context only, to > distinguish between kernel-based and userland Xenomai callers. > > What you want is probably something like: > > static inline int rtdm_rt_capable(void) > { > return xnshadow_thread(current) != NULL; > } Btw, the predicate as you defined it would not work over kernel-based Xenomai threads. rtdm_rt_capable() is ambiguous here. > > > > #endif /* !DOXYGEN_CPP */ > > > > int rtdm_exec_in_rt(struct rtdm_dev_context *context, > > diff --git a/ksrc/skins/rtdm/drvlib.c b/ksrc/skins/rtdm/drvlib.c > > index 3b04493..6e26501 100644 > > --- a/ksrc/skins/rtdm/drvlib.c > > +++ b/ksrc/skins/rtdm/drvlib.c > > @@ -2341,6 +2341,31 @@ int rtdm_strncpy_from_user(rtdm_user_info_t > > *user_info, char *dst, > > */ > > int rtdm_in_rt_context(void); > > > > +/** > > + * Test if the caller is capable of running in real-time context > > + * > > + * @return Non-zero is returned if the caller is able to execute in > > real-time > > + * context (independent of its current execution mode), 0 otherwise. > > + * > > + * @note This function can be used by drivers that provide different > > + * implementations for the same service depending on the execution mode of > > + * the caller. If a caller requests such a service in non-real-time context > > + * but is capable of running in real-time as well, it might be appropriate > > + * for the driver to reject the request via -ENOSYS so that RTDM can switch > > + * the caller and restart the request in real-time context. > > + * > > + * Environments: > > + * > > + * This service can be called from: > > + * > > + * - Kernel module initialization/cleanup code > > + * - Kernel-based task > > + * - User-space task (RT, non-RT) > > + * > > + * Rescheduling: never. > > + */ > > +int rtdm_rt_capable(void); > > + > > #endif /* DOXYGEN_CPP */ > > > > /** @} Utility Services */ > > -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 02/24] RTDM: Add rtdm_rt_capable() service
Philippe Gerum wrote: > On Sun, 2010-04-18 at 15:12 +0200, Jan Kiszka wrote: >> From: Jan Kiszka >> >> This adds rtdm_rt_capable(), a function that can be used by drivers to >> detect callers that could issue a service request also from the >> (typically preferred) real-time context. If that is the case, the driver >> can trigger a restart of the request if the current context is not >> real-time. >> >> CC: Philippe Gerum >> CC: Alexis Berlemont >> Signed-off-by: Jan Kiszka >> --- >> include/rtdm/rtdm_driver.h |6 ++ >> ksrc/skins/rtdm/drvlib.c | 25 + >> 2 files changed, 31 insertions(+), 0 deletions(-) >> >> diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h >> index 0fc1496..45be404 100644 >> --- a/include/rtdm/rtdm_driver.h >> +++ b/include/rtdm/rtdm_driver.h >> @@ -1296,6 +1296,12 @@ static inline int rtdm_in_rt_context(void) >> { >> return (rthal_current_domain != rthal_root_domain); >> } >> + >> +static inline int rtdm_rt_capable(void) >> +{ >> +return xnpod_shadow_p(); >> +} >> + > > This won't do what your comment states; xnpod_shadow_p() would always > return false on behalf of a relaxed shadow, since it tests the status > bits of the current Xenomai thread, which has to be the root one in that > case. xnpod_shadow_p is to be used in primary context only, to > distinguish between kernel-based and userland Xenomai callers. > > What you want is probably something like: > > static inline int rtdm_rt_capable(void) > { > return xnshadow_thread(current) != NULL; > } > Thanks, will fix. Jan PS: Sorry for the From: mess - user error while feeding my posting script. signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 02/24] RTDM: Add rtdm_rt_capable() service
Philippe Gerum wrote: > On Sun, 2010-04-18 at 15:26 +0200, Philippe Gerum wrote: >> On Sun, 2010-04-18 at 15:12 +0200, Jan Kiszka wrote: >>> From: Jan Kiszka >>> >>> This adds rtdm_rt_capable(), a function that can be used by drivers to >>> detect callers that could issue a service request also from the >>> (typically preferred) real-time context. If that is the case, the driver >>> can trigger a restart of the request if the current context is not >>> real-time. >>> >>> CC: Philippe Gerum >>> CC: Alexis Berlemont >>> Signed-off-by: Jan Kiszka >>> --- >>> include/rtdm/rtdm_driver.h |6 ++ >>> ksrc/skins/rtdm/drvlib.c | 25 + >>> 2 files changed, 31 insertions(+), 0 deletions(-) >>> >>> diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h >>> index 0fc1496..45be404 100644 >>> --- a/include/rtdm/rtdm_driver.h >>> +++ b/include/rtdm/rtdm_driver.h >>> @@ -1296,6 +1296,12 @@ static inline int rtdm_in_rt_context(void) >>> { >>> return (rthal_current_domain != rthal_root_domain); >>> } >>> + >>> +static inline int rtdm_rt_capable(void) >>> +{ >>> + return xnpod_shadow_p(); >>> +} >>> + >> This won't do what your comment states; xnpod_shadow_p() would always >> return false on behalf of a relaxed shadow, since it tests the status >> bits of the current Xenomai thread, which has to be the root one in that >> case. xnpod_shadow_p is to be used in primary context only, to >> distinguish between kernel-based and userland Xenomai callers. >> >> What you want is probably something like: >> >> static inline int rtdm_rt_capable(void) >> { >> return xnshadow_thread(current) != NULL; >> } > > Btw, the predicate as you defined it would not work over kernel-based > Xenomai threads. rtdm_rt_capable() is ambiguous here. (!xnpod_root_p() || xnshadow_thread(current) != NULL) ? That would also avoid dereferencing current in a potentially unsafe context (if we still have such problematic archs). Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 08/23] RTDM: Convert device listings to seq_file
From: Jan Kiszka Given a large amount of devices, we could overflow the output page so far. Fix it by moving to seq_file operations. This also allows us to drop the RTDM_PROC_PRINT macros, now that the last user is converted. Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/device.c | 21 + ksrc/skins/rtdm/internal.h | 19 ksrc/skins/rtdm/proc.c | 221 +--- 3 files changed, 168 insertions(+), 93 deletions(-) diff --git a/ksrc/skins/rtdm/device.c b/ksrc/skins/rtdm/device.c index e927ce7..d0e8b46 100644 --- a/ksrc/skins/rtdm/device.c +++ b/ksrc/skins/rtdm/device.c @@ -55,8 +55,8 @@ MODULE_PARM_DESC(protocol_hashtab_size, struct list_head *rtdm_named_devices; /* hash table */ struct list_head *rtdm_protocol_devices; /* hash table */ -static int name_hashkey_mask; -static int proto_hashkey_mask; +int name_hashkey_mask; +int proto_hashkey_mask; DECLARE_MUTEX(nrt_dev_lock); DEFINE_XNLOCK(rt_dev_lock); @@ -77,23 +77,6 @@ int rtdm_select_bind_no_support(struct rtdm_dev_context *context, { return -EBADF; } - -static inline int get_name_hash(const char *str, int limit, int hashkey_mask) -{ - int hash = 0; - - while (*str != 0) { - hash += *str++; - if (--limit == 0) - break; - } - return hash & hashkey_mask; -} - -static inline int get_proto_hash(int protocol_family, int socket_type) -{ - return protocol_family & proto_hashkey_mask; -} static inline void rtdm_reference_device(struct rtdm_device *device) { diff --git a/ksrc/skins/rtdm/internal.h b/ksrc/skins/rtdm/internal.h index 69299f8..86840f9 100644 --- a/ksrc/skins/rtdm/internal.h +++ b/ksrc/skins/rtdm/internal.h @@ -59,6 +59,8 @@ extern int open_fildes; extern struct semaphore nrt_dev_lock; extern unsigned int devname_hashtab_size; extern unsigned int protocol_hashtab_size; +extern int name_hashkey_mask; +extern int proto_hashkey_mask; extern struct list_head *rtdm_named_devices; extern struct list_head *rtdm_protocol_devices; extern struct proc_dir_entry *rtdm_proc_root; @@ -79,6 +81,23 @@ static inline void rtdm_dereference_device(struct rtdm_device *device) atomic_dec(&device->reserved.refcount); } +static inline int get_name_hash(const char *str, int limit, int hashkey_mask) +{ + int hash = 0; + + while (*str != 0) { + hash += *str++; + if (--limit == 0) + break; + } + return hash & hashkey_mask; +} + +static inline int get_proto_hash(int protocol_family, int socket_type) +{ + return protocol_family & proto_hashkey_mask; +} + int __init rtdm_dev_init(void); static inline void rtdm_dev_cleanup(void) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index 20c9ad8..84e3cc0 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -21,100 +21,173 @@ #include "rtdm/internal.h" -/* Derived from Erwin Rol's rtai_proc_fs.h. - Assumes that output fits into the provided buffer. */ - -#define RTDM_PROC_PRINT_VARS(MAX_BLOCK_LEN)\ - const int max_block_len = MAX_BLOCK_LEN;\ - off_t __limit = count - MAX_BLOCK_LEN; \ - int __len = 0; \ - \ - *eof = 1; \ - if (count < MAX_BLOCK_LEN) \ - return 0 - -#define RTDM_PROC_PRINT(fmt, args...) \ -({ \ - __len += snprintf(buf + __len, max_block_len, fmt, ##args); \ - (__len <= __limit); \ -}) - -#define RTDM_PROC_PRINT_DONE \ -return __len - struct proc_dir_entry *rtdm_proc_root; /* /proc/xenomai/rtdm */ -static int proc_read_named_devs(char *buf, char **start, off_t offset, - int count, int *eof, void *data) +static void *devs_seq_start(struct seq_file *seq, loff_t *pos) { - int i; - struct list_head *entry; + struct list_head *list = seq->private; struct rtdm_device *device; - RTDM_PROC_PRINT_VARS(80); + loff_t n = *pos; + int i; - if (down_interruptible(&nrt_dev_lock)) - return -ERESTARTSYS; + if (n == 0) + return SEQ_START_TOKEN; - if (!RTDM_PROC_PRINT("Hash\tName\t\t\t\tDriver\t\t/proc\n")) - goto done; + for (i = 0; i < protocol_hashtab_size; i++) + list_for_each_entry(device, &list[i], reserved.entry) + if (--n == 0) + return device; + return NULL; +} - for (i = 0; i <
[Xenomai-core] [PATCH 11/23] nucleus: Convert faults proc entry to seq_file mechanism
From: Wolfgang Mauerer The entries depend on the number of CPUs and can thus overflow a single page. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/arch/generic/hal.c | 148 +-- 1 files changed, 118 insertions(+), 30 deletions(-) diff --git a/ksrc/arch/generic/hal.c b/ksrc/arch/generic/hal.c index c2239ca..ca221b5 100644 --- a/ksrc/arch/generic/hal.c +++ b/ksrc/arch/generic/hal.c @@ -47,6 +47,7 @@ #include #ifdef CONFIG_PROC_FS #include +#include #endif /* CONFIG_PROC_FS */ #include @@ -642,46 +643,133 @@ static int hal_read_proc(char *page, return len; } -static int faults_read_proc(char *page, -char **start, -off_t off, int count, int *eof, void *data) +struct faults_seq_iterator { + unsigned int nentries; + struct faults_seq_info { + unsigned int trap; + } faults_info[0]; +}; + +static int __faults_seq_open(struct inode *inode, +struct file *file, struct seq_operations *ops) { -int len = 0, cpu, trap; -char *p = page; + struct faults_seq_iterator *iter = NULL; + struct faults_seq_info *faults_info; + struct seq_file *seq; + unsigned int ntraps = 0; + unsigned int trap; + int err; + + for (trap = 0; rthal_fault_labels[trap] != NULL; trap++) { + if (!*rthal_fault_labels[trap]) + continue; + ntraps++; + } -p += sprintf(p, "TRAP "); + iter = kmalloc(sizeof(*iter) + + ntraps * sizeof(struct faults_seq_info), + GFP_KERNEL); + if (!iter) + return -ENOMEM; -for_each_online_cpu(cpu) { -p += sprintf(p, "CPU%d", cpu); -} + err = seq_open(file, ops); -for (trap = 0; rthal_fault_labels[trap] != NULL; trap++) { + if (err) { + kfree(iter); + return err; + } -if (!*rthal_fault_labels[trap]) -continue; + iter->nentries = 0; -p += sprintf(p, "\n%3d: ", trap); + for (trap = 0; rthal_fault_labels[trap] != NULL; trap++) { + if (!*rthal_fault_labels[trap]) + continue; -for_each_online_cpu(cpu) { -p += sprintf(p, "%12u", rthal_realtime_faults[cpu][trap]); -} + faults_info = &iter->faults_info[iter->nentries++]; -p += sprintf(p, "(%s)", rthal_fault_labels[trap]); -} + faults_info->trap = trap; + } -p += sprintf(p, "\n"); + seq = file->private_data; + seq->private = iter; -len = p - page - off; -if (len <= off + count) -*eof = 1; -*start = page + off; -if (len > count) -len = count; -if (len < 0) -len = 0; + return 0; +} -return len; +static void *faults_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct faults_seq_iterator *iter = seq->private; + + if (*pos > iter->nentries) + return NULL; + + if (*pos == 0) + return SEQ_START_TOKEN; + + return iter->faults_info + *pos - 1; } +static void *faults_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct faults_seq_iterator *iter = seq->private; + + (*pos)++; + + if (*pos > iter->nentries) + return NULL; + + return iter->faults_info + *pos - 1; +} + +static void faults_seq_stop(struct seq_file *f, void *v) +{ + /* Nothing to do */ +} + +static int faults_seq_show(struct seq_file *f, void *v) +{ + unsigned int cpu; + struct faults_seq_info *p = v; + + if (v == SEQ_START_TOKEN) { + seq_puts(f, "TRAP "); + + for_each_online_cpu(cpu) { + seq_printf(f, "CPU%d\n", cpu); + } + } + else { + seq_printf(f, "%3d: ", p->trap); + + for_each_online_cpu(cpu) { + seq_printf(f, "%12u", + rthal_realtime_faults[cpu][p->trap]); + } + + seq_printf(f, "(%s)\n", rthal_fault_labels[p->trap]); + } + + return 0; +} + +static struct seq_operations faults_op = { + .start = faults_seq_start, + .next = faults_seq_next, + .stop = faults_seq_stop, + .show = faults_seq_show +}; + +static int faults_seq_open(struct inode *inode, struct file *file) +{ + return __faults_seq_open(inode, file, &faults_op); +} + +static struct file_operations faults_seq_operations = { + .owner = THIS_MODULE, + .open = faults_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release= seq_release_private, +}; static int apc_read_proc(char *page, char **start, @@ -779,
[Xenomai-core] [PATCH 15/23] native: Convert buffer registry proc entry to the seq_file mechanism
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/buffer.c | 46 ++- 1 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ksrc/skins/native/buffer.c b/ksrc/skins/native/buffer.c index 2d364bb..5dc772d 100644 --- a/ksrc/skins/native/buffer.c +++ b/ksrc/skins/native/buffer.c @@ -50,21 +50,19 @@ #ifdef CONFIG_PROC_FS -static int __buffer_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +#include + +static int buffer_seq_show(struct seq_file *f, void *v) { - RT_BUFFER *bf = (RT_BUFFER *)data; - char *p = page; - int len; + RT_BUFFER *bf = (RT_BUFFER *)f->private; spl_t s; xnlock_get_irqsave(&nklock, s); - p += sprintf(p, "type=%s:size=%zu:used=%zu\n", -bf->mode & B_PRIO ? "PRIO" : "FIFO", -bf->bufsz, -bf->fillsz); + seq_printf(f, "type=%s:size=%zu:used=%zu\n", + bf->mode & B_PRIO ? "PRIO" : "FIFO", + bf->bufsz, + bf->fillsz); if (xnsynch_nsleepers(&bf->isynch_base) > 0) { xnpholder_t *holder; @@ -73,7 +71,7 @@ static int __buffer_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s (input)\n", xnthread_name(sleeper)); + seq_printf(f, "+%s (input)\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&bf->isynch_base), holder); @@ -87,7 +85,7 @@ static int __buffer_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s (output)\n", xnthread_name(sleeper)); + seq_printf(f, "+%s (output)\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&bf->osynch_base), holder); @@ -96,18 +94,21 @@ static int __buffer_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int buffer_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, buffer_seq_show, PDE(inode)->data); } +static struct file_operations buffer_proc_fops = { +.owner = THIS_MODULE, +.open = buffer_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __buffer_pnode = { @@ -115,8 +116,9 @@ static xnpnode_t __buffer_pnode = { .dir = NULL, .type = "buffers", .entries = 0, - .read_proc = &__buffer_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &buffer_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 14/23] native: Convert the alarm registry proc entry to seq_single
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/alarm.c | 43 +++ 1 files changed, 23 insertions(+), 20 deletions(-) diff --git a/ksrc/skins/native/alarm.c b/ksrc/skins/native/alarm.c index 1130dfb..4ff14a7 100644 --- a/ksrc/skins/native/alarm.c +++ b/ksrc/skins/native/alarm.c @@ -45,20 +45,18 @@ #ifdef CONFIG_PROC_FS -static int __alarm_read_proc(char *page, -char **start, -off_t off, int count, int *eof, void *data) +#include + +static int alarm_seq_show(struct seq_file *f, void *v) { - RT_ALARM *alarm = (RT_ALARM *)data; - char *p = page; - int len; + RT_ALARM *alarm = (RT_ALARM *)f->private; spl_t s; xnlock_get_irqsave(&nklock, s); - p += sprintf(p, "interval=%Lu:expiries=%lu\n", -rt_timer_tsc2ns(xntimer_interval(&alarm->timer_base)), -alarm->expiries); + seq_printf(f, "interval=%Lu:expiries=%lu\n", + rt_timer_tsc2ns(xntimer_interval(&alarm->timer_base)), + alarm->expiries); #ifdef CONFIG_XENO_OPT_PERVASIVE { @@ -67,7 +65,7 @@ static int __alarm_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); + seq_printf(f, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&alarm->synch_base), holder); @@ -77,18 +75,22 @@ static int __alarm_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int alarm_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, alarm_seq_show, PDE(inode)->data); } +static struct file_operations alarm_proc_fops = { +.owner = THIS_MODULE, +.open = alarm_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + + extern xnptree_t __native_ptree; static xnpnode_t __alarm_pnode = { @@ -96,8 +98,9 @@ static xnpnode_t __alarm_pnode = { .dir = NULL, .type = "alarms", .entries = 0, - .read_proc = &__alarm_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &alarm_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 00/23] [git pull] procfs overflow fixes and seq_file conversions
The following changes since commit 113ea4d56e8b215cb56ae7673013163ea5a5987d: Gilles Chanteperdrix (1): switchtest: increase stack sizes are available in the git repository at: git://git.xenomai.org/xenomai-jki.git queues/proc This series fixes some of the potential (but when they happen fatal) overflows in our procfs outputs. Specifically, it fixes all issues in RTDM (one of them hit us in the field) and the recently reported overflow in /proc/xenomai/heap. Moreover, Wolfgang started the lengthy conversion of the registry by introducing a new seq_file-based interface and already moving the native skin over. The future belongs to seq_file, so some of the patches are strictly spoken not yet required. But we better start this effort before the last legacy interface user was converted and the old interface is suddenly dropped from the kernel. This may not be that far away. A patch of mine to improve error reporting of the old interface was rejected with "->read_proc is going to be removed, so there is no point." Jan Kiszka (9): hal: Mark file ops of rthal_add_proc_seq const RTDM: Plug race between proc_read_dev_info and device deregistration RTDM: Properly clean up on proc setup errors RTDM: Convert fildes proc to single-seq RTDM: Convert device information proc entry to single-seq RTDM: Convert open_fildes reading to seq_file RTDM: Extend device name space in open_fildes proc output RTDM: Convert device listings to seq_file nucleus: Convert heap proc entry to seq_file Wolfgang Mauerer (14): nucleus: Convert irq proc entry to seqfile nucleus: Convert faults proc entry to seq_file mechanism nucleus: Convert apc proc file to the seq_file mechanism nucleus: Add infrastructure for supporting the seq_file mechanism in registry objects native: Convert the alarm registry proc entry to seq_single native: Convert buffer registry proc entry to the seq_file mechanism native: Convert cond registry proc entry to the seq_file mechanism native: convert the proc entry for the semaphore registry to seq_file native: Convert intr registry proc files to seq_file native: Convert event registry proc file to seq_file native: Convert heap registry proc file to seq_file native: Convert mutex registry proc entry to seq_file native: Convert queue registry proc entry to seq_file nucleus: Convert timebases proc entry to seq_file include/asm-generic/hal.h |8 +- include/nucleus/registry.h | 19 +- ksrc/arch/generic/hal.c| 269 +++-- ksrc/nucleus/heap.c| 121 +-- ksrc/nucleus/intr.c| 149 -- ksrc/nucleus/registry.c| 14 ++- ksrc/nucleus/timebase.c| 64 +++--- ksrc/skins/native/alarm.c | 43 ++-- ksrc/skins/native/buffer.c | 46 +++-- ksrc/skins/native/cond.c | 36 ++-- ksrc/skins/native/event.c | 40 ++-- ksrc/skins/native/heap.c | 50 +++--- ksrc/skins/native/intr.c | 44 ++-- ksrc/skins/native/mutex.c | 42 ++-- ksrc/skins/native/queue.c | 44 ++-- ksrc/skins/native/sem.c| 38 ++-- ksrc/skins/rtdm/device.c | 21 +-- ksrc/skins/rtdm/internal.h | 19 ++ ksrc/skins/rtdm/proc.c | 481 +--- 19 files changed, 1008 insertions(+), 540 deletions(-) ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 18/23] native: Convert intr registry proc files to seq_file
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/intr.c | 44 +++- 1 files changed, 23 insertions(+), 21 deletions(-) diff --git a/ksrc/skins/native/intr.c b/ksrc/skins/native/intr.c index a69bd46..955c0e3 100644 --- a/ksrc/skins/native/intr.c +++ b/ksrc/skins/native/intr.c @@ -58,13 +58,11 @@ static unsigned long __intr_get_hits(RT_INTR *intr) #ifdef CONFIG_PROC_FS -static int __intr_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +#include + +static int intr_seq_show(struct seq_file *f, void *v) { - RT_INTR *intr = (RT_INTR *)data; - char *p = page; - int len; + RT_INTR *intr = (RT_INTR *)f->private; spl_t s; xnlock_get_irqsave(&nklock, s); @@ -73,9 +71,9 @@ static int __intr_read_proc(char *page, { xnpholder_t *holder; - p += sprintf(p, "hits=%lu, pending=%u, mode=0x%x\n", -__intr_get_hits(intr), intr->pending, -intr->mode); + seq_printf(f, "hits=%lu, pending=%u, mode=0x%x\n", + __intr_get_hits(intr), intr->pending, + intr->mode); /* Pended interrupt -- dump waiters. */ @@ -83,30 +81,33 @@ static int __intr_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); + seq_printf(f, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&intr->synch_base), holder); } } #else /* !CONFIG_XENO_OPT_PERVASIVE */ - p += sprintf(p, "hits=%lu\n", __intr_get_hits(intr)); + seq_printf(f, "hits=%lu\n", __intr_get_hits(intr)); #endif /* CONFIG_XENO_OPT_PERVASIVE */ xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int intr_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, intr_seq_show, PDE(inode)->data); } +static struct file_operations intr_proc_fops = { +.owner = THIS_MODULE, +.open = intr_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __intr_pnode = { @@ -114,8 +115,9 @@ static xnpnode_t __intr_pnode = { .dir = NULL, .type = "interrupts", .entries = 0, - .read_proc = &__intr_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &intr_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 03/23] RTDM: Properly clean up on proc setup errors
From: Jan Kiszka Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/proc.c | 14 +- 1 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index b889f73..70ee4a2 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -292,34 +292,38 @@ int __init rtdm_proc_init(void) /* Initialise /proc entries */ rtdm_proc_root = create_proc_entry("xenomai/rtdm", S_IFDIR, NULL); if (!rtdm_proc_root) - return -EAGAIN; + goto error; proc_entry = create_proc_entry("named_devices", S_IFREG | S_IRUGO, rtdm_proc_root); if (!proc_entry) - return -EAGAIN; + goto error; proc_entry->read_proc = proc_read_named_devs; proc_entry = create_proc_entry("protocol_devices", S_IFREG | S_IRUGO, rtdm_proc_root); if (!proc_entry) - return -EAGAIN; + goto error; proc_entry->read_proc = proc_read_proto_devs; proc_entry = create_proc_entry("open_fildes", S_IFREG | S_IRUGO, rtdm_proc_root); if (!proc_entry) - return -EAGAIN; + goto error; proc_entry->read_proc = proc_read_open_fildes; proc_entry->write_proc = proc_kill_open_fildes; proc_entry = create_proc_entry("fildes", S_IFREG | S_IRUGO, rtdm_proc_root); if (!proc_entry) - return -EAGAIN; + goto error; proc_entry->read_proc = proc_read_fildes; return 0; + +error: + rtdm_proc_cleanup(); + return -EAGAIN; } void rtdm_proc_cleanup(void) -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 01/23] hal: Mark file ops of rthal_add_proc_seq const
From: Jan Kiszka Older kernels do not have this tag but do not touch them as well, so perform a type cast when assigning them to proc_dir_entry. Signed-off-by: Jan Kiszka --- include/asm-generic/hal.h |2 +- ksrc/arch/generic/hal.c |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-generic/hal.h b/include/asm-generic/hal.h index 84c1a4d..61da1b7 100644 --- a/include/asm-generic/hal.h +++ b/include/asm-generic/hal.h @@ -554,7 +554,7 @@ struct proc_dir_entry *rthal_add_proc_leaf(const char *name, struct proc_dir_entry *parent); struct proc_dir_entry *rthal_add_proc_seq(const char *name, - struct file_operations *fops, + const struct file_operations *fops, size_t size, struct proc_dir_entry *parent); #endif /* CONFIG_PROC_FS */ diff --git a/ksrc/arch/generic/hal.c b/ksrc/arch/generic/hal.c index 8a5ec39..c2239ca 100644 --- a/ksrc/arch/generic/hal.c +++ b/ksrc/arch/generic/hal.c @@ -748,7 +748,7 @@ struct proc_dir_entry *rthal_add_proc_leaf(const char *name, EXPORT_SYMBOL_GPL(rthal_add_proc_leaf); struct proc_dir_entry *rthal_add_proc_seq(const char *name, - struct file_operations *fops, + const struct file_operations *fops, size_t size, struct proc_dir_entry *parent) { @@ -758,7 +758,7 @@ struct proc_dir_entry *rthal_add_proc_seq(const char *name, if (entry == NULL) return NULL; - entry->proc_fops = fops; + entry->proc_fops = (struct file_operations *)fops; wrap_proc_dir_entry_owner(entry); if (size) -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 10/23] nucleus: Convert irq proc entry to seqfile
From: Wolfgang Mauerer On a system with many CPUs, the size of the data can exceed a single page. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/nucleus/intr.c | 149 +++ 1 files changed, 90 insertions(+), 59 deletions(-) diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c index a6de4ea..79fa3e4 100644 --- a/ksrc/nucleus/intr.c +++ b/ksrc/nucleus/intr.c @@ -984,27 +984,27 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) #ifdef CONFIG_PROC_FS #include +#include #include -static int format_irq_proc(unsigned int irq, char *str) +static void format_irq_proc(unsigned int irq, struct seq_file *f) { xnintr_t *intr; - char *p = str; spl_t s; if (rthal_virtual_irq_p(irq)) { - p += sprintf(p, " [virtual]"); - return p - str; + seq_puts(f, " [virtual]"); + return; } else if (irq == XNARCH_TIMER_IRQ) { - p += sprintf(p, " [timer]"); - return p - str; + seq_puts(f, " [timer]"); + return ; #ifdef CONFIG_SMP } else if (irq == RTHAL_SERVICE_IPI0) { - p += sprintf(p, " [IPI]"); - return p - str; + seq_puts(f, " [IPI]"); + return; } else if (irq == RTHAL_CRITICAL_IPI) { - p += sprintf(p, " [critical sync]"); - return p - str; + seq_puts(f, " [critical sync]"); + return; #endif /* CONFIG_SMP */ } @@ -1012,61 +1012,17 @@ static int format_irq_proc(unsigned int irq, char *str) intr = xnintr_shirq_first(irq); if (intr) { - strcpy(p, ""); p += 8; + seq_puts(f, ""); do { - *p = ' '; p += 1; - strcpy(p, intr->name); p += strlen(intr->name); + seq_putc(f, ' '); + seq_printf(f, "%s", intr->name); intr = xnintr_shirq_next(intr); } while (intr); } xnlock_put_irqrestore(&intrlock, s); - - return p - str; -} - -static int irq_read_proc(char *page, -char **start, -off_t off, int count, int *eof, void *data) -{ - int len = 0, cpu, irq; - char *p = page; - - p += sprintf(p, "IRQ "); - - for_each_online_cpu(cpu) { - p += sprintf(p, "CPU%d", cpu); - } - - for (irq = 0; irq < XNARCH_NR_IRQS; irq++) { - if (rthal_irq_handler(&rthal_domain, irq) == NULL) - continue; - - p += sprintf(p, "\n%3d:", irq); - - for_each_online_cpu(cpu) { - p += sprintf(p, "%12lu", -rthal_cpudata_irq_hits(&rthal_domain, cpu, - irq)); - } - - p += format_irq_proc(irq, p); - } - - p += sprintf(p, "\n"); - - len = p - page - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; - - return len; } #ifdef CONFIG_SMP @@ -1094,6 +1050,75 @@ static int affinity_read_proc(char *page, return len; } +static void *irq_seq_start(struct seq_file *seq, loff_t *pos) +{ + /* +* Note: Position 0 is the header, so we need to +* use <= instead of < +*/ + return (*pos <= XNARCH_NR_IRQS) ? pos : NULL; +} + +static void irq_seq_stop(struct seq_file *f, void *v) +{ + /* Nothing to do */ +} + +static void *irq_seq_next(struct seq_file *f, void *v, loff_t *pos) +{ + (*pos)++; + + if (*pos > XNARCH_NR_IRQS) + return NULL; + + return pos; +} + +static int irq_seq_show(struct seq_file *f, void *v) +{ + unsigned int i = *(loff_t *) v; + unsigned int irq, cpu; + + if (i == 0) { + seq_puts(f, "IRQ "); + for_each_online_cpu(cpu) { + seq_printf(f, "CPU%u", cpu); + } + seq_putc(f, '\n'); + + return 0; + } + + irq = i - 1; + if (rthal_irq_handler(&rthal_domain, irq) == NULL) + return 0; + + seq_printf(f, "%3d:", irq); + + for_each_online_cpu(cpu) { + seq_printf(f, "%12lu", + rthal_cpudata_irq_hits(&rthal_domain, cpu, + irq)); + } + + format_irq_proc(irq, f); + seq_putc(f, '\n'); + + return 0; +} + +static struct seq_operations irq_seq_ops = { + .start = irq_seq_start, + .n
[Xenomai-core] [PATCH 13/23] nucleus: Add infrastructure for supporting the seq_file mechanism in registry objects
From: Wolfgang Mauerer We augment struct xnpnode with a new element for representing file_operations that allow for using more generic file system methods than read_proc. However, we have to retain read_proc and write_proc for now since not all proc entries are immediately converted. However, we should be able to get rid of them in the future because writing can as well be implemented in conjunction to the seq_file mechanism. NOTE: When the proc file depends on a data argument given to registry_enter, it can be obtained in seq_open via PDE(inode)->data. In turn, it should be associated with the seq_file instance, which is easy enough for single_open (just use it as third argument). It must be done manually for seq_open; note that seq_file is available as file->private after the call. ((struct seq_file *)file->private)->private = PDE(inode)->data is your friend. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- include/asm-generic/hal.h |6 ++ include/nucleus/registry.h | 19 --- ksrc/arch/generic/hal.c| 18 ++ ksrc/nucleus/registry.c| 14 +- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/include/asm-generic/hal.h b/include/asm-generic/hal.h index 61da1b7..04979cd 100644 --- a/include/asm-generic/hal.h +++ b/include/asm-generic/hal.h @@ -557,6 +557,12 @@ struct proc_dir_entry *rthal_add_proc_seq(const char *name, const struct file_operations *fops, size_t size, struct proc_dir_entry *parent); + +struct proc_dir_entry *rthal_add_proc_seq_data(const char *name, + const struct file_operations *fops, + size_t size, + void *data, + struct proc_dir_entry *parent); #endif /* CONFIG_PROC_FS */ #ifdef CONFIG_IPIPE_TRACE diff --git a/include/nucleus/registry.h b/include/nucleus/registry.h index 56826db..3685308 100644 --- a/include/nucleus/registry.h +++ b/include/nucleus/registry.h @@ -73,6 +73,7 @@ void xnregistry_cleanup(void); #ifdef CONFIG_PROC_FS #include +#include #define XNOBJECT_PROC_RESERVED1 ((struct proc_dir_entry *)1) #define XNOBJECT_PROC_RESERVED2 ((struct proc_dir_entry *)2) @@ -90,13 +91,17 @@ typedef struct xnptree { typedef struct xnpnode { -struct proc_dir_entry *dir; -const char *type; -int entries; -read_proc_t *read_proc; -write_proc_t *write_proc; -link_proc_t *link_proc; -xnptree_t *root; + struct proc_dir_entry *dir; + const char *type; + int entries; + + /* NOTE: Use either read_proc/write_proc, link_proc or fops. */ + read_proc_t *read_proc; + write_proc_t *write_proc; + link_proc_t *link_proc; + struct file_operations *fops; + + xnptree_t *root; } xnpnode_t; diff --git a/ksrc/arch/generic/hal.c b/ksrc/arch/generic/hal.c index c97659a..3b38895 100644 --- a/ksrc/arch/generic/hal.c +++ b/ksrc/arch/generic/hal.c @@ -901,6 +901,24 @@ struct proc_dir_entry *rthal_add_proc_seq(const char *name, } EXPORT_SYMBOL_GPL(rthal_add_proc_seq); +struct proc_dir_entry +*rthal_add_proc_seq_data(const char *name, +const struct file_operations *fops, +size_t size, +void *data, +struct proc_dir_entry *parent) +{ + struct proc_dir_entry *entry; + + entry = rthal_add_proc_seq(name, fops, size, parent); + + if (entry) + entry->data = data; + + return entry; +} +EXPORT_SYMBOL_GPL(rthal_add_proc_seq_data); + static int rthal_proc_register(void) { rthal_proc_root = create_proc_entry("xenomai", S_IFDIR, 0); diff --git a/ksrc/nucleus/registry.c b/ksrc/nucleus/registry.c index 9958dd3..c71da5d 100644 --- a/ksrc/nucleus/registry.c +++ b/ksrc/nucleus/registry.c @@ -338,8 +338,20 @@ static DECLARE_WORK_FUNC(registry_proc_callback) object->proc = add_proc_link(object->key, pnode->link_proc, object->objaddr, dir); + else if (pnode->fops) + /* Entry is a proper file */ + object->proc = rthal_add_proc_seq_data(object->key, + pnode->fops, + 0, + object->objaddr, + dir); else - /* Entry allows to get/set object properties. */ + /* +* Entry allows us to get/set object pr
[Xenomai-core] [PATCH 09/23] nucleus: Convert heap proc entry to seq_file
From: Jan Kiszka This fixes buffer overflows when large number of heaps are registered. Signed-off-by: Jan Kiszka --- ksrc/nucleus/heap.c | 121 +-- 1 files changed, 98 insertions(+), 23 deletions(-) diff --git a/ksrc/nucleus/heap.c b/ksrc/nucleus/heap.c index e5dfef0..3891cd3 100644 --- a/ksrc/nucleus/heap.c +++ b/ksrc/nucleus/heap.c @@ -1409,16 +1409,69 @@ void xnheap_destroy_mapped(xnheap_t *heap, #ifdef CONFIG_PROC_FS -#include +#include + +struct heap_seq_iterator { + int nentries; + struct heap_seq_info { + u_long usable_mem; + u_long used_mem; + u_long page_size; + char label[XNOBJECT_NAME_LEN]; + } heap_info[1]; +}; + +static void *heap_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct heap_seq_iterator *iter = seq->private; + + if (*pos >= iter->nentries) + return NULL; + + return iter->heap_info + *pos; +} + +static void *heap_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct heap_seq_iterator *iter = seq->private; + + ++*pos; -static int heap_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) + if (*pos >= iter->nentries) + return NULL; + + return iter->heap_info + *pos; +} + +static void heap_seq_stop(struct seq_file *seq, void *v) +{ +} + +static int heap_seq_show(struct seq_file *seq, void *v) { + struct heap_seq_info *p = v; + + seq_printf(seq, "size=%lu:used=%lu:pagesz=%lu (%s)\n", + p->usable_mem, p->used_mem, p->page_size, p->label); + return 0; +} + +static const struct seq_operations heap_op = { + .start = heap_seq_start, + .next = heap_seq_next, + .stop = heap_seq_stop, + .show = heap_seq_show +}; + +static int heap_seq_open(struct inode *inode, struct file *file) +{ + struct heap_seq_iterator *iter = NULL; + struct heap_seq_info *heap_info; + struct seq_file *seq; unsigned long rev; xnholder_t *entry; xnheap_t *heap; - int len; + int count, err; spl_t s; if (!xnpod_active_p()) @@ -1427,17 +1480,38 @@ static int heap_read_proc(char *page, xnlock_get_irqsave(&nklock, s); restart: - len = 0; + count = countq(&heapq); /* Cannot be empty (system heap) */ + rev = heapq_rev; + + xnlock_put_irqrestore(&nklock, s); + + kfree(iter); + iter = kmalloc(sizeof(*iter) + + (count - 1) * sizeof(struct heap_seq_info), + GFP_KERNEL); + if (!iter) + return -ENOMEM; + + err = seq_open(file, &heap_op); + if (err) { + kfree(iter); + return err; + } + + iter->nentries = 0; + + xnlock_get_irqsave(&nklock, s); entry = getheadq(&heapq); while (entry) { heap = container_of(entry, xnheap_t, stat_link); - len += sprintf(page + len, - "size=%lu:used=%lu:pagesz=%lu (%s)\n", - xnheap_usable_mem(heap), - xnheap_used_mem(heap), - xnheap_page_size(heap), - heap->label); + heap_info = &iter->heap_info[iter->nentries++]; + + heap_info->usable_mem = xnheap_usable_mem(heap); + heap_info->used_mem = xnheap_used_mem(heap); + heap_info->page_size = xnheap_page_size(heap); + memcpy(heap_info->label, heap->label, + sizeof(heap_info->label)); rev = heapq_rev; @@ -1451,22 +1525,23 @@ restart: xnlock_put_irqrestore(&nklock, s); - len -= off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + seq = file->private_data; + seq->private = iter; - return len; + return 0; } +static const struct file_operations heap_operations = { + .owner = THIS_MODULE, + .open = heap_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release= seq_release_private, +}; + void xnheap_init_proc(void) { - rthal_add_proc_leaf("heap", &heap_read_proc, NULL, NULL, - rthal_proc_root); + rthal_add_proc_seq("heap", &heap_operations, 0, rthal_proc_root); } void xnheap_cleanup_proc(void) -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 04/23] RTDM: Convert fildes proc to single-seq
From: Jan Kiszka As read_proc is deprecated and will die soon, we have to convert to single-seq. Start with RTDM's fildes proc entry. Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/proc.c | 31 --- 1 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index 70ee4a2..ff264b6 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -17,6 +17,8 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + #include "rtdm/internal.h" /* Derived from Erwin Rol's rtai_proc_fs.h. @@ -189,17 +191,26 @@ static int proc_kill_open_fildes(struct file *file, const char __user *buffer, return count; } -static int proc_read_fildes(char *buf, char **start, off_t offset, - int count, int *eof, void *data) +static int fildes_show(struct seq_file *seq, void *v) { - RTDM_PROC_PRINT_VARS(80); - - RTDM_PROC_PRINT("total=%d:open=%d:free=%d\n", RTDM_FD_MAX, - open_fildes, RTDM_FD_MAX - open_fildes); + seq_printf(seq, "total=%d:open=%d:free=%d\n", + RTDM_FD_MAX, open_fildes, RTDM_FD_MAX - open_fildes); + return 0; +} - RTDM_PROC_PRINT_DONE; +static int fildes_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, fildes_show, NULL); } +static const struct file_operations fildes_operations = { + .owner = THIS_MODULE, + .open = fildes_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + static int proc_read_dev_info(char *buf, char **start, off_t offset, int count, int *eof, void *data) { @@ -313,11 +324,9 @@ int __init rtdm_proc_init(void) proc_entry->read_proc = proc_read_open_fildes; proc_entry->write_proc = proc_kill_open_fildes; - proc_entry = - create_proc_entry("fildes", S_IFREG | S_IRUGO, rtdm_proc_root); - if (!proc_entry) + if (!rthal_add_proc_seq("fildes", &fildes_operations, 0, + rtdm_proc_root)) goto error; - proc_entry->read_proc = proc_read_fildes; return 0; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 07/23] RTDM: Extend device name space in open_fildes proc output
From: Jan Kiszka Device names can be up to 31 characters long. Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/proc.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index e83c0c4..20c9ad8 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -146,7 +146,7 @@ static int open_fildes_seq_show(struct seq_file *seq, void *v) spl_t s; if (v == SEQ_START_TOKEN) { - seq_printf(seq, "Index\tLocked\tDevice\t\tOwner [PID]\n"); + seq_printf(seq, "Index\tLocked\tDevice\t\t\t\tOwner [PID]\n"); return 0; } @@ -173,7 +173,7 @@ static int open_fildes_seq_show(struct seq_file *seq, void *v) xnlock_put_irqrestore(&rt_fildes_lock, s); - seq_printf(seq, "%d\t%d\t%-15s %s [%d]\n", + seq_printf(seq, "%d\t%d\t%-31s %s [%d]\n", (int)(fildes - fildes_table), close_lock_count, (device->device_flags & RTDM_NAMED_DEVICE) ? device->device_name : device->proc_name, -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 06/23] RTDM: Convert open_fildes reading to seq_file
From: Jan Kiszka This avoids overflows in case the number of open file descriptors gets too high. Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/proc.c | 119 1 files changed, 80 insertions(+), 39 deletions(-) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index 9b5d349..e83c0c4 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -76,6 +76,10 @@ static int proc_read_named_devs(char *buf, char **start, off_t offset, RTDM_PROC_PRINT_DONE; } +static void dummy_seq_stop(struct seq_file *seq, void *v) +{ +} + static int proc_read_proto_devs(char *buf, char **start, off_t offset, int count, int *eof, void *data) { @@ -111,61 +115,90 @@ static int proc_read_proto_devs(char *buf, char **start, off_t offset, RTDM_PROC_PRINT_DONE; } -static int proc_read_open_fildes(char *buf, char **start, off_t offset, -int count, int *eof, void *data) +static void *open_fildes_seq_start(struct seq_file *seq, loff_t *pos) { - int i; - int close_lock_count; + if (*pos > RTDM_FD_MAX) + return NULL; + + if (*pos == 0) + return SEQ_START_TOKEN; + + return &fildes_table[*pos - 1]; +} + +static void *open_fildes_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ++*pos; + + if (*pos > RTDM_FD_MAX) + return NULL; + + return &fildes_table[*pos - 1]; +} + +static int open_fildes_seq_show(struct seq_file *seq, void *v) +{ + struct rtdm_fildes *fildes = v; + struct rtdm_dev_context *context; struct rtdm_device *device; struct rtdm_process owner; + int close_lock_count; spl_t s; - RTDM_PROC_PRINT_VARS(80); - if (!RTDM_PROC_PRINT("Index\tLocked\tDevice\t\tOwner [PID]\n")) - goto done; + if (v == SEQ_START_TOKEN) { + seq_printf(seq, "Index\tLocked\tDevice\t\tOwner [PID]\n"); + return 0; + } if (down_interruptible(&nrt_dev_lock)) return -ERESTARTSYS; - for (i = 0; i < RTDM_FD_MAX; i++) { - struct rtdm_dev_context *context; - - xnlock_get_irqsave(&rt_fildes_lock, s); + xnlock_get_irqsave(&rt_fildes_lock, s); - context = fildes_table[i].context; - if (!context) { - xnlock_put_irqrestore(&rt_fildes_lock, s); - continue; - } + context = fildes->context; + if (!context) { + xnlock_put_irqrestore(&rt_fildes_lock, s); + goto unlock_out; + } - close_lock_count = atomic_read(&context->close_lock_count); - device = context->device; + close_lock_count = atomic_read(&context->close_lock_count); + device = context->device; - if (context->reserved.owner) - memcpy(&owner, context->reserved.owner, sizeof(owner)); - else { - strcpy(owner.name, ""); - owner.pid = -1; - } + if (context->reserved.owner) + memcpy(&owner, context->reserved.owner, sizeof(owner)); + else { + strcpy(owner.name, ""); + owner.pid = -1; + } - xnlock_put_irqrestore(&rt_fildes_lock, s); + xnlock_put_irqrestore(&rt_fildes_lock, s); - if (!RTDM_PROC_PRINT("%d\t%d\t%-15s %s [%d]\n", i, -close_lock_count, -(device->device_flags&RTDM_NAMED_DEVICE) ? -device->device_name : device->proc_name, -owner.name, owner.pid)) - break; - } + seq_printf(seq, "%d\t%d\t%-15s %s [%d]\n", + (int)(fildes - fildes_table), close_lock_count, + (device->device_flags & RTDM_NAMED_DEVICE) ? + device->device_name : device->proc_name, + owner.name, owner.pid); +unlock_out: up(&nrt_dev_lock); + return 0; +} - done: - RTDM_PROC_PRINT_DONE; +static const struct seq_operations open_fildes_op = { + .start = open_fildes_seq_start, + .next = open_fildes_seq_next, + .stop = dummy_seq_stop, + .show = open_fildes_seq_show +}; + +static int open_fildes_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &open_fildes_op); } -static int proc_kill_open_fildes(struct file *file, const char __user *buffer, -unsigned long count, void *data) +static ssize_t +proc_kill_open_fildes(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) { char krnl_buf[32]; int fd; @@ -191,6 +224,15 @@ stat
[Xenomai-core] [PATCH 02/23] RTDM: Plug race between proc_read_dev_info and device deregistration
From: Jan Kiszka As the device references passed to proc_read_dev_info may become invalid while we dereference it, we need to acquire nrt_dev_lock and check the pointer against our list of registered devices. Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/proc.c | 29 ++--- 1 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index c797764..b889f73 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -203,11 +203,33 @@ static int proc_read_fildes(char *buf, char **start, off_t offset, static int proc_read_dev_info(char *buf, char **start, off_t offset, int count, int *eof, void *data) { - /* accessing the device during unregister (remove_proc_entry) might be - racy, but no official workaround is known yet */ - struct rtdm_device *device = data; + struct rtdm_device *device; + int i; RTDM_PROC_PRINT_VARS(256); + if (down_interruptible(&nrt_dev_lock)) + return -ERESTARTSYS; + + /* +* As the device may have disappeared while the handler was called, +* first match the pointer against registered devices. +*/ + for (i = 0; i < devname_hashtab_size; i++) + list_for_each_entry(device, &rtdm_named_devices[i], + reserved.entry) + if (device == data) + goto found; + + for (i = 0; i < protocol_hashtab_size; i++) + list_for_each_entry(device, &rtdm_protocol_devices[i], + reserved.entry) + if (device == data) + goto found; + + up(&nrt_dev_lock); + return -ENODEV; + +found: if (!RTDM_PROC_PRINT("driver:\t\t%s\nversion:\t%d.%d.%d\n", device->driver_name, RTDM_DRIVER_MAJOR_VER(device->driver_version), @@ -232,6 +254,7 @@ static int proc_read_dev_info(char *buf, char **start, off_t offset, atomic_read(&device->reserved.refcount)); done: + up(&nrt_dev_lock); RTDM_PROC_PRINT_DONE; } -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 19/23] native: Convert event registry proc file to seq_file
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/event.c | 40 +--- 1 files changed, 21 insertions(+), 19 deletions(-) diff --git a/ksrc/skins/native/event.c b/ksrc/skins/native/event.c index 5b2a8b5..d674a89 100644 --- a/ksrc/skins/native/event.c +++ b/ksrc/skins/native/event.c @@ -47,18 +47,16 @@ #ifdef CONFIG_PROC_FS -static int __event_read_proc(char *page, -char **start, -off_t off, int count, int *eof, void *data) +#include + +static int event_seq_show(struct seq_file *f, void *v) { - RT_EVENT *event = (RT_EVENT *)data; - char *p = page; - int len; + RT_EVENT *event = (RT_EVENT *)f->private; spl_t s; xnlock_get_irqsave(&nklock, s); - p += sprintf(p, "=0x%lx\n", event->value); + seq_printf(f, "=0x%lx\n", event->value); if (xnsynch_nsleepers(&event->synch_base) > 0) { xnpholder_t *holder; @@ -74,8 +72,8 @@ static int __event_read_proc(char *page, (task->wait_args.event. mode & EV_ANY) ? "any" : "all"; unsigned long mask = task->wait_args.event.mask; - p += sprintf(p, "+%s (mask=0x%lx, %s)\n", -xnthread_name(sleeper), mask, mode); + seq_printf(f, "+%s (mask=0x%lx, %s)\n", + xnthread_name(sleeper), mask, mode); holder = nextpq(xnsynch_wait_queue(&event->synch_base), holder); @@ -84,18 +82,21 @@ static int __event_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int event_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, event_seq_show, PDE(inode)->data); } +static struct file_operations event_proc_fops = { +.owner = THIS_MODULE, +.open = event_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __event_pnode = { @@ -103,8 +104,9 @@ static xnpnode_t __event_pnode = { .dir = NULL, .type = "events", .entries = 0, - .read_proc = &__event_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &event_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 12/23] nucleus: Convert apc proc file to the seq_file mechanism
From: Wolfgang Mauerer Same procedure as last year, Miss Sophie? Same procedure as every year, James. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/arch/generic/hal.c | 99 ++- 1 files changed, 72 insertions(+), 27 deletions(-) diff --git a/ksrc/arch/generic/hal.c b/ksrc/arch/generic/hal.c index ca221b5..c97659a 100644 --- a/ksrc/arch/generic/hal.c +++ b/ksrc/arch/generic/hal.c @@ -771,47 +771,92 @@ static struct file_operations faults_seq_operations = { .release= seq_release_private, }; -static int apc_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +static inline void *apc_seq_find_valid_pos(loff_t *pos) { -int len = 0, cpu, apc; -char *p = page; + while (!(*pos > BITS_PER_LONG) && + !test_bit(*pos - 1, &rthal_apc_map)) { + (*pos)++; + } -p += sprintf(p, "APC "); + if (*pos > BITS_PER_LONG) { + return NULL; + } -for_each_online_cpu(cpu) { -p += sprintf(p, " CPU%d", cpu); -} + return pos; +} -for (apc = 0; apc < BITS_PER_LONG; apc++) { -if (!test_bit(apc, &rthal_apc_map)) -continue; /* Not hooked. */ +static void *apc_seq_start(struct seq_file *seq, loff_t *pos) +{ + /* The header is valid, naturally */ + if (*pos == 0) + return pos; -p += sprintf(p, "\n%3d: ", apc); + return apc_seq_find_valid_pos(pos); +} + +static void apc_seq_stop(struct seq_file *f, void *v) +{ + /* Nothing to do */ +} + +static void *apc_seq_next(struct seq_file *f, void *v, loff_t *pos) +{ + (*pos)++; + + return apc_seq_find_valid_pos(pos); +} + +static int apc_seq_show(struct seq_file *f, void *v) +{ + unsigned int i = *(loff_t *) v; + unsigned int apc, cpu; + + if (i == 0) { + seq_puts(f, "APC "); + for_each_online_cpu(cpu) { + seq_printf(f, "CPU%u", cpu); + } + seq_putc(f, '\n'); + + return 0; + } + + apc = i - 1; + +seq_printf(f, "%3d: ", apc); for_each_online_cpu(cpu) { -p += sprintf(p, "%12lu", rthal_apc_table[apc].hits[cpu]); +seq_printf(f, "%12lu", rthal_apc_table[apc].hits[cpu]); } if (rthal_apc_table[apc].name) - p += sprintf(p, "(%s)", rthal_apc_table[apc].name); -} + seq_printf(f, "(%s)", rthal_apc_table[apc].name); -p += sprintf(p, "\n"); + seq_putc(f, '\n'); -len = p - page - off; -if (len <= off + count) -*eof = 1; -*start = page + off; -if (len > count) -len = count; -if (len < 0) -len = 0; + return 0; +} -return len; +static struct seq_operations apc_seq_ops = { + .start = apc_seq_start, + .next = apc_seq_next, + .stop = apc_seq_stop, + .show = apc_seq_show, +}; + +static int apc_open(struct inode *inode, struct file *filp) +{ + return seq_open(filp, &apc_seq_ops); } +static struct file_operations apc_seq_operations = { + .open = apc_open, + .read = seq_read, + .llseek = seq_lseek, + .release= seq_release, +}; + + struct proc_dir_entry *rthal_add_proc_leaf(const char *name, read_proc_t rdproc, write_proc_t wrproc, @@ -869,7 +914,7 @@ static int rthal_proc_register(void) rthal_add_proc_leaf("hal", &hal_read_proc, NULL, NULL, rthal_proc_root); rthal_add_proc_seq("faults", &faults_seq_operations, 0, rthal_proc_root); - rthal_add_proc_leaf("apc", &apc_read_proc, NULL, NULL, rthal_proc_root); + rthal_add_proc_seq("apc", &apc_seq_operations, 0, rthal_proc_root); rthal_nmi_proc_register(); -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 05/23] RTDM: Convert device information proc entry to single-seq
From: Jan Kiszka Signed-off-by: Jan Kiszka --- ksrc/skins/rtdm/proc.c | 77 1 files changed, 45 insertions(+), 32 deletions(-) diff --git a/ksrc/skins/rtdm/proc.c b/ksrc/skins/rtdm/proc.c index ff264b6..9b5d349 100644 --- a/ksrc/skins/rtdm/proc.c +++ b/ksrc/skins/rtdm/proc.c @@ -211,12 +211,10 @@ static const struct file_operations fildes_operations = { .release= single_release, }; -static int proc_read_dev_info(char *buf, char **start, off_t offset, - int count, int *eof, void *data) +static int dev_info_show(struct seq_file *seq, void *v) { struct rtdm_device *device; int i; - RTDM_PROC_PRINT_VARS(256); if (down_interruptible(&nrt_dev_lock)) return -ERESTARTSYS; @@ -228,47 +226,63 @@ static int proc_read_dev_info(char *buf, char **start, off_t offset, for (i = 0; i < devname_hashtab_size; i++) list_for_each_entry(device, &rtdm_named_devices[i], reserved.entry) - if (device == data) + if (device == seq->private) goto found; for (i = 0; i < protocol_hashtab_size; i++) list_for_each_entry(device, &rtdm_protocol_devices[i], reserved.entry) - if (device == data) + if (device == seq->private) goto found; up(&nrt_dev_lock); return -ENODEV; found: - if (!RTDM_PROC_PRINT("driver:\t\t%s\nversion:\t%d.%d.%d\n", -device->driver_name, -RTDM_DRIVER_MAJOR_VER(device->driver_version), -RTDM_DRIVER_MINOR_VER(device->driver_version), -RTDM_DRIVER_PATCH_VER(device->driver_version))) - goto done; - if (!RTDM_PROC_PRINT("peripheral:\t%s\nprovider:\t%s\n", -device->peripheral_name, device->provider_name)) - goto done; - if (!RTDM_PROC_PRINT("class:\t\t%d\nsub-class:\t%d\n", -device->device_class, device->device_sub_class)) - goto done; - if (!RTDM_PROC_PRINT("flags:\t\t%s%s%s\n", -(device->device_flags & RTDM_EXCLUSIVE) ? -"EXCLUSIVE " : "", -(device->device_flags & RTDM_NAMED_DEVICE) ? -"NAMED_DEVICE " : "", -(device->device_flags & RTDM_PROTOCOL_DEVICE) ? -"PROTOCOL_DEVICE " : "")) - goto done; - RTDM_PROC_PRINT("lock count:\t%d\n", - atomic_read(&device->reserved.refcount)); + seq_printf(seq, "driver:\t\t%-64s\nversion:\t%d.%d.%d\n", + device->driver_name, + RTDM_DRIVER_MAJOR_VER(device->driver_version), + RTDM_DRIVER_MINOR_VER(device->driver_version), + RTDM_DRIVER_PATCH_VER(device->driver_version)); + seq_printf(seq, "peripheral:\t%-64s\nprovider:\t%-64s\n", + device->peripheral_name, device->provider_name); + seq_printf(seq, "class:\t\t%d\nsub-class:\t%d\n", +device->device_class, device->device_sub_class); + seq_printf(seq, "flags:\t\t%s%s%s\n", + (device->device_flags & RTDM_EXCLUSIVE) ? + "EXCLUSIVE " : "", + (device->device_flags & RTDM_NAMED_DEVICE) ? + "NAMED_DEVICE " : "", + (device->device_flags & RTDM_PROTOCOL_DEVICE) ? + "PROTOCOL_DEVICE " : ""); + seq_printf(seq, "lock count:\t%d\n", + atomic_read(&device->reserved.refcount)); - done: up(&nrt_dev_lock); - RTDM_PROC_PRINT_DONE; + return 0; +} + +static int dev_info_proc_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + int err; + + err = single_open(file, dev_info_show, NULL); + if (!err) { + seq = file->private_data; + seq->private = PDE(inode)->data; + } + return err; } +static const struct file_operations dev_info_operations = { + .owner = THIS_MODULE, + .open = dev_info_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + int rtdm_proc_register_device(struct rtdm_device *device) { struct proc_dir_entry *dev_dir; @@ -278,14 +292,13 @@ int rtdm_proc_register_device(struct rtdm_device *device) if (!dev_dir) goto err_out; - proc_entry = create_proc_entry("information", S_IFREG | S_IRUGO, - dev_dir); + proc_en
[Xenomai-core] [PATCH 20/23] native: Convert heap registry proc file to seq_file
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/heap.c | 50 +++-- 1 files changed, 26 insertions(+), 24 deletions(-) diff --git a/ksrc/skins/native/heap.c b/ksrc/skins/native/heap.c index 2a5de8c..560cc4b 100644 --- a/ksrc/skins/native/heap.c +++ b/ksrc/skins/native/heap.c @@ -51,21 +51,19 @@ #ifdef CONFIG_PROC_FS -static int __heap_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +#include + +static int heap_seq_show(struct seq_file *f, void *v) { - RT_HEAP *heap = (RT_HEAP *)data; - char *p = page; - int len; + RT_HEAP *heap = (RT_HEAP *)f->private; spl_t s; - p += sprintf(p, "type=%s:size=%lu:used=%lu:numaps=%lu\n", -(heap->mode & H_SHARED) == H_SHARED ? "shared" : -(heap->mode & H_MAPPABLE) ? "mappable" : "kernel", -xnheap_usable_mem(&heap->heap_base), -xnheap_used_mem(&heap->heap_base), -heap->heap_base.archdep.numaps); + seq_printf(f, "type=%s:size=%lu:used=%lu:numaps=%lu\n", + (heap->mode & H_SHARED) == H_SHARED ? "shared" : + (heap->mode & H_MAPPABLE) ? "mappable" : "kernel", + xnheap_usable_mem(&heap->heap_base), + xnheap_used_mem(&heap->heap_base), + heap->heap_base.archdep.numaps); xnlock_get_irqsave(&nklock, s); @@ -79,8 +77,8 @@ static int __heap_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); size_t size = sleeper->wait_u.buffer.size; - p += sprintf(p, "+%s (size=%zd)\n", -xnthread_name(sleeper), size); + seq_printf(f, "+%s (size=%zd)\n", + xnthread_name(sleeper), size); holder = nextpq(xnsynch_wait_queue(&heap->synch_base), holder); @@ -89,18 +87,21 @@ static int __heap_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int heap_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, heap_seq_show, PDE(inode)->data); } +static struct file_operations heap_proc_fops = { +.owner = THIS_MODULE, +.open = heap_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __heap_pnode = { @@ -108,8 +109,9 @@ static xnpnode_t __heap_pnode = { .dir = NULL, .type = "heaps", .entries = 0, - .read_proc = &__heap_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &heap_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 16/23] native: Convert cond registry proc entry to the seq_file mechanism
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/cond.c | 36 +++- 1 files changed, 19 insertions(+), 17 deletions(-) diff --git a/ksrc/skins/native/cond.c b/ksrc/skins/native/cond.c index 86f83ff..081c2af 100644 --- a/ksrc/skins/native/cond.c +++ b/ksrc/skins/native/cond.c @@ -50,13 +50,11 @@ #ifdef CONFIG_PROC_FS -static int __cond_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +#include + +static int cond_seq_show(struct seq_file *f, void *v) { - RT_COND *cond = (RT_COND *)data; - char *p = page; - int len; + RT_COND *cond = (RT_COND *)f->private; spl_t s; xnlock_get_irqsave(&nklock, s); @@ -70,7 +68,7 @@ static int __cond_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); + seq_printf(f, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&cond->synch_base), holder); @@ -79,18 +77,21 @@ static int __cond_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int cond_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, cond_seq_show, PDE(inode)->data); } +static struct file_operations cond_proc_fops = { +.owner = THIS_MODULE, +.open = cond_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __cond_pnode = { @@ -98,8 +99,9 @@ static xnpnode_t __cond_pnode = { .dir = NULL, .type = "condvars", .entries = 0, - .read_proc = &__cond_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &cond_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 22/23] native: Convert queue registry proc entry to seq_file
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/queue.c | 44 +++- 1 files changed, 23 insertions(+), 21 deletions(-) diff --git a/ksrc/skins/native/queue.c b/ksrc/skins/native/queue.c index 6a71165..72a640d 100644 --- a/ksrc/skins/native/queue.c +++ b/ksrc/skins/native/queue.c @@ -49,19 +49,17 @@ #ifdef CONFIG_PROC_FS -static int __queue_read_proc(char *page, -char **start, -off_t off, int count, int *eof, void *data) +#include + +static int queue_seq_show(struct seq_file *f, void *v) { - RT_QUEUE *q = (RT_QUEUE *)data; - char *p = page; - int len; + RT_QUEUE *q = (RT_QUEUE *)f->private; spl_t s; - p += sprintf(p, "type=%s:poolsz=%lu:usedmem=%lu:limit=%d:mcount=%d\n", -q->mode & Q_SHARED ? "shared" : "local", -xnheap_usable_mem(&q->bufpool), xnheap_used_mem(&q->bufpool), -q->qlimit, countq(&q->pendq)); + seq_printf(f, "type=%s:poolsz=%lu:usedmem=%lu:limit=%d:mcount=%d\n", + q->mode & Q_SHARED ? "shared" : "local", + xnheap_usable_mem(&q->bufpool), xnheap_used_mem(&q->bufpool), + q->qlimit, countq(&q->pendq)); xnlock_get_irqsave(&nklock, s); @@ -74,7 +72,7 @@ static int __queue_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); + seq_printf(f, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&q->synch_base), holder); } @@ -82,18 +80,21 @@ static int __queue_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int queue_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, queue_seq_show, PDE(inode)->data); } +static struct file_operations queue_proc_fops = { +.owner = THIS_MODULE, +.open = queue_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __queue_pnode = { @@ -101,8 +102,9 @@ static xnpnode_t __queue_pnode = { .dir = NULL, .type = "queues", .entries = 0, - .read_proc = &__queue_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &queue_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 21/23] native: Convert mutex registry proc entry to seq_file
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/mutex.c | 42 ++ 1 files changed, 22 insertions(+), 20 deletions(-) diff --git a/ksrc/skins/native/mutex.c b/ksrc/skins/native/mutex.c index 6cf7eb1..4f3e9dc 100644 --- a/ksrc/skins/native/mutex.c +++ b/ksrc/skins/native/mutex.c @@ -53,17 +53,15 @@ #ifdef CONFIG_PROC_FS -static int __mutex_read_proc(char *page, -char **start, -off_t off, int count, int *eof, void *data) +#include + +static int mutex_seq_show(struct seq_file *f, void *v) { - RT_MUTEX *mutex = (RT_MUTEX *)data; + RT_MUTEX *mutex = (RT_MUTEX *)f->private; #ifdef CONFIG_XENO_FASTSYNCH xnhandle_t lock_state; #endif /* CONFIG_XENO_FASTSYNCH */ xnthread_t *owner; - char *p = page; - int len; spl_t s; xnlock_get_irqsave(&nklock, s); @@ -77,42 +75,45 @@ static int __mutex_read_proc(char *page, xnthread_lookup(xnsynch_fast_mask_claimed(lock_state)); if (!owner && lock_state != XN_NO_HANDLE) - p += sprintf(p, "="); + seq_printf(f, "="); else #endif /* CONFIG_XENO_FASTSYNCH */ if (owner) { /* Locked mutex -- dump owner and waiters, if any. */ xnpholder_t *holder; - p += sprintf(p, "=locked by %s\n", xnthread_name(owner)); + seq_printf(f, "=locked by %s\n", xnthread_name(owner)); holder = getheadpq(xnsynch_wait_queue(&mutex->synch_base)); while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); + seq_printf(f, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&mutex->synch_base), holder); } } else /* Mutex unlocked. */ - p += sprintf(p, "=unlocked\n"); + seq_printf(f, "=unlocked\n"); xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int mutex_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, mutex_seq_show, PDE(inode)->data); } +static struct file_operations mutex_proc_fops = { +.owner = THIS_MODULE, +.open = mutex_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __mutex_pnode = { @@ -120,8 +121,9 @@ static xnpnode_t __mutex_pnode = { .dir = NULL, .type = "mutexes", .entries = 0, - .read_proc = &__mutex_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &mutex_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 17/23] native: convert the proc entry for the semaphore registry to seq_file
From: Wolfgang Mauerer Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/skins/native/sem.c | 38 -- 1 files changed, 20 insertions(+), 18 deletions(-) diff --git a/ksrc/skins/native/sem.c b/ksrc/skins/native/sem.c index 0afea09..f962966 100644 --- a/ksrc/skins/native/sem.c +++ b/ksrc/skins/native/sem.c @@ -50,20 +50,18 @@ #ifdef CONFIG_PROC_FS -static int __sem_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +#include + +static int sem_seq_show(struct seq_file *f, void *v) { - RT_SEM *sem = (RT_SEM *)data; - char *p = page; - int len; + RT_SEM *sem = (RT_SEM *)f->private; spl_t s; xnlock_get_irqsave(&nklock, s); if (xnsynch_nsleepers(&sem->synch_base) == 0) /* Idle/posted semaphore -- dump count. */ - p += sprintf(p, "=%lu\n", sem->count); + seq_printf(f, "=%lu\n", sem->count); else { xnpholder_t *holder; @@ -73,7 +71,7 @@ static int __sem_read_proc(char *page, while (holder) { xnthread_t *sleeper = link2thread(holder, plink); - p += sprintf(p, "+%s\n", xnthread_name(sleeper)); + seq_printf(f, "+%s\n", xnthread_name(sleeper)); holder = nextpq(xnsynch_wait_queue(&sem->synch_base), holder); @@ -82,18 +80,21 @@ static int __sem_read_proc(char *page, xnlock_put_irqrestore(&nklock, s); - len = (p - page) - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + return 0; +} - return len; +static int sem_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, sem_seq_show, PDE(inode)->data); } +static struct file_operations sem_proc_fops = { +.owner = THIS_MODULE, +.open = sem_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + extern xnptree_t __native_ptree; static xnpnode_t __sem_pnode = { @@ -101,8 +102,9 @@ static xnpnode_t __sem_pnode = { .dir = NULL, .type = "semaphores", .entries = 0, - .read_proc = &__sem_read_proc, + .read_proc = NULL, .write_proc = NULL, + .fops = &sem_proc_fops, .root = &__native_ptree, }; -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
[Xenomai-core] [PATCH 23/23] nucleus: Convert timebases proc entry to seq_file
From: Wolfgang Mauerer Admittedly, the proc page cannot overflow right now, but since the number of time bases is at least in theory unlimited, let's convert the file while we are at it. Also properly take the nklock when accessing the nktimebase list. Signed-off-by: Wolfgang Mauerer Signed-off-by: Jan Kiszka --- ksrc/nucleus/timebase.c | 64 +-- 1 files changed, 34 insertions(+), 30 deletions(-) diff --git a/ksrc/nucleus/timebase.c b/ksrc/nucleus/timebase.c index 48be711..c3717e9 100644 --- a/ksrc/nucleus/timebase.c +++ b/ksrc/nucleus/timebase.c @@ -810,57 +810,61 @@ void xntbase_remove_proc(xntbase_t *base) #endif /* CONFIG_XENO_OPT_STATS */ -static int timebase_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) +static int timebase_seq_show(struct seq_file *f, void *v) { xnholder_t *holder; xntbase_t *tbase; - char *p = page; - int len = 0; + spl_t s; + + seq_printf(f, "%-10s %10s %10s %s\n", + "NAME", "RESOLUTION", "JIFFIES", "STATUS"); - p += sprintf(p, "%-10s %10s %10s %s\n", -"NAME", "RESOLUTION", "JIFFIES", "STATUS"); + xnlock_get_irqsave(&nklock, s); for (holder = getheadq(&nktimebaseq); holder != NULL; holder = nextq(&nktimebaseq, holder)) { tbase = link2tbase(holder); if (xntbase_periodic_p(tbase)) - p += sprintf(p, "%-10s %10lu %10Lu %s%s%s\n", -tbase->name, -tbase->tickvalue, -tbase->jiffies, -xntbase_enabled_p(tbase) ? "enabled" : "disabled", -xntbase_timeset_p(tbase) ? ",set" : ",unset", -xntbase_isolated_p(tbase) ? ",isolated" : ""); + seq_printf(f, "%-10s %10lu %10Lu %s%s%s\n", + tbase->name, + tbase->tickvalue, + tbase->jiffies, + xntbase_enabled_p(tbase) ? "enabled" : "disabled", + xntbase_timeset_p(tbase) ? ",set" : ",unset", + xntbase_isolated_p(tbase) ? ",isolated" : ""); else - p += sprintf(p, "%-10s %10s %10s %s\n", -tbase->name, -"1", -"n/a", -"enabled,set"); + seq_printf(f, "%-10s %10s %10s %s\n", + tbase->name, + "1", + "n/a", + "enabled,set"); } - len = p - page - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; + xnlock_put_irqrestore(&nklock, s); + + return 0; +} - return len; +static int timebase_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, timebase_seq_show, NULL); } +static struct file_operations timebase_proc_fops = { +.owner = THIS_MODULE, +.open = timebase_seq_open, +.read = seq_read, +.llseek = seq_lseek, +}; + void xntbase_init_proc(void) { #ifdef CONFIG_XENO_OPT_STATS tmstat_proc_root = create_proc_entry("timerstat", S_IFDIR, rthal_proc_root); #endif /* CONFIG_XENO_OPT_STATS */ - rthal_add_proc_leaf("timebases", &timebase_read_proc, NULL, NULL, - rthal_proc_root); + rthal_add_proc_seq("timebases", &timebase_proc_fops, 0, + rthal_proc_root); } void xntbase_cleanup_proc(void) -- 1.6.0.2 ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 17/24] rttest: Resolved test device conflicts via separate name spaces
Jan Kiszka wrote: > From: Jan Kiszka > > Usually, all devices of some RTDM class use the same naming scheme. But > as test devices are different as they do not provide compatible APIs, > let's give them separate name space for their device names. That finally > resolves all the detection troubles that showed up once more than one > test device was registered. > > To allow addressing old drivers with new user space and vice versa, a > config switch is added to the former to select the naming scheme, and > the latter will try to open under both names. > > Signed-off-by: Jan Kiszka Could we please have the devices named after the same name as the driver? So switchtst -> switchtest tmbench->timerbench -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 23/24] RTDM: Early fd release with poll-free context reference tracking
Jan Kiszka wrote: > From: Jan Kiszka > > Two changes in one as they are tightly related: Once close is called, > remove the file descriptor from open table, allowing its reuse while > close for the previous user proceeds. > > The second and major part of the patch avoids time-based polling while > waiting for context references to be dropped. This specifically helps in > scenarios where references can be held for a longer time beyond the > first close. A few set_bit and clear_bit with an xnlock locked. Could not these been replaced with __set_bit/__clear_bit in UP? -- Gilles. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 17/24] rttest: Resolved test device conflicts via separate name spaces
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: >> From: Jan Kiszka >> >> Usually, all devices of some RTDM class use the same naming scheme. But >> as test devices are different as they do not provide compatible APIs, >> let's give them separate name space for their device names. That finally >> resolves all the detection troubles that showed up once more than one >> test device was registered. >> >> To allow addressing old drivers with new user space and vice versa, a >> config switch is added to the former to select the naming scheme, and >> the latter will try to open under both names. >> >> Signed-off-by: Jan Kiszka > > Could we please have the devices named after the same name as the driver? > So switchtst -> switchtest > tmbench->timerbench We can (now that I know your preferences). Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 23/24] RTDM: Early fd release with poll-free context reference tracking
Gilles Chanteperdrix wrote: > Jan Kiszka wrote: >> From: Jan Kiszka >> >> Two changes in one as they are tightly related: Once close is called, >> remove the file descriptor from open table, allowing its reuse while >> close for the previous user proceeds. >> >> The second and major part of the patch avoids time-based polling while >> waiting for context references to be dropped. This specifically helps in >> scenarios where references can be held for a longer time beyond the >> first close. > > A few set_bit and clear_bit with an xnlock locked. Could not these been > replaced with __set_bit/__clear_bit in UP? > used_fildes: yes context_flags: no (drivers may manipulated them as well) Will add a corresponding patch to the next round. Jan signature.asc Description: OpenPGP digital signature ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core
Re: [Xenomai-core] [PATCH v3 02/24] RTDM: Add rtdm_rt_capable() service
On Sun, 2010-04-18 at 15:40 +0200, Jan Kiszka wrote: > Philippe Gerum wrote: > > On Sun, 2010-04-18 at 15:26 +0200, Philippe Gerum wrote: > >> On Sun, 2010-04-18 at 15:12 +0200, Jan Kiszka wrote: > >>> From: Jan Kiszka > >>> > >>> This adds rtdm_rt_capable(), a function that can be used by drivers to > >>> detect callers that could issue a service request also from the > >>> (typically preferred) real-time context. If that is the case, the driver > >>> can trigger a restart of the request if the current context is not > >>> real-time. > >>> > >>> CC: Philippe Gerum > >>> CC: Alexis Berlemont > >>> Signed-off-by: Jan Kiszka > >>> --- > >>> include/rtdm/rtdm_driver.h |6 ++ > >>> ksrc/skins/rtdm/drvlib.c | 25 + > >>> 2 files changed, 31 insertions(+), 0 deletions(-) > >>> > >>> diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h > >>> index 0fc1496..45be404 100644 > >>> --- a/include/rtdm/rtdm_driver.h > >>> +++ b/include/rtdm/rtdm_driver.h > >>> @@ -1296,6 +1296,12 @@ static inline int rtdm_in_rt_context(void) > >>> { > >>> return (rthal_current_domain != rthal_root_domain); > >>> } > >>> + > >>> +static inline int rtdm_rt_capable(void) > >>> +{ > >>> + return xnpod_shadow_p(); > >>> +} > >>> + > >> This won't do what your comment states; xnpod_shadow_p() would always > >> return false on behalf of a relaxed shadow, since it tests the status > >> bits of the current Xenomai thread, which has to be the root one in that > >> case. xnpod_shadow_p is to be used in primary context only, to > >> distinguish between kernel-based and userland Xenomai callers. > >> > >> What you want is probably something like: > >> > >> static inline int rtdm_rt_capable(void) > >> { > >>return xnshadow_thread(current) != NULL; > >> } > > > > Btw, the predicate as you defined it would not work over kernel-based > > Xenomai threads. rtdm_rt_capable() is ambiguous here. > > (!xnpod_root_p() || xnshadow_thread(current) != NULL) ? > > That would also avoid dereferencing current in a potentially unsafe > context (if we still have such problematic archs). Depending on how precise you want that predicate to be, (!xnpod_asynch_p() && (!xnpod_root_p() || xnshadow_thread(current) != NULL)) may be better, in a sense that it also excludes IRQ handlers and nucleus callouts. > > Jan > -- Philippe. ___ Xenomai-core mailing list Xenomai-core@gna.org https://mail.gna.org/listinfo/xenomai-core