All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] Dovetail integration, moving forward
@ 2021-06-04 10:05 Jan Kiszka
  2021-06-04 10:05 ` [PATCH 01/12] cobalt/kevents: dovetail: provide thread info initializer Jan Kiszka
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

This pulls the first half of the last half, up to the RT-NRT signaling
patches that need more work (Hongzhan is on that).

Jan


CC: Hongzhan Chen <hongzhan.chen@intel.com>
CC: Philippe Gerum <rpm@xenomai.org>

Hongzhan Chen (1):
  cobalt/sched: dovetail: fix missed switching to OOB opportunities

Jan Kiszka (1):
  cobalt/trace: Avoid clash with kernel trace definitions

Philippe Gerum (10):
  cobalt/kevents: dovetail: provide thread info initializer
  cobalt/thread: pipeline: refactor thread control block
  cobalt/build: pipeline: enable Dovetail support if detected
  cobalt/trace: dovetail: enable basic tracepoints
  cobalt/trace: add tracing call to notify of a latency peak
  cobalt/kevents: dovetail: unregister thread resuming from ptrace stop
  cobalt/clock: dovetail: use refined monotonic source
  cobalt/clock: pipeline: abstract handling of CLOCK_REALTIME
  rtdm/fd: move inband work description off the stack
  drivers/udd: move inband work description off the stack

 include/cobalt/kernel/clock.h                 | 12 ++-
 .../cobalt/kernel/dovetail/pipeline/clock.h   | 21 +++-
 .../cobalt/kernel/dovetail/pipeline/trace.h   | 56 +++++------
 include/cobalt/kernel/ipipe/pipeline/clock.h  |  5 +
 include/cobalt/kernel/ipipe/pipeline/trace.h  |  5 +
 include/cobalt/kernel/thread.h                |  6 +-
 include/cobalt/trace.h                        |  2 +
 include/cobalt/uapi/kernel/trace.h            |  1 +
 include/mercury/boilerplate/trace.h           |  4 +
 .../arm/ipipe/include/asm/xenomai/thread.h    |  8 +-
 .../arm64/ipipe/include/asm/xenomai/thread.h  |  8 +-
 .../ipipe/include/asm/xenomai/thread.h        |  8 +-
 .../x86/dovetail/include/asm/xenomai/thread.h |  8 +-
 .../x86/ipipe/include/asm/xenomai/thread.h    |  8 +-
 kernel/cobalt/clock.c                         | 66 +++++++------
 kernel/cobalt/dovetail/kevents.c              | 41 ++++++--
 kernel/cobalt/dovetail/sched.c                | 17 +++-
 .../asm-generic/xenomai/dovetail/thread.h     | 24 +++++
 .../asm-generic/xenomai/{ => ipipe}/thread.h  |  9 +-
 kernel/cobalt/ipipe/clock.c                   | 15 +++
 kernel/cobalt/ipipe/tick.c                    |  3 -
 kernel/cobalt/posix/clock.c                   |  9 +-
 kernel/cobalt/posix/syscall.c                 |  6 ++
 kernel/cobalt/rtdm/fd.c                       | 22 ++---
 kernel/cobalt/trace/cobalt-core.h             | 98 +++++++++++++++++++
 kernel/cobalt/trace/cobalt-posix.h            | 12 +--
 kernel/drivers/testing/timerbench.c           |  2 +-
 kernel/drivers/udd/udd.c                      | 25 +++--
 lib/cobalt/trace.c                            |  5 +
 scripts/Kconfig.frag                          |  1 +
 testsuite/latency/latency.c                   |  2 +-
 31 files changed, 375 insertions(+), 134 deletions(-)
 create mode 100644 kernel/cobalt/include/asm-generic/xenomai/dovetail/thread.h
 rename kernel/cobalt/include/asm-generic/xenomai/{ => ipipe}/thread.h (87%)

-- 
2.26.2



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 01/12] cobalt/kevents: dovetail: provide thread info initializer
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 02/12] cobalt/thread: pipeline: refactor thread control block Jan Kiszka
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Dovetail invokes arch_inband_task_init() for each emerging thread in
the system, so that we may initialize our extended state with default
settings. Make sure to intercept this hook in order to start from a
fresh and clean state.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/kevents.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
index a402d5569..df5408ccc 100644
--- a/kernel/cobalt/dovetail/kevents.c
+++ b/kernel/cobalt/dovetail/kevents.c
@@ -86,6 +86,14 @@ static void unregister_debugged_thread(struct xnthread *thread)
 		resume_debugged_process(process);
 }
 
+void arch_inband_task_init(struct task_struct *tsk)
+{
+	struct cobalt_threadinfo *p = dovetail_task_state(tsk);
+
+	p->thread = NULL;
+	p->process = NULL;
+}
+
 void handle_oob_trap_entry(unsigned int trapnr, struct pt_regs *regs)
 {
 	struct xnthread *thread;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 02/12] cobalt/thread: pipeline: refactor thread control block
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
  2021-06-04 10:05 ` [PATCH 01/12] cobalt/kevents: dovetail: provide thread info initializer Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 03/12] cobalt/build: pipeline: enable Dovetail support if detected Jan Kiszka
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

With Dovetail in, a thread control block is fully generic, merely
composed of an alternate scheduling control descriptor. Refactor the
definitions of the per-architecture control blocks accordingly.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/thread.h                |  6 ++---
 .../arm/ipipe/include/asm/xenomai/thread.h    |  8 ++++++-
 .../arm64/ipipe/include/asm/xenomai/thread.h  |  8 ++++++-
 .../ipipe/include/asm/xenomai/thread.h        |  8 ++++++-
 .../x86/dovetail/include/asm/xenomai/thread.h |  8 +------
 .../x86/ipipe/include/asm/xenomai/thread.h    |  8 ++++++-
 .../asm-generic/xenomai/dovetail/thread.h     | 24 +++++++++++++++++++
 .../asm-generic/xenomai/{ => ipipe}/thread.h  |  9 +++----
 8 files changed, 59 insertions(+), 20 deletions(-)
 create mode 100644 kernel/cobalt/include/asm-generic/xenomai/dovetail/thread.h
 rename kernel/cobalt/include/asm-generic/xenomai/{ => ipipe}/thread.h (87%)

diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index fe7390088..c92037bfe 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -268,7 +268,7 @@ static inline int xnthread_current_priority(const struct xnthread *thread)
 
 static inline struct task_struct *xnthread_host_task(struct xnthread *thread)
 {
-	return xnthread_archtcb(thread)->core.host_task;
+	return xnarch_host_task(xnthread_archtcb(thread));
 }
 
 #define xnthread_for_each_booster(__pos, __thread)		\
@@ -283,7 +283,7 @@ static inline struct task_struct *xnthread_host_task(struct xnthread *thread)
 		if ((__p__)->ops.__h)					\
 			(__p__)->ops.__h(__t, ##__a);			\
 	} while (0)
-	
+
 #define xnthread_run_handler_stack(__t, __h, __a...)			\
 	do {								\
 		struct xnthread_personality *__p__ = (__t)->personality;	\
@@ -293,7 +293,7 @@ static inline struct task_struct *xnthread_host_task(struct xnthread *thread)
 			__p__ = (__p__)->ops.__h(__t, ##__a);		\
 		} while (__p__);					\
 	} while (0)
