[PATCH] cobalt/posix/process: pipeline: abstract kernel event handlers

Jan Kiszka jan.kiszka at siemens.com
Fri Jan 8 08:08:59 CET 2021


On 07.01.21 19:27, Jan Kiszka via Xenomai wrote:
> On 07.01.21 18:56, Jan Kiszka via Xenomai wrote:
>> On 17.12.20 19:02, Philippe Gerum wrote:
>>> From: Philippe Gerum <rpm at xenomai.org>
>>>
>>> Although there are significant commonalities between the I-pipe and
>>> Dovetail when it comes to dealing with synchronous kernel events,
>>> there is no strict 1:1 mapping between the two kernel interfaces.
>>>
>>> As an initial step, move all the code handling the kernel events to
>>> the I-pipe section. We may exploit commonalities between the I-pipe
>>> and Dovetail in this area as we gradually merge support for the
>>> latter.
>>>
>>> No functional change is introduced.
>>>
>>> Signed-off-by: Philippe Gerum <rpm at xenomai.org>
>>> ---
>>>  .../cobalt/kernel/ipipe/pipeline/kevents.h    |  31 +
>>>  kernel/cobalt/ipipe/Makefile                  |   4 +-
>>>  kernel/cobalt/ipipe/kevents.c                 | 860 ++++++++++++++++++
>>>  kernel/cobalt/posix/process.c                 | 846 +----------------
>>>  kernel/cobalt/posix/process.h                 |   4 +
>>>  kernel/cobalt/posix/signal.c                  |   5 +
>>>  kernel/cobalt/posix/signal.h                  |   2 +
>>>  kernel/cobalt/thread.c                        |   4 +-
>>>  kernel/cobalt/trace/cobalt-core.h             |  12 +-
>>>  9 files changed, 930 insertions(+), 838 deletions(-)
>>>  create mode 100644 include/cobalt/kernel/ipipe/pipeline/kevents.h
>>>  create mode 100644 kernel/cobalt/ipipe/kevents.c
>>>
>>> diff --git a/include/cobalt/kernel/ipipe/pipeline/kevents.h b/include/cobalt/kernel/ipipe/pipeline/kevents.h
>>> new file mode 100644
>>> index 000000000..30425a96b
>>> --- /dev/null
>>> +++ b/include/cobalt/kernel/ipipe/pipeline/kevents.h
>>> @@ -0,0 +1,31 @@
>>> +/*
>>> + * SPDX-License-Identifier: GPL-2.0
>>> + *
>>> + * Copyright (C) 2019 Philippe Gerum  <rpm at xenomai.org>
>>> + */
>>> +
>>> +#ifndef _COBALT_KERNEL_IPIPE_KEVENTS_H
>>> +#define _COBALT_KERNEL_IPIPE_KEVENTS_H
>>> +
>>> +struct cobalt_process;
>>> +struct cobalt_thread;
>>> +
>>> +static inline
>>> +int pipeline_attach_process(struct cobalt_process *process)
>>> +{
>>> +	return 0;
>>> +}
>>> +
>>> +static inline
>>> +void pipeline_detach_process(struct cobalt_process *process)
>>> +{ }
>>> +
>>> +int pipeline_prepare_current(void);
>>> +
>>> +void pipeline_attach_current(struct xnthread *thread);
>>> +
>>> +int pipeline_trap_kevents(void);
>>> +
>>> +void pipeline_enable_kevents(void);
>>> +
>>> +#endif /* !_COBALT_KERNEL_IPIPE_KEVENTS_H */
>>> diff --git a/kernel/cobalt/ipipe/Makefile b/kernel/cobalt/ipipe/Makefile
>>> index 6021008fb..5170bb32b 100644
>>> --- a/kernel/cobalt/ipipe/Makefile
>>> +++ b/kernel/cobalt/ipipe/Makefile
>>> @@ -1,3 +1,5 @@
>>> +ccflags-y += -Ikernel
>>> +
>>>  obj-y +=	pipeline.o
>>>  
>>> -pipeline-y :=	init.o intr.o
>>> +pipeline-y :=	init.o intr.o kevents.o
>>> diff --git a/kernel/cobalt/ipipe/kevents.c b/kernel/cobalt/ipipe/kevents.c
>>> new file mode 100644
>>> index 000000000..ba584677c
>>> --- /dev/null
>>> +++ b/kernel/cobalt/ipipe/kevents.c
>>> @@ -0,0 +1,860 @@
>>> +/*
>>> + * SPDX-License-Identifier: GPL-2.0
>>> + *
>>> + * Copyright (C) 2001-2014 Philippe Gerum <rpm at xenomai.org>.
>>> + * Copyright (C) 2001-2014 The Xenomai project <http://www.xenomai.org>
>>> + * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperdrix at xenomai.org>
>>> + *
>>> + * SMP support Copyright (C) 2004 The HYADES project <http://www.hyades-itea.org>
>>> + * RTAI/fusion Copyright (C) 2004 The RTAI project <http://www.rtai.org>
>>> + */
>>> +
>>> +#include <linux/ipipe.h>
>>> +#include <linux/ipipe_tickdev.h>
>>> +#include <linux/ptrace.h>
>>> +#include <pipeline/kevents.h>
>>> +#include <cobalt/kernel/sched.h>
>>> +#include <cobalt/kernel/thread.h>
>>> +#include <cobalt/kernel/vdso.h>
>>> +#include <rtdm/driver.h>
>>> +#include <trace/events/cobalt-core.h>
>>> +#include "../posix/process.h"
>>> +#include "../posix/thread.h"
>>> +#include "../posix/memory.h"
>>> +
>>> +static void detach_current(void);
>>> +
>>> +static inline struct cobalt_process *
>>> +process_from_thread(struct xnthread *thread)
>>> +{
>>> +	return container_of(thread, struct cobalt_thread, threadbase)->process;
>>> +}
>>> +
>>> +#ifdef IPIPE_KEVT_PTRESUME
>>> +
>>> +static void stop_debugged_process(struct xnthread *thread)
>>> +{
>>> +	struct cobalt_process *process = process_from_thread(thread);
>>> +	struct cobalt_thread *cth;
>>> +
>>> +	if (process->debugged_threads > 0)
>>> +		return;
>>> +
>>> +	list_for_each_entry(cth, &process->thread_list, next) {
>>> +		if (&cth->threadbase == thread)
>>> +			continue;
>>> +
>>> +		xnthread_suspend(&cth->threadbase, XNDBGSTOP, XN_INFINITE,
>>> +				 XN_RELATIVE, NULL);
>>> +	}
>>> +}
>>> +
>>> +static void resume_debugged_process(struct cobalt_process *process)
>>> +{
>>> +	struct cobalt_thread *cth;
>>> +
>>> +	xnsched_lock();
>>> +
>>> +	list_for_each_entry(cth, &process->thread_list, next)
>>> +		if (xnthread_test_state(&cth->threadbase, XNDBGSTOP))
>>> +			xnthread_resume(&cth->threadbase, XNDBGSTOP);
>>> +
>>> +	xnsched_unlock();
>>> +}
>>> +
>>> +#else /* !IPIPE_KEVT_PTRESUME */
>>> +
>>> +static inline void stop_debugged_process(struct xnthread *thread)
>>> +{
>>> +}
>>> +
>>> +static inline void resume_debugged_process(struct cobalt_process *process)
>>> +{
>>> +}
>>> +
>>> +#endif /* !IPIPE_KEVT_PTRESUME */
>>> +
>>> +/* called with nklock held */
>>> +static void register_debugged_thread(struct xnthread *thread)
>>> +{
>>> +	struct cobalt_process *process = process_from_thread(thread);
>>> +
>>> +	xnthread_set_state(thread, XNSSTEP);
>>> +
>>> +	stop_debugged_process(thread);
>>> +	process->debugged_threads++;
>>> +
>>> +	if (xnthread_test_state(thread, XNRELAX))
>>> +		xnthread_suspend(thread, XNDBGSTOP, XN_INFINITE, XN_RELATIVE,
>>> +				 NULL);
>>> +}
>>> +
>>> +/* called with nklock held */
>>> +static void unregister_debugged_thread(struct xnthread *thread)
>>> +{
>>> +	struct cobalt_process *process = process_from_thread(thread);
>>> +
>>> +	process->debugged_threads--;
>>> +	xnthread_clear_state(thread, XNSSTEP);
>>> +
>>> +	if (process->debugged_threads == 0)
>>> +		resume_debugged_process(process);
>>> +}
>>> +
>>> +static inline int handle_exception(struct ipipe_trap_data *d)
>>> +{
>>> +	struct xnthread *thread;
>>> +	struct xnsched *sched;
>>> +
>>> +	sched = xnsched_current();
>>> +	thread = sched->curr;
>>> +
>>> +	trace_cobalt_thread_fault(xnarch_fault_pc(d),
>>> +				  xnarch_fault_trap(d));
>>> +
>>> +	if (xnthread_test_state(thread, XNROOT))
>>> +		return 0;
>>> +
>>> +#ifdef IPIPE_KEVT_USERINTRET
>>> +	if (xnarch_fault_bp_p(d) && user_mode(d->regs)) {
>>> +		spl_t s;
>>> +
>>> +		XENO_WARN_ON(CORE, xnthread_test_state(thread, XNRELAX));
>>> +		xnlock_get_irqsave(&nklock, s);
>>> +		xnthread_set_info(thread, XNCONTHI);
>>> +		ipipe_enable_user_intret_notifier();
>>> +		stop_debugged_process(thread);
>>> +		xnlock_put_irqrestore(&nklock, s);
>>> +		xnsched_run();
>>> +	}
>>> +#endif
>>> +
>>> +	if (xnarch_fault_fpu_p(d)) {
>>> +#ifdef CONFIG_XENO_ARCH_FPU
>>> +		spl_t s;
>>> +
>>> +		/* FPU exception received in primary mode. */
>>> +		splhigh(s);
>>> +		if (xnarch_handle_fpu_fault(sched->fpuholder, thread, d)) {
>>> +			sched->fpuholder = thread;
>>> +			splexit(s);
>>> +			return 1;
>>> +		}
>>> +		splexit(s);
>>> +#endif /* CONFIG_XENO_ARCH_FPU */
>>> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
> 
> Inverted logic? Build is broken for 4.14 and older.
> 

Nope, the problem was missing include moving. Fixed that up as well,
result is in next.

Jan

> Jan
> 
>>> +		printk("invalid use of FPU in Xenomai context at %pS\n",
>>> +		       (void *)xnarch_fault_pc(d));
>>> +#else
>>> +		print_symbol("invalid use of FPU in Xenomai context at %s\n",
>>> +			     xnarch_fault_pc(d));
>>> +#endif

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux



More information about the Xenomai mailing list