-	
+
 static inline
 struct xnthread_wait_context *xnthread_get_wait_context(struct xnthread *thread)
 {
diff --git a/kernel/cobalt/arch/arm/ipipe/include/asm/xenomai/thread.h b/kernel/cobalt/arch/arm/ipipe/include/asm/xenomai/thread.h
index c51b51a93..93346fd2e 100644
--- a/kernel/cobalt/arch/arm/ipipe/include/asm/xenomai/thread.h
+++ b/kernel/cobalt/arch/arm/ipipe/include/asm/xenomai/thread.h
@@ -19,7 +19,7 @@
 #ifndef _COBALT_ARM_ASM_THREAD_H
 #define _COBALT_ARM_ASM_THREAD_H
 
-#include <asm-generic/xenomai/thread.h>
+#include <asm-generic/xenomai/ipipe/thread.h>
 
 #ifdef CONFIG_XENO_ARCH_FPU
 #ifdef CONFIG_VFP
@@ -51,6 +51,12 @@ struct xnarchtcb {
 
 #define xnarch_fault_notify(d) (!xnarch_fault_bp_p(d))
 
+static inline
+struct task_struct *xnarch_host_task(struct xnarchtcb *tcb)
+{
+	return tcb->core.host_task;
+}
+
 void xnarch_switch_to(struct xnthread *out, struct xnthread *in);
 
 static inline void xnarch_enter_root(struct xnthread *root) { }
diff --git a/kernel/cobalt/arch/arm64/ipipe/include/asm/xenomai/thread.h b/kernel/cobalt/arch/arm64/ipipe/include/asm/xenomai/thread.h
index c81c01321..7899a49e6 100644
--- a/kernel/cobalt/arch/arm64/ipipe/include/asm/xenomai/thread.h
+++ b/kernel/cobalt/arch/arm64/ipipe/include/asm/xenomai/thread.h
@@ -20,7 +20,7 @@
 #define _COBALT_ARM64_ASM_THREAD_H
 
 #include <linux/version.h>
-#include <asm-generic/xenomai/thread.h>
+#include <asm-generic/xenomai/ipipe/thread.h>
 
 #if defined(CONFIG_XENO_ARCH_FPU) && LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)
 #define ARM64_XENO_OLD_SWITCH
@@ -47,6 +47,12 @@ struct xnarchtcb {
 
 #define xnarch_fault_notify(d) (!xnarch_fault_bp_p(d))
 
+static inline
+struct task_struct *xnarch_host_task(struct xnarchtcb *tcb)
+{
+	return tcb->core.host_task;
+}
+
 void xnarch_switch_to(struct xnthread *out, struct xnthread *in);
 
 static inline void xnarch_enter_root(struct xnthread *root) { }
diff --git a/kernel/cobalt/arch/powerpc/ipipe/include/asm/xenomai/thread.h b/kernel/cobalt/arch/powerpc/ipipe/include/asm/xenomai/thread.h
index 97129f739..f91e26b36 100644
--- a/kernel/cobalt/arch/powerpc/ipipe/include/asm/xenomai/thread.h
+++ b/kernel/cobalt/arch/powerpc/ipipe/include/asm/xenomai/thread.h
@@ -19,7 +19,7 @@
 #ifndef _COBALT_POWERPC_ASM_THREAD_H
 #define _COBALT_POWERPC_ASM_THREAD_H
 
-#include <asm-generic/xenomai/thread.h>
+#include <asm-generic/xenomai/ipipe/thread.h>
 
 struct xnarchtcb {
 	struct xntcb core;
@@ -44,6 +44,12 @@ struct xnarchtcb {
 				 (d)->exception == IPIPE_TRAP_DEBUG))
 #define xnarch_fault_notify(d) (xnarch_fault_bp_p(d) == 0)
 
+static inline
+struct task_struct *xnarch_host_task(struct xnarchtcb *tcb)
+{
+	return tcb->core.host_task;
+}
+
 static inline void xnarch_enter_root(struct xnthread *root) { }
 
 #ifdef CONFIG_XENO_ARCH_FPU
diff --git a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
index 73ecd945c..6eb71e2a8 100644
--- a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
+++ b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
@@ -20,15 +20,9 @@
 #ifndef _COBALT_X86_ASM_THREAD_H
 #define _COBALT_X86_ASM_THREAD_H
 
-#include <linux/dovetail.h>
-#include <asm-generic/xenomai/thread.h>
+#include <asm-generic/xenomai/dovetail/thread.h>
 #include <asm/traps.h>
 
-struct xnarchtcb {
-	struct xntcb core;
-	struct dovetail_altsched_context altsched;
-};
-
 #define xnarch_fault_pc(__regs)		((__regs)->ip)
 #define xnarch_fault_pf_p(__nr)		((__nr) == X86_TRAP_PF)
 #define xnarch_fault_bp_p(__nr)		((current->ptrace & PT_PTRACED) &&	\
diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/thread.h b/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/thread.h
index 10cd6ecd5..a1a79bbc0 100644
--- a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/thread.h
+++ b/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/thread.h
@@ -20,7 +20,7 @@
 #ifndef _COBALT_X86_ASM_THREAD_H
 #define _COBALT_X86_ASM_THREAD_H
 
-#include <asm-generic/xenomai/thread.h>
+#include <asm-generic/xenomai/ipipe/thread.h>
 #include <asm/xenomai/wrappers.h>
 #include <asm/traps.h>
 
@@ -64,6 +64,12 @@ struct xnarchtcb {
 				 ((d)->exception == X86_TRAP_DB || (d)->exception == X86_TRAP_BP))
 #define xnarch_fault_notify(d)	(!xnarch_fault_bp_p(d))
 
+static inline
+struct task_struct *xnarch_host_task(struct xnarchtcb *tcb)
+{
+	return tcb->core.host_task;
+}
+
 void xnarch_switch_fpu(struct xnthread *from, struct xnthread *to);
 
 int xnarch_handle_fpu_fault(struct xnthread *from, 
diff --git a/kernel/cobalt/include/asm-generic/xenomai/dovetail/thread.h b/kernel/cobalt/include/asm-generic/xenomai/dovetail/thread.h
new file mode 100644
index 000000000..8939e45f3
--- /dev/null
+++ b/kernel/cobalt/include/asm-generic/xenomai/dovetail/thread.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * 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.
+ */
+#ifndef _COBALT_ASM_GENERIC_DOVETAIL_THREAD_H
+#define _COBALT_ASM_GENERIC_DOVETAIL_THREAD_H
+
+#include <linux/dovetail.h>
+
+struct xnarchtcb {
+	struct dovetail_altsched_context altsched;
+};
+
+static inline
+struct task_struct *xnarch_host_task(struct xnarchtcb *tcb)
+{
+	return tcb->altsched.task;
+}
+
+#endif /* !_COBALT_ASM_GENERIC_DOVETAIL_THREAD_H */
diff --git a/kernel/cobalt/include/asm-generic/xenomai/thread.h b/kernel/cobalt/include/asm-generic/xenomai/ipipe/thread.h
similarity index 87%
rename from kernel/cobalt/include/asm-generic/xenomai/thread.h
rename to kernel/cobalt/include/asm-generic/xenomai/ipipe/thread.h
index cd0c6e913..fcd7275d9 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/thread.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/ipipe/thread.h
@@ -16,17 +16,14 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  * 02111-1307, USA.
  */
-#ifndef _COBALT_ASM_GENERIC_THREAD_H
-#define _COBALT_ASM_GENERIC_THREAD_H
+#ifndef _COBALT_ASM_GENERIC_IPIPE_THREAD_H
+#define _COBALT_ASM_GENERIC_IPIPE_THREAD_H
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 
 struct task_struct;
 
-struct xnthread;
-struct xnarchtcb;
-
 struct xntcb {
 	struct task_struct *host_task;
 	struct thread_struct *tsp;
@@ -39,4 +36,4 @@ struct xntcb {
 #endif
 };
 
-#endif /* !_COBALT_ASM_GENERIC_THREAD_H */
+#endif /* !_COBALT_ASM_GENERIC_IPIPE_THREAD_H */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 03/12] cobalt/build: pipeline: enable Dovetail support if detected
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
  2021-06-04 10:05 ` [PATCH 01/12] cobalt/kevents: dovetail: provide thread info initializer Jan Kiszka
  2021-06-04 10:05 ` [PATCH 02/12] cobalt/thread: pipeline: refactor thread control block Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 04/12] cobalt/trace: Avoid clash with kernel trace definitions Jan Kiszka
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 scripts/Kconfig.frag | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/Kconfig.frag b/scripts/Kconfig.frag
index 319683369..dd91dc6c9 100644
--- a/scripts/Kconfig.frag
+++ b/scripts/Kconfig.frag
@@ -3,6 +3,7 @@ menuconfig XENOMAI
 	bool "Xenomai/cobalt"
 	select IPIPE if HAVE_IPIPE_SUPPORT
 	select IPIPE_WANT_APIREV_2 if IPIPE
+	select DOVETAIL if HAVE_DOVETAIL
 	default y
 	help
 	  Xenomai's Cobalt core is a real-time extension to the Linux
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 04/12] cobalt/trace: Avoid clash with kernel trace definitions
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (2 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 03/12] cobalt/build: pipeline: enable Dovetail support if detected Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 05/12] cobalt/trace: dovetail: enable basic tracepoints Jan Kiszka
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Started to bite us on newer kernels / with dovetail.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/trace/cobalt-posix.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/cobalt/trace/cobalt-posix.h b/kernel/cobalt/trace/cobalt-posix.h
index a3713e9c9..1d623069d 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -156,7 +156,7 @@
 		__cobalt_symbolic_syscall(sendmmsg),			\
 		__cobalt_symbolic_syscall(clock_adjtime))
 
-DECLARE_EVENT_CLASS(syscall_entry,
+DECLARE_EVENT_CLASS(cobalt_syscall_entry,
 	TP_PROTO(unsigned int nr),
 	TP_ARGS(nr),
 
@@ -171,7 +171,7 @@ DECLARE_EVENT_CLASS(syscall_entry,
 	TP_printk("syscall=%s", __cobalt_syscall_name(__entry->nr))
 );
 
-DECLARE_EVENT_CLASS(syscall_exit,
+DECLARE_EVENT_CLASS(cobalt_syscall_exit,
 	TP_PROTO(long result),
 	TP_ARGS(result),
 
@@ -266,22 +266,22 @@ DECLARE_EVENT_CLASS(cobalt_void,
 	TP_printk("%s", "")
 );
 
-DEFINE_EVENT(syscall_entry, cobalt_head_sysentry,
+DEFINE_EVENT(cobalt_syscall_entry, cobalt_head_sysentry,
 	TP_PROTO(unsigned int nr),
 	TP_ARGS(nr)
 );
 
-DEFINE_EVENT(syscall_exit, cobalt_head_sysexit,
+DEFINE_EVENT(cobalt_syscall_exit, cobalt_head_sysexit,
 	TP_PROTO(long result),
 	TP_ARGS(result)
 );
 
-DEFINE_EVENT(syscall_entry, cobalt_root_sysentry,
+DEFINE_EVENT(cobalt_syscall_entry, cobalt_root_sysentry,
 	TP_PROTO(unsigned int nr),
 	TP_ARGS(nr)
 );
 
-DEFINE_EVENT(syscall_exit, cobalt_root_sysexit,
+DEFINE_EVENT(cobalt_syscall_exit, cobalt_root_sysexit,
 	TP_PROTO(long result),
 	TP_ARGS(result)
 );
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 05/12] cobalt/trace: dovetail: enable basic tracepoints
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (3 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 04/12] cobalt/trace: Avoid clash with kernel trace definitions Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 06/12] cobalt/trace: add tracing call to notify of a latency peak Jan Kiszka
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
[Jan: add missing struct xnsched_quota_group declaration, style fixes]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../cobalt/kernel/dovetail/pipeline/trace.h   | 52 ++++--------
 kernel/cobalt/trace/cobalt-core.h             | 84 +++++++++++++++++++
 2 files changed, 102 insertions(+), 34 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/trace.h b/include/cobalt/kernel/dovetail/pipeline/trace.h
index 819b8a713..e39fdfa7c 100644
--- a/include/cobalt/kernel/dovetail/pipeline/trace.h
+++ b/include/cobalt/kernel/dovetail/pipeline/trace.h
@@ -22,96 +22,80 @@
 #include <linux/types.h>
 #include <linux/kconfig.h>
 #include <cobalt/uapi/kernel/trace.h>
+#include <trace/events/cobalt-core.h>
+#include <cobalt/kernel/assert.h>
 
 static inline int xntrace_max_begin(unsigned long v)
 {
-//#chz: NTD
-	//ipipe_trace_begin(v);
+	TODO();
 	return 0;
 }
 
 static inline int xntrace_max_end(unsigned long v)
 {
-//#chz: NTD
-	//ipipe_trace_end(v);
+	TODO();
 	return 0;
 }
 
 static inline int xntrace_max_reset(void)
 {
-//#chz: NTD
-	//ipipe_trace_max_reset();
+	TODO();
 	return 0;
 }
 
 static inline int xntrace_user_start(void)
 {
-//#chz: NTD
-	//return ipipe_trace_frozen_reset();
+	TODO();
 	return 0;
 }
 
 static inline int xntrace_user_stop(unsigned long v)
 {
-//#chz: NTD
-	//ipipe_trace_freeze(v);
+	TODO();
 	return 0;
 }
 
 static inline int xntrace_user_freeze(unsigned long v, int once)
 {
-	int ret = 0;
-//#chz: NTD
-/*
-	if (!once)
-		ret = ipipe_trace_frozen_reset();
-
-	ipipe_trace_freeze(v);
-*/
-	return ret;
+	trace_cobalt_trace_longval(0, v);
+	trace_cobalt_trigger("freeze");
+	return 0;
 }
 
 static inline int xntrace_special(unsigned char id, unsigned long v)
 {
-//#chz: NTD
-//	ipipe_trace_special(id, v);
+	trace_cobalt_trace_longval(id, v);
 	return 0;
 }
 
 static inline int xntrace_special_u64(unsigned char id,
-					unsigned long long v)
+				unsigned long long v)
 {
-//#chz: NTD
-//	ipipe_trace_special(id, (unsigned long)(v >> 32));
-//	ipipe_trace_special(id, (unsigned long)(v & 0xFFFFFFFF));
+	trace_cobalt_trace_longval(id, v);
 	return 0;
 }
 
 static inline int xntrace_pid(pid_t pid, short prio)
 {
-//#chz: NTD
-//	ipipe_trace_pid(pid, prio);
+	trace_cobalt_trace_pid(pid, prio);
 	return 0;
 }
 
-static inline int xntrace_tick(unsigned long delay_ticks)
+static inline int xntrace_tick(unsigned long delay_ticks) /* ns */
 {
-//#chz: NTD
-//	ipipe_trace_event(0, delay_ticks);
+	trace_cobalt_tick_shot(delay_ticks);
 	return 0;
 }
 
 static inline int xntrace_panic_freeze(void)
 {
-//#chz: NTD
-//	ipipe_trace_panic_freeze();
+	TODO();
 	return 0;
 }
 
 static inline int xntrace_panic_dump(void)
 {
-//#chz: NTD
-//	ipipe_trace_panic_dump();
+	TODO();
 	return 0;
 }
 
diff --git a/kernel/cobalt/trace/cobalt-core.h b/kernel/cobalt/trace/cobalt-core.h
index 96eec3664..76240d245 100644
--- a/kernel/cobalt/trace/cobalt-core.h
+++ b/kernel/cobalt/trace/cobalt-core.h
@@ -24,6 +24,16 @@
 #define _TRACE_COBALT_CORE_H
 
 #include <linux/tracepoint.h>
+#include <linux/math64.h>
+#include <cobalt/kernel/timer.h>
+#include <cobalt/uapi/kernel/types.h>
+
+struct xnsched;
+struct xnthread;
+struct xnsynch;
+struct xnsched_class;
+struct xnsched_quota_group;
+struct xnthread_init_attr;
 
 DECLARE_EVENT_CLASS(thread_event,
 	TP_PROTO(struct xnthread *thread),
@@ -768,6 +778,80 @@ DEFINE_EVENT(synch_post_event, cobalt_synch_forget,
 	TP_ARGS(synch)
 );
 
+TRACE_EVENT(cobalt_tick_shot,
+	TP_PROTO(s64 delta),
+	TP_ARGS(delta),
+
+	TP_STRUCT__entry(
+		__field(u64, secs)
+		__field(u32, nsecs)
+		__field(s64, delta)
+	),
+
+	TP_fast_assign(
+		__entry->delta = delta;
+		__entry->secs = div_u64_rem(trace_clock_local() + delta,
+					    NSEC_PER_SEC, &__entry->nsecs);
+	),
+
+	TP_printk("next tick at %Lu.%06u (delay: %Ld us)",
+		  (unsigned long long)__entry->secs,
+		  __entry->nsecs / 1000, div_s64(__entry->delta, 1000))
+);
+
+TRACE_EVENT(cobalt_trace,
+	TP_PROTO(const char *msg),
+	TP_ARGS(msg),
+	TP_STRUCT__entry(
+		__string(msg, msg)
+	),
+	TP_fast_assign(
+		__assign_str(msg, msg);
+	),
+	TP_printk("%s", __get_str(msg))
+);
+
+TRACE_EVENT(cobalt_trace_longval,
+	TP_PROTO(int id, u64 val),
+	TP_ARGS(id, val),
+	TP_STRUCT__entry(
+		__field(int, id)
+		__field(u64, val)
+	),
+	TP_fast_assign(
+		__entry->id = id;
+		__entry->val = val;
+	),
+	TP_printk("id=%#x, v=%llu", __entry->id, __entry->val)
+);
+
+TRACE_EVENT(cobalt_trace_pid,
+	TP_PROTO(pid_t pid, int prio),
+	TP_ARGS(pid, prio),
+	TP_STRUCT__entry(
+		__field(pid_t, pid)
+		__field(int, prio)
+	),
+	TP_fast_assign(
+		__entry->pid = pid;
+		__entry->prio = prio;
+	),
+	TP_printk("pid=%d, prio=%d", __entry->pid, __entry->prio)
+);
+
+/* Basically cobalt_trace() + trigger point */
+TRACE_EVENT(cobalt_trigger,
+	TP_PROTO(const char *issuer),
+	TP_ARGS(issuer),
+	TP_STRUCT__entry(
+		__string(issuer, issuer)
+	),
+	TP_fast_assign(
+		__assign_str(issuer, issuer);
+	),
+	TP_printk("%s", __get_str(issuer))
+);
+
 #endif /* _TRACE_COBALT_CORE_H */
 
 /* This part must be outside protection */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 06/12] cobalt/trace: add tracing call to notify of a latency peak
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (4 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 05/12] cobalt/trace: dovetail: enable basic tracepoints Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 07/12] cobalt/kevents: dovetail: unregister thread resuming from ptrace stop Jan Kiszka
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

When running on top of Dovetail, we may want to perform a specific
sequence of actions upon notification of a latency peak by some
application. Let's create a dedicated trace call in the API to handle
this particular case, instead of relying on the generic "user_freeze"
event.

NOTE: the new trace call does not return any value, because there is
nothing valuable to receive from a trace call. If required,
xntrace_enabled() should be tested beforehand to figure out whether
the kernel tracer is enabled.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/trace.h |  8 +++++++-
 include/cobalt/kernel/ipipe/pipeline/trace.h    |  5 +++++
 include/cobalt/trace.h                          |  2 ++
 include/cobalt/uapi/kernel/trace.h              |  1 +
 include/mercury/boilerplate/trace.h             |  4 ++++
 kernel/cobalt/posix/syscall.c                   |  6 ++++++
 kernel/cobalt/trace/cobalt-core.h               | 14 ++++++++++++++
 kernel/drivers/testing/timerbench.c             |  2 +-
 lib/cobalt/trace.c                              |  5 +++++
 testsuite/latency/latency.c                     |  2 +-
 10 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/trace.h b/include/cobalt/kernel/dovetail/pipeline/trace.h
index e39fdfa7c..513d9b48b 100644
--- a/include/cobalt/kernel/dovetail/pipeline/trace.h
+++ b/include/cobalt/kernel/dovetail/pipeline/trace.h
@@ -58,10 +58,16 @@ static inline int xntrace_user_stop(unsigned long v)
 static inline int xntrace_user_freeze(unsigned long v, int once)
 {
 	trace_cobalt_trace_longval(0, v);
-	trace_cobalt_trigger("freeze");
+	trace_cobalt_trigger("user-freeze");
 	return 0;
 }
 
+static inline void xntrace_latpeak_freeze(int delay)
+{
+	trace_cobalt_latpeak(delay);
+	trace_cobalt_trigger("latency-freeze");
+}
+
 static inline int xntrace_special(unsigned char id, unsigned long v)
 {
 	trace_cobalt_trace_longval(id, v);
diff --git a/include/cobalt/kernel/ipipe/pipeline/trace.h b/include/cobalt/kernel/ipipe/pipeline/trace.h
index d92e57a63..a28b83a48 100644
--- a/include/cobalt/kernel/ipipe/pipeline/trace.h
+++ b/include/cobalt/kernel/ipipe/pipeline/trace.h
@@ -65,6 +65,11 @@ static inline int xntrace_user_freeze(unsigned long v, int once)
 	return ret;
 }
 
+static inline void xntrace_latpeak_freeze(int delay)
+{
+	xntrace_user_freeze(delay, 0);
+}
+
 static inline int xntrace_special(unsigned char id, unsigned long v)
 {
 	ipipe_trace_special(id, v);
diff --git a/include/cobalt/trace.h b/include/cobalt/trace.h
index 172c0dc38..b2f9d954f 100644
--- a/include/cobalt/trace.h
+++ b/include/cobalt/trace.h
@@ -40,6 +40,8 @@ int xntrace_special(unsigned char id, unsigned long v);
 
 int xntrace_special_u64(unsigned char id, unsigned long long v);
 
+void xntrace_latpeak_freeze(int delay);
+
 int xnftrace_vprintf(const char *format, va_list args);
 int xnftrace_printf(const char *format, ...);
 
diff --git a/include/cobalt/uapi/kernel/trace.h b/include/cobalt/uapi/kernel/trace.h
index 95fd07e76..a1add3013 100644
--- a/include/cobalt/uapi/kernel/trace.h
+++ b/include/cobalt/uapi/kernel/trace.h
@@ -26,5 +26,6 @@
 #define __xntrace_op_user_freeze	5
 #define __xntrace_op_special		6
 #define __xntrace_op_special_u64	7
+#define __xntrace_op_latpeak_freeze	8
 
 #endif /* !_COBALT_UAPI_KERNEL_TRACE_H */
diff --git a/include/mercury/boilerplate/trace.h b/include/mercury/boilerplate/trace.h
index 223e36429..787b088e3 100644
--- a/include/mercury/boilerplate/trace.h
+++ b/include/mercury/boilerplate/trace.h
@@ -50,6 +50,10 @@ static inline int xntrace_user_freeze(unsigned long v, int once)
 	return -ENOSYS;
 }
 
+static inline void xntrace_latpeak_freeze(int delay)
+{
+}
+
 static inline int xntrace_special(unsigned char id, unsigned long v)
 {
 	return -ENOSYS;
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index c6fe737e6..30c33dda6 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -177,6 +177,12 @@ static COBALT_SYSCALL(trace, current,
 		ret = xntrace_special_u64(a1 & 0xFF,
 					  (((u64) a2) << 32) | a3);
 		break;
+
+	case __xntrace_op_latpeak_freeze:
+		xntrace_latpeak_freeze(a1);
+		ret = 0;
+		break;
+
 	}
 	return ret;
 }
diff --git a/kernel/cobalt/trace/cobalt-core.h b/kernel/cobalt/trace/cobalt-core.h
index 76240d245..88ed5700d 100644
--- a/kernel/cobalt/trace/cobalt-core.h
+++ b/kernel/cobalt/trace/cobalt-core.h
@@ -839,6 +839,20 @@ TRACE_EVENT(cobalt_trace_pid,
 	TP_printk("pid=%d, prio=%d", __entry->pid, __entry->prio)
 );
 
+TRACE_EVENT(cobalt_latpeak,
+	TP_PROTO(int latmax_ns),
+	TP_ARGS(latmax_ns),
+	TP_STRUCT__entry(
+		 __field(int, latmax_ns)
+	),
+	TP_fast_assign(
+		__entry->latmax_ns = latmax_ns;
+	),
+	TP_printk("** latency peak: %d.%.3d us **",
+		  __entry->latmax_ns / 1000,
+		  __entry->latmax_ns % 1000)
+);
+
 /* Basically cobalt_trace() + trigger point */
 TRACE_EVENT(cobalt_trigger,
 	TP_PROTO(const char *issuer),
diff --git a/kernel/drivers/testing/timerbench.c b/kernel/drivers/testing/timerbench.c
index 31f0bea76..68e50a241 100644
--- a/kernel/drivers/testing/timerbench.c
+++ b/kernel/drivers/testing/timerbench.c
@@ -82,8 +82,8 @@ static void eval_inner_loop(struct rt_tmbench_context *ctx, __s32 dt)
 		ctx->freeze_max &&
 		(dt > ctx->result.overall.max) &&
 		!ctx->warmup) {
-		xntrace_user_freeze(dt, false);
 		ctx->result.overall.max = dt;
+		xntrace_latpeak_freeze(dt);
 	}
 
 	ctx->date += ctx->period;
diff --git a/lib/cobalt/trace.c b/lib/cobalt/trace.c
index 42e139f13..8d9c18902 100644
--- a/lib/cobalt/trace.c
+++ b/lib/cobalt/trace.c
@@ -53,6 +53,11 @@ int xntrace_user_freeze(unsigned long v, int once)
 				v, once);
 }
 
+void xntrace_latpeak_freeze(int delay)
+{
+	XENOMAI_SYSCALL2(sc_cobalt_trace, __xntrace_op_latpeak_freeze, delay);
+}
+
 int xntrace_special(unsigned char id, unsigned long v)
 {
 	return XENOMAI_SYSCALL3(sc_cobalt_trace, __xntrace_op_special, id, v);
diff --git a/testsuite/latency/latency.c b/testsuite/latency/latency.c
index 5304342ff..a0e6f4826 100644
--- a/testsuite/latency/latency.c
+++ b/testsuite/latency/latency.c
@@ -192,7 +192,7 @@ static void *latency(void *cookie)
 
 			if (freeze_max && (dt > gmaxjitter)
 			    && !(finished || warmup)) {
-				xntrace_user_freeze(dt, 0);
+				xntrace_latpeak_freeze(dt);
 				gmaxjitter = dt;
 			}
 
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 07/12] cobalt/kevents: dovetail: unregister thread resuming from ptrace stop
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (5 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 06/12] cobalt/trace: add tracing call to notify of a latency peak Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 08/12] cobalt/sched: dovetail: fix missed switching to OOB opportunities Jan Kiszka
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
[Jan: style fix]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/kevents.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
index df5408ccc..164ab9461 100644
--- a/kernel/cobalt/dovetail/kevents.c
+++ b/kernel/cobalt/dovetail/kevents.c
@@ -481,14 +481,19 @@ int handle_ptrace_resume(struct task_struct *tracee)
 
 static void handle_ptrace_cont(void)
 {
-	/*
-	 * This is the place where the ptrace-related work which used
-	 * to happen in handle_schedule_event() should go. We are
-	 * called when current is resuming execution after a ptrace
-	 * stopped state, which is what look for in
-	 * handle_schedule_event().
-	 */
-	TODO();
+	struct xnthread *curr = xnthread_current();
+	spl_t s;
+
+	xnlock_get_irqsave(&nklock, s);
+
+	if (xnthread_test_state(curr, XNSSTEP)) {
+		if (!xnthread_test_info(curr, XNCONTHI))
+			unregister_debugged_thread(curr);
+
+		xnthread_set_localinfo(curr, XNHICCUP);
+	}
+
+	xnlock_put_irqrestore(&nklock, s);
 }
 
 void handle_inband_event(enum inband_event_type event, void *data)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 08/12] cobalt/sched: dovetail: fix missed switching to OOB opportunities
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (6 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 07/12] cobalt/kevents: dovetail: unregister thread resuming from ptrace stop Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 09/12] cobalt/clock: dovetail: use refined monotonic source Jan Kiszka
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Ask for switching back to oob mode once ptrace core tell that
current is resuming from a stopped state, leaving space for
other runnable RT threads of the process to take over.

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
[Philippe: added missing dovetail_request_ucall to pipeline_leave_oob_prepare]
Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/kevents.c |  2 ++
 kernel/cobalt/dovetail/sched.c   | 17 +++++++++++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
index 164ab9461..37ff6ca4b 100644
--- a/kernel/cobalt/dovetail/kevents.c
+++ b/kernel/cobalt/dovetail/kevents.c
@@ -491,6 +491,8 @@ static void handle_ptrace_cont(void)
 			unregister_debugged_thread(curr);
 
 		xnthread_set_localinfo(curr, XNHICCUP);
+
+		dovetail_request_ucall(current);
 	}
 
 	xnlock_put_irqrestore(&nklock, s);
diff --git a/kernel/cobalt/dovetail/sched.c b/kernel/cobalt/dovetail/sched.c
index de7c43b70..074bc006e 100644
--- a/kernel/cobalt/dovetail/sched.c
+++ b/kernel/cobalt/dovetail/sched.c
@@ -56,9 +56,22 @@ int pipeline_leave_inband(void)
 
 int pipeline_leave_oob_prepare(void)
 {
-	dovetail_leave_oob();
+	int suspmask = XNRELAX;
+	struct xnthread *curr = xnthread_current();
 
-	return XNRELAX;
+	dovetail_leave_oob();
+	/*
+	 * If current is being debugged, record that it should migrate
+	 * back in case it resumes in userspace. If it resumes in
+	 * kernel space, i.e.  over a restarting syscall, the
+	 * associated hardening will clear XNCONTHI.
+	 */
+	if (xnthread_test_state(curr, XNSSTEP)) {
+		xnthread_set_info(curr, XNCONTHI);
+		dovetail_request_ucall(current);
+		suspmask |= XNDBGSTOP;
+	}
+	return suspmask;
 }
 
 void pipeline_leave_oob_finish(void)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 09/12] cobalt/clock: dovetail: use refined monotonic source
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (7 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 08/12] cobalt/sched: dovetail: fix missed switching to OOB opportunities Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 10/12] cobalt/clock: pipeline: abstract handling of CLOCK_REALTIME Jan Kiszka
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

In order to have applications calling clock_gettime(CLOCK_MONOTONIC)
and Cobalt share the same monotonic source, we need Cobalt to get
timestamps from ktime_get_mono_fast_ns().

Although pipeline_read_cycle_counter() does seem to hint to a raw
source, with Dovetail, our idea of time is directly based on a refined
count of nanoseconds since the epoch, the hardware time counter is
transparent to us. This naming discrepancy comes from the legacy
I-pipe support where we do manipulate hardware ticks internally; this
issue should go when such support is discontinued eventually.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/clock.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index 6761ed70d..388367e6e 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -13,8 +13,14 @@ struct timespec64;
 
 static inline u64 pipeline_read_cycle_counter(void)
 {
-	/* Read the raw cycle counter of the core clock. */
-	return  ktime_get_raw_fast_ns();
+	/*
+	 * With Dovetail, our idea of time is directly based on a
+	 * refined count of nanoseconds since the epoch, the hardware
+	 * time counter is transparent to us. For this reason,
+	 * xnclock_ticks_to_ns() and xnclock_ns_to_ticks() are
+	 * idempotent when building for Dovetail.
+	 */
+	return ktime_get_mono_fast_ns();
 }
 
 void pipeline_set_timer_shot(unsigned long cycles);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 10/12] cobalt/clock: pipeline: abstract handling of CLOCK_REALTIME
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (8 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 09/12] cobalt/clock: dovetail: use refined monotonic source Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 11/12] rtdm/fd: move inband work description off the stack Jan Kiszka
  2021-06-04 10:05 ` [PATCH 12/12] drivers/udd: " Jan Kiszka
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Dovetail allows the client core to share the common kernel clocks,
including CLOCK_REALTIME. This means the core does not have to
maintain the latter clock, but should hand over all requests to read
the clock and change its epoch to the corresponding in-band kernel
services instead. Conversely, Cobalt should keep on maintaining
CLOCK_REALTIME when running on top of the legacy I-pipe.

Abstract the management of CLOCK_REALTIME to enable such split based
on the underlying IRQ pipeline layer.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/clock.h                 | 12 ++--
 .../cobalt/kernel/dovetail/pipeline/clock.h   | 11 ++++
 include/cobalt/kernel/ipipe/pipeline/clock.h  |  5 ++
 kernel/cobalt/clock.c                         | 66 +++++++++++--------
 kernel/cobalt/dovetail/kevents.c              | 10 +++
 kernel/cobalt/ipipe/clock.c                   | 15 +++++
 kernel/cobalt/ipipe/tick.c                    |  3 -
 kernel/cobalt/posix/clock.c                   |  9 +--
 8 files changed, 89 insertions(+), 42 deletions(-)

diff --git a/include/cobalt/kernel/clock.h b/include/cobalt/kernel/clock.h
index 0e4f1e1cb..2f7b71404 100644
--- a/include/cobalt/kernel/clock.h
+++ b/include/cobalt/kernel/clock.h
@@ -43,7 +43,7 @@ struct xnclock_gravity {
 
 struct xnclock {
 	/** (ns) */
-	xnticks_t wallclock_offset;
+	xnsticks_t wallclock_offset;
 	/** (ns) */
 	xnticks_t resolution;
 	/** (raw clock ticks). */
@@ -112,9 +112,6 @@ void xnclock_deregister(struct xnclock *clock);
 
 void xnclock_tick(struct xnclock *clock);
 
-void xnclock_adjust(struct xnclock *clock,
-		    xnsticks_t delta);
-
 void xnclock_core_local_shot(struct xnsched *sched);
 
 void xnclock_core_remote_shot(struct xnsched *sched);
@@ -319,6 +316,8 @@ static inline void xnclock_reset_gravity(struct xnclock *clock)
 
 static inline xnticks_t xnclock_read_realtime(struct xnclock *clock)
 {
+	if (likely(clock == &nkclock))
+		return pipeline_read_wallclock();
 	/*
 	 * Return an adjusted value of the monotonic time with the
 	 * translated system wallclock offset.
@@ -326,6 +325,11 @@ static inline xnticks_t xnclock_read_realtime(struct xnclock *clock)
 	return xnclock_read_monotonic(clock) + xnclock_get_offset(clock);
 }
 
+void xnclock_apply_offset(struct xnclock *clock,
+			  xnsticks_t delta_ns);
+
+void xnclock_set_wallclock(xnticks_t epoch_ns);
+
 unsigned long long xnclock_divrem_billion(unsigned long long value,
 					  unsigned long *rem);
 
diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index 388367e6e..d8c94ab43 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -8,6 +8,7 @@
 #include <cobalt/uapi/kernel/types.h>
 #include <cobalt/kernel/assert.h>
 #include <linux/ktime.h>
+#include <linux/errno.h>
 
 struct timespec64;
 
@@ -23,6 +24,16 @@ static inline u64 pipeline_read_cycle_counter(void)
 	return ktime_get_mono_fast_ns();
 }
 
+static inline xnticks_t pipeline_read_wallclock(void)
+{
+	return ktime_get_real_fast_ns();
+}
+
+static inline int pipeline_set_wallclock(xnticks_t epoch_ns)
+{
+	return -EOPNOTSUPP;
+}
+
 void pipeline_set_timer_shot(unsigned long cycles);
 
 const char *pipeline_timer_name(void);
diff --git a/include/cobalt/kernel/ipipe/pipeline/clock.h b/include/cobalt/kernel/ipipe/pipeline/clock.h
index d35aea17b..a06d1aaae 100644
--- a/include/cobalt/kernel/ipipe/pipeline/clock.h
+++ b/include/cobalt/kernel/ipipe/pipeline/clock.h
@@ -6,6 +6,7 @@
 #define _COBALT_KERNEL_IPIPE_CLOCK_H
 
 #include <linux/ipipe_tickdev.h>
+#include <cobalt/uapi/kernel/types.h>
 
 struct timespec64;
 
@@ -16,6 +17,10 @@ static inline u64 pipeline_read_cycle_counter(void)
 	return t;
 }
 
+xnticks_t pipeline_read_wallclock(void);
+
+int pipeline_set_wallclock(xnticks_t epoch_ns);
+
 static inline void pipeline_set_timer_shot(unsigned long cycles)
 {
 	ipipe_timer_set(cycles);
diff --git a/kernel/cobalt/clock.c b/kernel/cobalt/clock.c
index 2115b15ef..2b9efad4e 100644
--- a/kernel/cobalt/clock.c
+++ b/kernel/cobalt/clock.c
@@ -226,18 +226,28 @@ enqueue:
 	xntimer_enqueue(timer, q);
 }
 
-static void adjust_clock_timers(struct xnclock *clock, xnsticks_t delta)
+void xnclock_apply_offset(struct xnclock *clock, xnsticks_t delta_ns)
 {
 	struct xntimer *timer, *tmp;
 	struct list_head adjq;
 	struct xnsched *sched;
+	xnsticks_t delta;
 	xntimerq_it_t it;
 	unsigned int cpu;
 	xntimerh_t *h;
 	xntimerq_t *q;
 
+	atomic_only();
+
+	/*
+	 * The (real-time) epoch just changed for the clock. Since
+	 * timeout dates of timers are expressed as monotonic ticks
+	 * internally, we need to apply the new offset to the
+	 * monotonic clock to all outstanding timers based on the
+	 * affected clock.
+	 */
 	INIT_LIST_HEAD(&adjq);
-	delta = xnclock_ns_to_ticks(clock, delta);
+	delta = xnclock_ns_to_ticks(clock, delta_ns);
 
 	for_each_online_cpu(cpu) {
 		sched = xnsched_struct(cpu);
@@ -265,34 +275,28 @@ static void adjust_clock_timers(struct xnclock *clock, xnsticks_t delta)
 			xnclock_program_shot(clock, sched);
 	}
 }
+EXPORT_SYMBOL_GPL(xnclock_apply_offset);
 
-/**
- * @fn void xnclock_adjust(struct xnclock *clock, xnsticks_t delta)
- * @brief Adjust a clock time.
- *
- * This service changes the epoch for the given clock by applying the
- * specified tick delta on its wallclock offset.
- *
- * @param clock The clock to adjust.
- *
- * @param delta The adjustment value expressed in nanoseconds.
- *
- * @coretags{task-unrestricted, atomic-entry}
- *
- * @note Xenomai tracks the system time in @a nkclock, as a
- * monotonously increasing count of ticks since the epoch. The epoch
- * is initially the same as the underlying machine time.
- */
-void xnclock_adjust(struct xnclock *clock, xnsticks_t delta)
+void xnclock_set_wallclock(xnticks_t epoch_ns)
 {
-	xnticks_t now;
+	xnsticks_t old_offset_ns, offset_ns;
+	spl_t s;
 
-	nkclock.wallclock_offset += delta;
-	nkvdso->wallclock_offset = nkclock.wallclock_offset;
-	now = xnclock_read_monotonic(clock) + nkclock.wallclock_offset;
-	adjust_clock_timers(clock, delta);
+	/*
+	 * The epoch of CLOCK_REALTIME just changed. Since timeouts
+	 * are expressed as monotonic ticks, we need to apply the
+	 * wallclock-to-monotonic offset to all outstanding timers
+	 * based on this clock.
+	 */
+	xnlock_get_irqsave(&nklock, s);
+	old_offset_ns = nkclock.wallclock_offset;
+	offset_ns = (xnsticks_t)(epoch_ns - xnclock_core_read_monotonic());
+	nkclock.wallclock_offset = offset_ns;
+	nkvdso->wallclock_offset = offset_ns;
+	xnclock_apply_offset(&nkclock, offset_ns - old_offset_ns);
+	xnlock_put_irqrestore(&nklock, s);
 }
-EXPORT_SYMBOL_GPL(xnclock_adjust);
+EXPORT_SYMBOL_GPL(xnclock_set_wallclock);
 
 xnticks_t xnclock_core_read_monotonic(void)
 {
@@ -464,7 +468,7 @@ static int clock_show(struct xnvfile_regular_iterator *it, void *data)
 
 	if (clock->id >= 0)	/* External clock, print id. */
 		xnvfile_printf(it, "%7s: %d\n", "id", __COBALT_CLOCK_EXT(clock->id));
-		
+
 	xnvfile_printf(it, "%7s: irq=%Ld kernel=%Ld user=%Ld\n", "gravity",
 		       xnclock_ticks_to_ns(clock, xnclock_get_gravity(clock, irq)),
 		       xnclock_ticks_to_ns(clock, xnclock_get_gravity(clock, kernel)),
@@ -700,7 +704,7 @@ void xnclock_tick(struct xnclock *clock)
 	else
 #endif
 		tmq = &xnclock_this_timerdata(clock)->q;
-	
+
 	/*
 	 * Optimisation: any local timer reprogramming triggered by
 	 * invoked timer handlers can wait until we leave the tick
@@ -807,11 +811,17 @@ void xnclock_cleanup(void)
 
 int __init xnclock_init()
 {
+	spl_t s;
+
 #ifdef XNARCH_HAVE_NODIV_LLIMD
 	xnarch_init_u32frac(&bln_frac, 1, 1000000000);
 #endif
 	pipeline_init_clock();
 	xnclock_reset_gravity(&nkclock);
+	xnlock_get_irqsave(&nklock, s);
+	nkclock.wallclock_offset = pipeline_read_wallclock() -
+		xnclock_core_read_monotonic();
+	xnlock_put_irqrestore(&nklock, s);
 	xnclock_register(&nkclock, &xnsched_realtime_cpus);
 
 	return 0;
diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
index 37ff6ca4b..3987d119a 100644
--- a/kernel/cobalt/dovetail/kevents.c
+++ b/kernel/cobalt/dovetail/kevents.c
@@ -15,6 +15,7 @@
 #include <cobalt/kernel/thread.h>
 #include <cobalt/kernel/clock.h>
 #include <cobalt/kernel/vdso.h>
+#include <cobalt/kernel/init.h>
 #include <rtdm/driver.h>
 #include <trace/events/cobalt-core.h>
 #include "../posix/process.h"
@@ -528,6 +529,15 @@ void handle_inband_event(enum inband_event_type event, void *data)
 	}
 }
 
+/*
+ * Called by the in-band kernel when the CLOCK_REALTIME epoch changes.
+ */
+void inband_clock_was_set(void)
+{
+	if (realtime_core_enabled())
+		xnclock_set_wallclock(ktime_get_real_fast_ns());
+}
+
 #ifdef CONFIG_MMU
 
 int pipeline_prepare_current(void)
diff --git a/kernel/cobalt/ipipe/clock.c b/kernel/cobalt/ipipe/clock.c
index d40b0ac89..1c04eed94 100644
--- a/kernel/cobalt/ipipe/clock.c
+++ b/kernel/cobalt/ipipe/clock.c
@@ -7,6 +7,8 @@
 #include <cobalt/kernel/clock.h>
 #include <cobalt/kernel/vdso.h>
 #include <cobalt/kernel/arith.h>
+#include <cobalt/kernel/timer.h>
+#include <xenomai/posix/clock.h>
 #include <pipeline/machine.h>
 
 static unsigned long long clockfreq;
@@ -121,6 +123,19 @@ int pipeline_get_host_time(struct timespec64 *tp)
 #endif
 }
 
+xnticks_t pipeline_read_wallclock(void)
+{
+	return xnclock_read_monotonic(&nkclock) + xnclock_get_offset(&nkclock);
+}
+EXPORT_SYMBOL_GPL(pipeline_read_wallclock);
+
+int pipeline_set_wallclock(xnticks_t epoch_ns)
+{
+	xnclock_set_wallclock(epoch_ns);
+
+	return 0;
+}
+
 void pipeline_update_clock_freq(unsigned long long freq)
 {
 	spl_t s;
diff --git a/kernel/cobalt/ipipe/tick.c b/kernel/cobalt/ipipe/tick.c
index d6dacad9b..db6e37cfe 100644
--- a/kernel/cobalt/ipipe/tick.c
+++ b/kernel/cobalt/ipipe/tick.c
@@ -184,9 +184,6 @@ int pipeline_install_tick_proxy(void)
 		    per_cpu(ipipe_percpu.hrtimer_irq, 0), NULL, NULL, 0);
 #endif /* CONFIG_XENO_OPT_STATS_IRQS */
 
-	nkclock.wallclock_offset =
-		ktime_to_ns(ktime_get_real()) - xnclock_read_monotonic(&nkclock);
-
 #ifdef CONFIG_SMP
 	ret = ipipe_request_irq(&cobalt_pipeline.domain,
 				IPIPE_HRTIMER_IPI,
diff --git a/kernel/cobalt/posix/clock.c b/kernel/cobalt/posix/clock.c
index 23a45bba9..6a479568c 100644
--- a/kernel/cobalt/posix/clock.c
+++ b/kernel/cobalt/posix/clock.c
@@ -142,18 +142,13 @@ COBALT_SYSCALL(clock_gettime, current,
 int __cobalt_clock_settime(clockid_t clock_id, const struct timespec64 *ts)
 {
 	int _ret, ret = 0;
-	xnticks_t now;
-	spl_t s;
 
 	if ((unsigned long)ts->tv_nsec >= ONE_BILLION)
 		return -EINVAL;
 
 	switch (clock_id) {
 	case CLOCK_REALTIME:
-		xnlock_get_irqsave(&nklock, s);
-		now = xnclock_read_realtime(&nkclock);
-		xnclock_adjust(&nkclock, (xnsticks_t) (ts2ns(ts) - now));
-		xnlock_put_irqrestore(&nklock, s);
+		ret = pipeline_set_wallclock(ts2ns(ts));
 		break;
 	default:
 		_ret = do_ext_clock(clock_id, set_time, ret, ts);
@@ -163,7 +158,7 @@ int __cobalt_clock_settime(clockid_t clock_id, const struct timespec64 *ts)
 
 	trace_cobalt_clock_settime(clock_id, ts);
 
-	return 0;
+	return ret;
 }
 
 int __cobalt_clock_adjtime(clockid_t clock_id, struct __kernel_timex *tx)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 11/12] rtdm/fd: move inband work description off the stack
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (9 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 10/12] cobalt/clock: pipeline: abstract handling of CLOCK_REALTIME Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  2021-06-04 10:05 ` [PATCH 12/12] drivers/udd: " Jan Kiszka
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Unlike the I-pipe, Dovetail does not copy the work descriptor but
merely hands over the request to the common irq_work() mechanism. We
must guarantee that such descriptor lives in a portion of memory which
won't go stale until the handler has run, which by design can only
happen once the calling out-of-band context unwinds.

Therefore, we have to move the in-band work descriptor used in
triggering fd closure off the stack to a global variable, which is
fine since the action of flushing the lingering fds is globally
scoped.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/rtdm/fd.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/kernel/cobalt/rtdm/fd.c b/kernel/cobalt/rtdm/fd.c
index 038247d54..151884a24 100644
--- a/kernel/cobalt/rtdm/fd.c
+++ b/kernel/cobalt/rtdm/fd.c
@@ -257,10 +257,6 @@ out:
 }
 EXPORT_SYMBOL_GPL(rtdm_fd_get);
 
-struct lostage_trigger_close {
-	struct pipeline_inband_work inband_work; /* Must be first. */
-};
-
 static int fd_cleanup_thread(void *data)
 {
 	struct rtdm_fd *fd;
@@ -293,9 +289,16 @@ static void lostage_trigger_close(struct pipeline_inband_work *inband_work)
 	up(&rtdm_fd_cleanup_sem);
 }
 
+static struct lostage_trigger_close {
+	struct pipeline_inband_work inband_work; /* Must be first. */
+} fd_closework =  {
+	.inband_work = PIPELINE_INBAND_WORK_INITIALIZER(fd_closework,
+						lostage_trigger_close),
+};
+
 static void __put_fd(struct rtdm_fd *fd, spl_t s)
 {
-	bool destroy;
+	bool destroy, trigger;
 
 	XENO_WARN_ON(COBALT, fd->refs <= 0);
 	destroy = --fd->refs == 0;
@@ -310,16 +313,13 @@ static void __put_fd(struct rtdm_fd *fd, spl_t s)
 	if (is_secondary_domain())
 		fd->ops->close(fd);
 	else {
-		struct lostage_trigger_close closework = {
-			.inband_work = PIPELINE_INBAND_WORK_INITIALIZER(closework,
-					lostage_trigger_close),
-		};
-
 		xnlock_get_irqsave(&fdtree_lock, s);
+		trigger = list_empty(&rtdm_fd_cleanup_queue);
 		list_add_tail(&fd->cleanup, &rtdm_fd_cleanup_queue);
 		xnlock_put_irqrestore(&fdtree_lock, s);
 
-		pipeline_post_inband_work(&closework);
+		if (trigger)
+			pipeline_post_inband_work(&fd_closework);
 	}
 }
 
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 12/12] drivers/udd: move inband work description off the stack
  2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
                   ` (10 preceding siblings ...)
  2021-06-04 10:05 ` [PATCH 11/12] rtdm/fd: move inband work description off the stack Jan Kiszka
@ 2021-06-04 10:05 ` Jan Kiszka
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2021-06-04 10:05 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Unlike the I-pipe, Dovetail does not copy the work descriptor but
merely hands over the request to the common irq_work() mechanism. We
must guarantee that such descriptor lives in a portion of memory which
won't go stale until the handler has run, which by design can only
happen once the calling out-of-band context unwinds.

Therefore, we have to allocate a request descriptor from the core heap
when issuing a request to enable/disable a particular IRQ channel from
the in-band stage.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/drivers/udd/udd.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/kernel/drivers/udd/udd.c b/kernel/drivers/udd/udd.c
index e1a2bc3b0..d263afc72 100644
--- a/kernel/drivers/udd/udd.c
+++ b/kernel/drivers/udd/udd.c
@@ -520,6 +520,7 @@ struct irqswitch_work {
 	rtdm_irq_t *irqh;
 	int enabled;
 	rtdm_event_t *done;
+	struct irqswitch_work *self; /* Revisit: I-pipe requirement */
 };
 
 static void lostage_irqswitch_line(struct pipeline_inband_work *inband_work)
@@ -538,24 +539,32 @@ static void lostage_irqswitch_line(struct pipeline_inband_work *inband_work)
 
 	if (rq->done)
 		rtdm_event_signal(rq->done);
+
+	xnfree(rq->self);
 }
 
 static void switch_irq_line(rtdm_irq_t *irqh, int enable, rtdm_event_t *done)
 {
-	struct irqswitch_work switchwork = {
-		.inband_work = PIPELINE_INBAND_WORK_INITIALIZER(switchwork,
-					lostage_irqswitch_line),
-		.irqh = irqh,
-		.enabled = enable,
-		.done = done,
-	};
+	struct irqswitch_work *rq;
+
+	rq = xnmalloc(sizeof(*rq));
+	if (WARN_ON(rq == NULL))
+		return;
+
+	rq->inband_work = (struct pipeline_inband_work)
+		PIPELINE_INBAND_WORK_INITIALIZER(*rq,
+					lostage_irqswitch_line);
+	rq->irqh = irqh;
+	rq->enabled = enable;
+	rq->done = done;
+	rq->self = rq;	/* Revisit: I-pipe requirement */
 
 	/*
 	 * Not pretty, but we may not traverse the kernel code for
 	 * enabling/disabling IRQ lines from primary mode. Defer this
 	 * to the root context.
 	 */
-	pipeline_post_inband_work(&switchwork);
+	pipeline_post_inband_work(rq);
 }
 
 /**
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-06-04 10:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-04 10:05 [PATCH 00/12] Dovetail integration, moving forward Jan Kiszka
2021-06-04 10:05 ` [PATCH 01/12] cobalt/kevents: dovetail: provide thread info initializer Jan Kiszka
2021-06-04 10:05 ` [PATCH 02/12] cobalt/thread: pipeline: refactor thread control block Jan Kiszka
2021-06-04 10:05 ` [PATCH 03/12] cobalt/build: pipeline: enable Dovetail support if detected Jan Kiszka
2021-06-04 10:05 ` [PATCH 04/12] cobalt/trace: Avoid clash with kernel trace definitions Jan Kiszka
2021-06-04 10:05 ` [PATCH 05/12] cobalt/trace: dovetail: enable basic tracepoints Jan Kiszka
2021-06-04 10:05 ` [PATCH 06/12] cobalt/trace: add tracing call to notify of a latency peak Jan Kiszka
2021-06-04 10:05 ` [PATCH 07/12] cobalt/kevents: dovetail: unregister thread resuming from ptrace stop Jan Kiszka
2021-06-04 10:05 ` [PATCH 08/12] cobalt/sched: dovetail: fix missed switching to OOB opportunities Jan Kiszka
2021-06-04 10:05 ` [PATCH 09/12] cobalt/clock: dovetail: use refined monotonic source Jan Kiszka
2021-06-04 10:05 ` [PATCH 10/12] cobalt/clock: pipeline: abstract handling of CLOCK_REALTIME Jan Kiszka
2021-06-04 10:05 ` [PATCH 11/12] rtdm/fd: move inband work description off the stack Jan Kiszka
2021-06-04 10:05 ` [PATCH 12/12] drivers/udd: " Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.