optimise syscall mux-code calculation
PATCH 1/1 optimise syscall mux-code calculation
Hi,
some may recall the "micro-optimisation" thread I once started. Here is now a simple approach to deal with the yet suboptimal mux-code calculation in user-space. Code saving:
Before:
text data bss dec hex filename
18004 476 8 18488 4838 native/.libs/libnative.so 27445 696 4 28145 6df1 posix/.libs/libpthread_rt.so
After:
text data bss dec hex filename
17172 476 8 17656 44f8 native/.libs/libnative.so 26805 696 4 27505 6b71 posix/.libs/libpthread_rt.so
Of course, this also results in a few ops less being executed on each Xenomai syscall invocation (not many cycles, though).
Tested without problems on x86 so far.
Jan
--- include/asm-arm/syscall.h | 25 +++++++++++++------------ include/asm-blackfin/syscall.h | 4 +++- include/asm-i386/syscall.h | 3 ++- include/asm-ia64/syscall.h | 23 ++++++++++++----------- include/asm-powerpc/syscall.h | 3 ++- ksrc/nucleus/shadow.c | 3 ++- 6 files changed, 34 insertions(+), 27 deletions(-)
include/asm-arm/syscall.h +13 -12
@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))#define XENO_ARM_SYSCALL 0x009F0042/* carefully chosen... */
@@ -131,19 +132,19 @@ static inline int __xn_interrupted_p(str#define __sys1 (x) __sys2(x) #define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ - ({ \ - unsigned long __res; \ + ({ \ + unsigned long __res; \ register unsigned long __res_r0 __asm__ ("r0"); \ - ASM_INDECL_##nr; \ - \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ - __asm__ __volatile__ ( \ -" swi " __sys1(XENO_ARM_SYSCALL) \ - : "=r" (__res_r0) \ - : ASM_INPUT_##nr \ - : "memory"); \ - __res = __res_r0; \ - (int) __res; \ + ASM_INDECL_##nr; \ + \ + LOADARGS_##nr(__xn_mux_code_shft(id,op), args); \ + __asm__ __volatile__ ( \ +" swi " __sys1(XENO_ARM_SYSCALL) \ + : "=r" (__res_r0) \ + : ASM_INPUT_##nr \ + : "memory"); \ + __res = __res_r0; \ + (int) __res; \ })#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)
include/asm-blackfin/syscall.h +3 -1
@@ -27,6 +27,7 @@ (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ #define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_fast(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))/* Local syscalls -- the braindamage thing about this arch is the absence of atomic ops usable from user-space; so we export what
@@ -213,7 +214,8 @@ static inline int __xn_interrupted_p(str __res; \ }) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) __emit_syscall##nr(__xn_mux_code(id,op), ##args) +#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ + __emit_syscall##nr(__xn_mux_code_shft(id,op), ##args)#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)#define XENOMAI_SYSCALL1 (op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
include/asm-i386/syscall.h +2 -1
@@ -23,6 +23,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0x7fff))#ifdef __KERNEL__
@@ -167,7 +168,7 @@ asm (".L__X'%ebx = 1\n\t" #define XENOMAI_SKIN_MUX(nr, id, op, args...) \ ({ \ - int muxcode = __xn_mux_code(id,op); \ + int muxcode = __xn_mux_code_shft(id,op); \ unsigned resultvar; \ asm volatile ( \ LOADARGS_##nr \
include/asm-ia64/syscall.h +12 -11
@@ -24,6 +24,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|(((id << 16) & 0xff0000UL)|(__xn_sys_mux & 0xffffUL))) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffffUL))#ifdef __KERNEL__
@@ -151,17 +152,17 @@ static inline int __xn_interrupted_p(str/* Branch registers. */ \ "b6", "b7" -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ - ({ \ - register long _r15 asm ("r15") = (__xn_mux_code(id,op)); \ - register long _retval asm ("r8"); \ - register long err asm ("r10"); \ - LOAD_ARGS_##nr (args); \ - __asm __volatile ("break %3;;\n\t" \ - : "=r" (_retval), "=r" (_r15), "=r" (err) \ - : "i" (__BREAK_SYSCALL), "1" (_r15) \ - ASM_ARGS_##nr \ - : "memory" ASM_CLOBBERS_##nr); \ +#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ + ({ \ + register long _r15 asm ("r15") = (__xn_mux_code_shft(id,op)); \ + register long _retval asm ("r8"); \ + register long err asm ("r10"); \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_retval), "=r" (_r15), "=r" (err) \ + : "i" (__BREAK_SYSCALL), "1" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ err < 0 ? -_retval : _retval; }) #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op , ##args)
include/asm-powerpc/syscall.h +2 -1
@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))#ifdef __KERNEL__
@@ -132,7 +133,7 @@ static inline int __xn_interrupted_p(str registerunsigned long __sc_6 __asm__ ("r6" ); \ registerunsigned long __sc_7 __asm__ ("r7" ); \ \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ + LOADARGS_##nr(__xn_mux_code_shft(id,op), args); \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0 " \
ksrc/nucleus/shadow.c +2 -1
@@ -1187,7 +1187,8 @@ static int xnshadow_sys_bind(struct taskreturn err; } -return muxid; +/* return pre-shifted muxid - saves some cycles in user-space */ +return __xn_mux_code (muxid,0 ); }static int xnshadow_sys_info (struct task_struct *curr,struct pt_regs *regs)
Quoted 13 lines · Jan Kiszka
Hi,
some may recall the "micro-optimisation" thread I once started. Here is now a simple approach to deal with the yet suboptimal mux-code calculation in user-space. Code saving:
Before:
text data bss dec hex filename18004 476 8 18488 4838 native/.libs/libnative.so 27445 696 4 28145 6df1 posix/.libs/libpthread_rt.soAfter:
text data bss dec hex filename
Quoted 8 lines
17172 476 8 17656 44f8 native/.libs/libnative.so 26805 696 4 27505 6b71 posix/.libs/libpthread_rt.soOf course, this also results in a few ops less being executed on each Xenomai syscall invocation (not many cycles, though).
Tested without problems on x86 so far.
This is post 2.2 stuff since we need to check this critical change against each and every supported arch. Since this breaks the ABI including the ascending compatibility between old apps and new kernel support, this won't make it during the v2 series either.
Quoted 16 lines
Jan
plain text document attachment (optimise-muxcode-calculation.patch)--- include/asm-arm/syscall.h | 25 +++++++++++++------------ include/asm-blackfin/syscall.h | 4 +++- include/asm-i386/syscall.h | 3 ++- include/asm-ia64/syscall.h | 23 ++++++++++++----------- include/asm-powerpc/syscall.h | 3 ++- ksrc/nucleus/shadow.c | 3 ++- 6 files changed, 34 insertions(+), 27 deletions(-)Index:
xenomai/include/asm-arm/syscall.h
===================================================================
include/asm-arm/syscall.h line 29
Quoted 4 lines
include/asm-arm/syscall.h +1
-0@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))
+#define __xn_mux_code_shft(shifted_id,op) ((op << 24)|shifted_id)
should be enough.
<snip>
include/asm-blackfin/syscall.h line 31
Quoted 10 lines
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-0@@ -27,6 +27,7 @@ (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ #define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_fast(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))
Breakage alert.
Signature · 1 line
Philippe.
Quoted 17 lines · Philippe Gerum
Quoted 16 lines · Jan Kiszka
Hi,
some may recall the "micro-optimisation" thread I once started. Here is now a simple approach to deal with the yet suboptimal mux-code calculation in user-space. Code saving:
Before:
text data bss dec hex filename18004 476 8 18488 4838 native/.libs/libnative.so 27445 696 4 28145 6df1 posix/.libs/libpthread_rt.soAfter:
text data bss dec hex filename17172 476 8 17656 44f8 native/.libs/libnative.so 26805 696 4 27505 6b71 posix/.libs/libpthread_rt.so
Quoted 8 lines
Quoted 5 lines
Of course, this also results in a few ops less being executed on each Xenomai syscall invocation (not many cycles, though).
Tested without problems on x86 so far.
This is post 2.2 stuff since we need to check this critical change against each and every supported arch.
Agree, there is no need to hurry in 2.2.
Quoted 3 lines
Since this breaks the ABI
including the ascending compatibility between old apps and new kernel support, this won't make it during the v2 series either.
The ABI chance just took place due to my laziness - I didn't want to touch every skin library. Anyway, this ABI breakage can be avoided with slightly more effort, i.e. by doing the shift in user-space during the binding.
Quoted 19 lines
Quoted 19 lines
Jan
plain text document attachment (optimise-muxcode-calculation.patch)--- include/asm-arm/syscall.h | 25 +++++++++++++------------ include/asm-blackfin/syscall.h | 4 +++- include/asm-i386/syscall.h | 3 ++- include/asm-ia64/syscall.h | 23 ++++++++++++----------- include/asm-powerpc/syscall.h | 3 ++- ksrc/nucleus/shadow.c | 3 ++- 6 files changed, 34 insertions(+), 27 deletions(-)Index:
xenomai/include/asm-arm/syscall.h
===================================================================include/asm-arm/syscall.h +0
-0@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h>
Quoted 6 lines
include/asm-arm/syscall.h line 29
Quoted 2 lines
include/asm-arm/syscall.h +1
-0#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))+#define
__xn_mux_code_shft(shifted_id,op)((op << 24)|shifted_id)should be enough.
Given my current calculation of the muxid in the kernel, yes. But the original variant has zero effect on the code and looks more consistent to me.
Quoted 16 lines
<snip>
include/asm-blackfin/syscall.h line 31
Quoted 10 lines
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-0@@ -27,6 +27,7 @@ (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ #define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_fast(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))Breakage alert.
Oops.
Ok, I will rework this patch.
Jan
Quoted 29 lines · Jan Kiszka
Quoted 17 lines · Philippe Gerum
Quoted 16 lines · Jan Kiszka
Hi,
some may recall the "micro-optimisation" thread I once started. Here is now a simple approach to deal with the yet suboptimal mux-code calculation in user-space. Code saving:
Before:
text data bss dec hex filename18004 476 8 18488 4838 native/.libs/libnative.so 27445 696 4 28145 6df1 posix/.libs/libpthread_rt.soAfter:
text data bss dec hex filename17172 476 8 17656 44f8 native/.libs/libnative.so 26805 696 4 27505 6b71 posix/.libs/libpthread_rt.soQuoted 8 lines
Quoted 5 lines
Of course, this also results in a few ops less being executed on each Xenomai syscall invocation (not many cycles, though).
Tested without problems on x86 so far.
This is post 2.2 stuff since we need to check this critical change against each and every supported arch.
Agree, there is no need to hurry in 2.2.
Quoted 9 lines
Quoted 3 lines
Since this breaks the ABI
including the ascending compatibility between old apps and new kernel support, this won't make it during the v2 series either.The ABI chance just took place due to my laziness - I didn't want to touch every skin library. Anyway, this ABI breakage can be avoided with slightly more effort, i.e. by doing the shift in user-space during the binding.
Yes, the mangling should be done in xeno_user_skin_init().
Quoted 24 lines
Quoted 24 lines
Quoted 17 lines
Jan
plain text document attachment (optimise-muxcode-calculation.patch)--- include/asm-arm/syscall.h | 25 +++++++++++++------------ include/asm-blackfin/syscall.h | 4 +++- include/asm-i386/syscall.h | 3 ++- include/asm-ia64/syscall.h | 23 ++++++++++++----------- include/asm-powerpc/syscall.h | 3 ++- ksrc/nucleus/shadow.c | 3 ++- 6 files changed, 34 insertions(+), 27 deletions(-)Index:
xenomai/include/asm-arm/syscall.h
===================================================================include/asm-arm/syscall.h line 29
Quoted 4 lines
include/asm-arm/syscall.h +1
-0@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))+#define
__xn_mux_code_shft(shifted_id,op)((op << 24)|shifted_id)
Quoted 5 lines
Quoted 1 line
should be enough.
Given my current calculation of the muxid in the kernel, yes. But the original variant has zero effect on the code and looks more consistent to me.
I don't get why actually. If the point is about reducing the number of micro operations per syscall, then leaving this redundancy is pointless. The relative obfuscation this optimization brings to the code is already there, regardless of when the mux tag is crammed into the syscall code:
in any case, we have an half-baked syscall code which is going to be adjusted at invocation time.
Quoted 24 lines
Quoted 4 lines
<snip>
Quoted 13 lines
include/asm-blackfin/syscall.h line 31
Quoted 10 lines
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-0@@ -27,6 +27,7 @@ (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ #define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_fast(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))Breakage alert.
Oops.
Ok, I will rework this patch.
Jan
Signature · 1 line
Philippe.
Quoted 31 lines · Philippe Gerum
Quoted 30 lines · Jan Kiszka
Quoted 17 lines · Philippe Gerum
Quoted 16 lines · Jan Kiszka
Hi,
some may recall the "micro-optimisation" thread I once started. Here is now a simple approach to deal with the yet suboptimal mux-code calculation in user-space. Code saving:
Before:
text data bss dec hex filename18004 476 8 18488 4838 native/.libs/libnative.so 27445 696 4 28145 6df1 posix/.libs/libpthread_rt.soAfter:
text data bss dec hex filename17172 476 8 17656 44f8 native/.libs/libnative.so 26805 696 4 27505 6b71 posix/.libs/libpthread_rt.soQuoted 7 lines
Quoted 5 lines
Of course, this also results in a few ops less being executed on each Xenomai syscall invocation (not many cycles, though).
Tested without problems on x86 so far.
This is post 2.2 stuff since we need to check this critical change against each and every supported arch.
Agree, there is no need to hurry in 2.2.
Quoted 3 lines
Since this breaks the ABI
including the ascending compatibility between old apps and new kernel support, this won't make it during the v2 series either.
Quoted 7 lines
Quoted 5 lines
The ABI chance just took place due to my laziness - I didn't want to touch every skin library. Anyway, this ABI breakage can be avoided with slightly more effort, i.e. by doing the shift in user-space during the binding.
Yes, the mangling should be done in
xeno_user_skin_init().
Oh, great, I forgot the new common init code for the skin. This will help.
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
Quoted 17 lines
Jan
plain text document attachment (optimise-muxcode-calculation.patch)--- include/asm-arm/syscall.h | 25 +++++++++++++------------ include/asm-blackfin/syscall.h | 4 +++- include/asm-i386/syscall.h | 3 ++- include/asm-ia64/syscall.h | 23 ++++++++++++----------- include/asm-powerpc/syscall.h | 3 ++- ksrc/nucleus/shadow.c | 3 ++- 6 files changed, 34 insertions(+), 27 deletions(-)Index:
xenomai/include/asm-arm/syscall.h
===================================================================include/asm-arm/syscall.h line 29
Quoted 4 lines
include/asm-arm/syscall.h +1
-0@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h> #define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))+#define
__xn_mux_code_shft(shifted_id,op)((op << 24)|shifted_id)
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
should be enough.
Given my current calculation of the muxid in the kernel, yes. But the original variant has zero effect on the code and looks more consistent to me.
I don't get why actually. If the point is about reducing the number of micro operations per syscall, then leaving this redundancy is pointless.
As "op" is typically, well, always constant, that __xn_sys_mux bits are just merge during compile time into the same constant.
Quoted 4 lines
The relative obfuscation this optimization brings to the code is already there, regardless of when the mux tag is crammed into the syscall code:
in any case, we have an half-baked syscall code which is going to be adjusted at invocation time.
My second approach will likely only shift the muxid ahead-of-time, thus reduce obfuscation a bit again.
Quoted 21 lines
Quoted 21 lines
Quoted 15 lines
<snip>
include/asm-blackfin/syscall.h line 31
Quoted 10 lines
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-0@@ -27,6 +27,7 @@ (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ #define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_fast(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))Breakage alert.
Oops.
Ok, I will rework this patch.
Jan
Quoted 70 lines · Jan Kiszka
Quoted 31 lines · Philippe Gerum
Quoted 30 lines · Jan Kiszka
Quoted 17 lines · Philippe Gerum
Quoted 16 lines · Jan Kiszka
Hi,
some may recall the "micro-optimisation" thread I once started. Here is now a simple approach to deal with the yet suboptimal mux-code calculation in user-space. Code saving:
Before:
text data bss dec hex filename18004 476 8 18488 4838 native/.libs/libnative.so 27445 696 4 28145 6df1 posix/.libs/libpthread_rt.soAfter:
text data bss dec hex filename17172 476 8 17656 44f8 native/.libs/libnative.so 26805 696 4 27505 6b71 posix/.libs/libpthread_rt.soQuoted 7 lines
Quoted 5 lines
Of course, this also results in a few ops less being executed on each Xenomai syscall invocation (not many cycles, though).
Tested without problems on x86 so far.
This is post 2.2 stuff since we need to check this critical change against each and every supported arch.
Agree, there is no need to hurry in 2.2.
Quoted 3 lines
Since this breaks the ABI
including the ascending compatibility between old apps and new kernel support, this won't make it during the v2 series either.Quoted 7 lines
Quoted 5 lines
The ABI chance just took place due to my laziness - I didn't want to touch every skin library. Anyway, this ABI breakage can be avoided with slightly more effort, i.e. by doing the shift in user-space during the binding.
Yes, the mangling should be done in
xeno_user_skin_init().Oh, great, I forgot the new common init code for the skin. This will help.
Quoted 28 lines
Quoted 27 lines
Quoted 19 lines
Quoted 19 lines
Jan
plain text document attachment (optimise-muxcode-calculation.patch)--- include/asm-arm/syscall.h | 25 +++++++++++++------------ include/asm-blackfin/syscall.h | 4 +++- include/asm-i386/syscall.h | 3 ++- include/asm-ia64/syscall.h | 23 ++++++++++++----------- include/asm-powerpc/syscall.h | 3 ++- ksrc/nucleus/shadow.c | 3 ++- 6 files changed, 34 insertions(+), 27 deletions(-)Index:
xenomai/include/asm-arm/syscall.h
===================================================================include/asm-arm/syscall.h +0
-0@@ -26,6 +26,7 @@#include <asm-generic/xenomai/syscall.h> Quoted 5 lines
include/asm-arm/syscall.h line 29
Quoted 2 lines
include/asm-arm/syscall.h +1
-0#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_shft (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))+#define
__xn_mux_code_shft(shifted_id,op)((op << 24)|shifted_id)should be enough.
Given my current calculation of the muxid in the kernel, yes. But the original variant has zero effect on the code and looks more consistent to me.
Quoted 6 lines
Quoted 2 lines
I don't get why actually. If the point is about reducing the number of micro operations per syscall, then leaving this redundancy is pointless.
As "op" is typically, well, always constant, that
__xn_sys_muxbits are just merge during compile time into the same constant.
Exactly, this is part of what I called "relative obfuscation". If both codes do the same thing, then one of them is one too many.
Quoted 31 lines
Quoted 4 lines
The relative obfuscation this optimization brings to the code is already there, regardless of when the mux tag is crammed into the syscall code:
in any case, we have an half-baked syscall code which is going to be adjusted at invocation time.My second approach will likely only shift the muxid ahead-of-time, thus reduce obfuscation a bit again.
Quoted 21 lines
Quoted 21 lines
Quoted 15 lines
<snip>
include/asm-blackfin/syscall.h line 31
Quoted 10 lines
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-0@@ -27,6 +27,7 @@ (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ #define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code_fast(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))Breakage alert.
Oops.
Ok, I will rework this patch.
Jan
Signature · 1 line
Philippe.
Quoted 3 lines · Jan Kiszka
...
Ok, I will rework this patch.
And here is -v2 (for post 2.2 trunk). It keeps the ABI but changes the API wrt __xeno_mux_code. As this change gets widely caught by xeno_user_skin_init, the modifications are limited.
At this chance I also converted the rtdm library to the generic initialisation code. I tweaked nucleus/bind.h a bit so that one can control via XENO_DISABLE_MLOCKALL_DETECTION if the related code gets built into the lib. This appeared to be reasonable to me because librtdm doesn't create its own RT threads, thus the check should be better left to those skins who do so. Anyone any better idea, or is this acceptable? If a separate patch is preferred, I will break out this change.
Tested of x86, other archs need review and/or testing.
Jan
--- include/asm-arm/syscall.h | 29 ++++++++++++------------ include/asm-blackfin/syscall.h | 6 +++-- include/asm-i386/syscall.h | 7 +++-- include/asm-ia64/syscall.h | 25 ++++++++++---------- include/asm-powerpc/syscall.h | 7 +++-- include/nucleus/bind.h | 19 ++++++++++----- src/skins/rtdm/init.c | 49 +++-------------------------------------- 7 files changed, 56 insertions(+), 86 deletions(-)
include/asm-arm/syscall.h +15 -14
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#define XENO_ARM_SYSCALL 0x009F0042/* carefully chosen... */
@@ -130,20 +131,20 @@ static inline int __xn_interrupted_p(str#define __sys2 (x) #x#define __sys1 (x) __sys2(x) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ - ({ \ - unsigned long __res; \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + ({ \ + unsigned long __res; \ register unsigned long __res_r0 __asm__ ("r0"); \ - ASM_INDECL_##nr; \ - \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ - __asm__ __volatile__ ( \ -" swi " __sys1(XENO_ARM_SYSCALL) \ - : "=r" (__res_r0) \ - : ASM_INPUT_##nr \ - : "memory"); \ - __res = __res_r0; \ - (int) __res; \ + ASM_INDECL_##nr; \ + \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ + __asm__ __volatile__ ( \ +" swi " __sys1(XENO_ARM_SYSCALL) \ + : "=r" (__res_r0) \ + : ASM_INPUT_##nr \ + : "memory"); \ + __res = __res_r0; \ + (int) __res; \ })#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)
include/asm-blackfin/syscall.h +4 -2
@@ -26,7 +26,8 @@ marker. Note: watch out for the p0 sign convention used by Linux (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ -#define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id(id) (id << 24)/* Local syscalls -- the braindamage thing about this arch is the absence of atomic ops usable from user-space; so we export what
@@ -213,7 +214,8 @@ static inline int __xn_interrupted_p(str __res; \ }) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) __emit_syscall##nr(__xn_mux_code(id,op), ##args) +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + __emit_syscall##nr(__xn_mux_code(shifted_id,op), ##args)#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)#define XENOMAI_SYSCALL1 (op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
include/asm-i386/syscall.h +4 -3
@@ -22,7 +22,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -165,9 +166,9 @@ asm (".L__X'%ebx = 1\n\t" : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ ({ \ - int muxcode = __xn_mux_code(id,op); \ + int muxcode = __xn_mux_code(shifted_id,op); \ unsigned resultvar; \ asm volatile ( \ LOADARGS_##nr \
include/asm-ia64/syscall.h +13 -12
@@ -23,7 +23,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|(((id << 16) & 0xff0000UL)|(__xn_sys_mux & 0xffffUL))) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffffUL)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000UL)#ifdef __KERNEL__
@@ -151,17 +152,17 @@ static inline int __xn_interrupted_p(str/* Branch registers. */ \ "b6", "b7" -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ - ({ \ - register long _r15 asm ("r15") = (__xn_mux_code(id,op)); \ - register long _retval asm ("r8"); \ - register long err asm ("r10"); \ - LOAD_ARGS_##nr (args); \ - __asm __volatile ("break %3;;\n\t" \ - : "=r" (_retval), "=r" (_r15), "=r" (err) \ - : "i" (__BREAK_SYSCALL), "1" (_r15) \ - ASM_ARGS_##nr \ - : "memory" ASM_CLOBBERS_##nr); \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ + ({ \ + register long _r15 asm ("r15") = (__xn_mux_code(shifted_id,op)); \ + register long _retval asm ("r8"); \ + register long err asm ("r10"); \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_retval), "=r" (_r15), "=r" (err) \ + : "i" (__BREAK_SYSCALL), "1" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ err < 0 ? -_retval : _retval; }) #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op , ##args)
include/asm-powerpc/syscall.h +4 -3
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -123,7 +124,7 @@ static inline int __xn_interrupted_p(str#define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)#define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ ({ \ register unsigned long __sc_0 __asm__ ("r0"); \ register unsigned long __sc_3 __asm__ ("r3"); \
@@ -132,7 +133,7 @@ static inline int __xn_interrupted_p(str registerunsigned long __sc_6 __asm__ ("r6" ); \ registerunsigned long __sc_7 __asm__ ("r7" ); \ \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0 " \
include/nucleus/bind.h +12 -7
@@ -9,6 +9,7 @@#include <pthread.h> #include <asm/xenomai/syscall.h> +#ifndef XENO_DISABLE_MLOCKALL_DETECTION __attribute__((weak))int xeno_sigxcpu_no_mlock =1 ;static void xeno_handle_mlock_alert (int sig)
@@ -34,11 +35,11 @@ static void xeno_handle_mlock_alert (in pthread_kill(pthread_self(),SIGXCPU); } } +#endif /* !XENO_DISABLE_MLOCKALL_DETECTION */ static inline int xeno_user_skin_init (unsigned skin_magic,const char *skin,const char *module) { -struct sigaction sa;xnfeatinfo_t finfo;int muxid;
@@ -80,15 +81,19 @@ xeno_user_skin_init(unsigned skin_magic, exit(1); } +#ifndef XENO_DISABLE_MLOCKALL_DETECTION /* Install a SIGXCPU handler to intercept alerts about unlocked process memory. */ + { +struct sigaction sa; + sa.sa_handler = &xeno_handle_mlock_alert; +sigemptyset (&sa.sa_mask); + sa.sa_flags =0 ; +sigaction (SIGXCPU ,&sa,NULL ); + } +#endif /* !XENO_DISABLE_MLOCKALL_DETECTION */ - sa.sa_handler = &xeno_handle_mlock_alert; -sigemptyset (&sa.sa_mask); - sa.sa_flags =0 ; -sigaction (SIGXCPU ,&sa,NULL ); - -return muxid; +return __xn_mux_shifted_id (muxid); }#endif /* _XENO_NUCLEUS_BIND_H */
src/skins/rtdm/init.c +4 -45
59 lines not on this page · raw message
include/asm-blackfin/syscall.h line 29
Quoted 10 lines · Jan Kiszka
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-1@@ -26,7 +26,8 @@ marker. Note: watch out for the p0 sign convention used by Linux (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ -#define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))
Should not this be (op << 16) ?
Quoted 1 line
include/asm-blackfin/syscall.h +1
-0+#define __xn_mux_shifted_id (id) (id << 24)
Signature · 1 line
Gilles Chanteperdrix.
Quoted 14 lines · Gilles Chanteperdrix
include/asm-blackfin/syscall.h line 29
Quoted 10 lines · Jan Kiszka
Index:
xenomai/include/asm-blackfin/syscall.h
===================================================================include/asm-blackfin/syscall.h +1
-1@@ -26,7 +26,8 @@ marker. Note: watch out for the p0 sign convention used by Linux (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ -#define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code(shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff))Should not this be (op << 16) ?
Yes, corrected version attached.
Thanks,
Jan
--- include/asm-arm/syscall.h | 29 ++++++++++++------------ include/asm-blackfin/syscall.h | 6 +++-- include/asm-i386/syscall.h | 7 +++-- include/asm-ia64/syscall.h | 25 ++++++++++---------- include/asm-powerpc/syscall.h | 7 +++-- include/nucleus/bind.h | 19 ++++++++++----- src/skins/rtdm/init.c | 49 +++-------------------------------------- 7 files changed, 56 insertions(+), 86 deletions(-)
include/asm-arm/syscall.h +15 -14
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#define XENO_ARM_SYSCALL 0x009F0042/* carefully chosen... */
@@ -130,20 +131,20 @@ static inline int __xn_interrupted_p(str#define __sys2 (x) #x#define __sys1 (x) __sys2(x) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ - ({ \ - unsigned long __res; \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + ({ \ + unsigned long __res; \ register unsigned long __res_r0 __asm__ ("r0"); \ - ASM_INDECL_##nr; \ - \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ - __asm__ __volatile__ ( \ -" swi " __sys1(XENO_ARM_SYSCALL) \ - : "=r" (__res_r0) \ - : ASM_INPUT_##nr \ - : "memory"); \ - __res = __res_r0; \ - (int) __res; \ + ASM_INDECL_##nr; \ + \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ + __asm__ __volatile__ ( \ +" swi " __sys1(XENO_ARM_SYSCALL) \ + : "=r" (__res_r0) \ + : ASM_INPUT_##nr \ + : "memory"); \ + __res = __res_r0; \ + (int) __res; \ })#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)
include/asm-blackfin/syscall.h +4 -2
@@ -26,7 +26,8 @@ marker. Note: watch out for the p0 sign convention used by Linux (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ -#define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code(shifted_id,op) (shifted_id|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id(id) (id << 24)/* Local syscalls -- the braindamage thing about this arch is the absence of atomic ops usable from user-space; so we export what
@@ -213,7 +214,8 @@ static inline int __xn_interrupted_p(str __res; \ }) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) __emit_syscall##nr(__xn_mux_code(id,op), ##args) +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + __emit_syscall##nr(__xn_mux_code(shifted_id,op), ##args)#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)#define XENOMAI_SYSCALL1 (op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
include/asm-i386/syscall.h +4 -3
@@ -22,7 +22,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -165,9 +166,9 @@ asm (".L__X'%ebx = 1\n\t" : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ ({ \ - int muxcode = __xn_mux_code(id,op); \ + int muxcode = __xn_mux_code(shifted_id,op); \ unsigned resultvar; \ asm volatile ( \ LOADARGS_##nr \
include/asm-ia64/syscall.h +13 -12
@@ -23,7 +23,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|(((id << 16) & 0xff0000UL)|(__xn_sys_mux & 0xffffUL))) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffffUL)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000UL)#ifdef __KERNEL__
@@ -151,17 +152,17 @@ static inline int __xn_interrupted_p(str/* Branch registers. */ \ "b6", "b7" -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ - ({ \ - register long _r15 asm ("r15") = (__xn_mux_code(id,op)); \ - register long _retval asm ("r8"); \ - register long err asm ("r10"); \ - LOAD_ARGS_##nr (args); \ - __asm __volatile ("break %3;;\n\t" \ - : "=r" (_retval), "=r" (_r15), "=r" (err) \ - : "i" (__BREAK_SYSCALL), "1" (_r15) \ - ASM_ARGS_##nr \ - : "memory" ASM_CLOBBERS_##nr); \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ + ({ \ + register long _r15 asm ("r15") = (__xn_mux_code(shifted_id,op)); \ + register long _retval asm ("r8"); \ + register long err asm ("r10"); \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_retval), "=r" (_r15), "=r" (err) \ + : "i" (__BREAK_SYSCALL), "1" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ err < 0 ? -_retval : _retval; }) #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op , ##args)
include/asm-powerpc/syscall.h +4 -3
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -123,7 +124,7 @@ static inline int __xn_interrupted_p(str#define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)#define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ ({ \ register unsigned long __sc_0 __asm__ ("r0"); \ register unsigned long __sc_3 __asm__ ("r3"); \
@@ -132,7 +133,7 @@ static inline int __xn_interrupted_p(str registerunsigned long __sc_6 __asm__ ("r6" ); \ registerunsigned long __sc_7 __asm__ ("r7" ); \ \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0 " \
include/nucleus/bind.h +12 -7
@@ -9,6 +9,7 @@#include <pthread.h> #include <asm/xenomai/syscall.h> +#ifndef XENO_DISABLE_MLOCKALL_DETECTION __attribute__((weak))int xeno_sigxcpu_no_mlock =1 ;static void xeno_handle_mlock_alert (int sig)
@@ -34,11 +35,11 @@ static void xeno_handle_mlock_alert (in pthread_kill(pthread_self(),SIGXCPU); } } +#endif /* !XENO_DISABLE_MLOCKALL_DETECTION */ static inline int xeno_user_skin_init (unsigned skin_magic,const char *skin,const char *module) { -struct sigaction sa;xnfeatinfo_t finfo;int muxid;
@@ -80,15 +81,19 @@ xeno_user_skin_init(unsigned skin_magic, exit(1); } +#ifndef XENO_DISABLE_MLOCKALL_DETECTION /* Install a SIGXCPU handler to intercept alerts about unlocked process memory. */ + { +struct sigaction sa; + sa.sa_handler = &xeno_handle_mlock_alert; +sigemptyset (&sa.sa_mask); + sa.sa_flags =0 ; +sigaction (SIGXCPU ,&sa,NULL ); + } +#endif /* !XENO_DISABLE_MLOCKALL_DETECTION */ - sa.sa_handler = &xeno_handle_mlock_alert; -sigemptyset (&sa.sa_mask); - sa.sa_flags =0 ; -sigaction (SIGXCPU ,&sa,NULL ); - -return muxid; +return __xn_mux_shifted_id (muxid); }#endif /* _XENO_NUCLEUS_BIND_H */
src/skins/rtdm/init.c +4 -45
59 lines not on this page · raw message
Quoted 9 lines · Jan Kiszka
Quoted 3 lines · Jan Kiszka
...
Ok, I will rework this patch.And here is -v2 (for post 2.2 trunk). It keeps the ABI but changes the API wrt
__xeno_mux_code. As this change gets widely caught byxeno_user_skin_init, the modifications are limited.
Quoted 7 lines
At this chance I also converted the rtdm library to the generic initialisation code. I tweaked
nucleus/bind.ha bit so that one can control viaXENO_DISABLE_MLOCKALL_DETECTIONif the related code gets built into the lib. This appeared to be reasonable to me because librtdm doesn't create its own RT threads, thus the check should be better left to those skins who do so. Anyone any better idea, or is this acceptable? If a separate patch is preferred, I will break out this change.
Another reason why rtdm did not use the generic initialization code is that RTDM did not call exit upon failure to bind, and let a later call to open fail. I do not know if it was desirable, but it was a feature of the previous implementation.
Signature · 1 line
Gilles Chanteperdrix.
Quoted 18 lines · Gilles Chanteperdrix
Quoted 9 lines · Jan Kiszka
Quoted 3 lines · Jan Kiszka
...
Ok, I will rework this patch.And here is -v2 (for post 2.2 trunk). It keeps the ABI but changes the API wrt
__xeno_mux_code. As this change gets widely caught byxeno_user_skin_init, the modifications are limited.Quoted 7 lines
At this chance I also converted the rtdm library to the generic initialisation code. I tweaked
nucleus/bind.ha bit so that one can control viaXENO_DISABLE_MLOCKALL_DETECTIONif the related code gets built into the lib. This appeared to be reasonable to me because librtdm doesn't create its own RT threads, thus the check should be better left to those skins who do so. Anyone any better idea, or is this acceptable? If a separate patch is preferred, I will break out this change.
Quoted 5 lines
Another reason why rtdm did not use the generic initialization code is that RTDM did not call exit upon failure to bind, and let a later call to open fail. I do not know if it was desirable, but it was a feature of the previous implementation.
Damn right. So let's try this more systematically:
The first patch prepares the generic skin-init code for the usage by rtdm/init.c. I'm not totally happy with the #ifndef tweak. I would prefer to control the signal setup also via a flag, but I have no idea how to avoid linking the unused xeno_handle_mlock_alert into librtdm. Any ideas?
Based on this conversion is the optimisation patch -v4. There was another quirk hidden in libpthread_rt which binds to RTDM "manually". That's now also covered by the patch.
Jan
--- include/nucleus/bind.h | 43 +++++++++++++++++++++++------------- src/skins/native/init.c | 2 - src/skins/posix/init.c | 2 - src/skins/rtai/init.c | 2 - src/skins/rtdm/init.c | 55 ++++++++--------------------------------------- src/skins/uvm/init.c | 3 +- src/skins/vrtx/init.c | 2 - src/skins/vxworks/init.c | 2 - 8 files changed, 45 insertions(+), 66 deletions(-)
include/nucleus/bind.h +28 -15
@@ -9,6 +9,9 @@#include <pthread.h> #include <asm/xenomai/syscall.h> +#define XNSKIN_LAZY_BIND_FAIL 0x01/* do not fail on missing skin */ + +#ifndef XNSKIN_NO_MLOCK_ALERT __attribute__((weak))int xeno_sigxcpu_no_mlock =1 ;static void xeno_handle_mlock_alert (int sig)
@@ -34,18 +37,19 @@ static void xeno_handle_mlock_alert (in pthread_kill(pthread_self(),SIGXCPU); } } +#endif /* !XNSKIN_NO_MLOCK_ALERT */ static inline int -xeno_user_skin_init (unsigned skin_magic,const char *skin,const char *module) +xeno_user_skin_init (unsigned skin_magic,const char *skin,const char *module, +int flags) { -struct sigaction sa;xnfeatinfo_t finfo; -int muxid; +int muxid =-1 ;#ifdef xeno_arch_features_checkxeno_arch_features_check ();#endif /* xeno_arch_features_check */ - + muxid = XENOMAI_SYSBIND(skin_magic, XENOMAI_FEAT_DEP, XENOMAI_ABI_REV,
@@ -69,24 +73,33 @@ xeno_user_skin_init(unsigned skin_magic,case -ENOSYS :case -ESRCH : +if (flags &XNSKIN_LAZY_BIND_FAIL ) +break ;/* We are ordered to ignore the missing skin. */ +fprintf (stderr,"Xenomai: %s skin or CONFIG_XENO_OPT_PERVASIVE disabled.\n" -"(modprobe %s?)\n" , skin, module); +"(modprobe %s?)\n" , skin, module);exit (1 ); - } - -if (muxid <0 ) - { -fprintf (stderr,"Xenomai: binding failed: %s.\n" ,strerror (-muxid)); -exit (1 ); + +default : +if (muxid <0 ) + { +fprintf (stderr,"Xenomai: binding failed: %s.\n" ,strerror (-muxid)); +exit (1 ); + } } +#ifndef XNSKIN_NO_MLOCK_ALERT /* Install a SIGXCPU handler to intercept alerts about unlocked process memory. */ + { +struct sigaction sa; - sa.sa_handler = &xeno_handle_mlock_alert; -sigemptyset (&sa.sa_mask); - sa.sa_flags =0 ; -sigaction (SIGXCPU ,&sa,NULL ); + sa.sa_handler = &xeno_handle_mlock_alert; +sigemptyset (&sa.sa_mask); + sa.sa_flags =0 ; +sigaction (SIGXCPU ,&sa,NULL ); + } +#endif /* !XNSKIN_NO_MLOCK_ALERT */ return muxid; }
src/skins/native/init.c +1 -1
@@ -39,7 +39,7 @@ static __attribute__ ((constructor))void __init_xeno_interface (void ) { __native_muxid = -xeno_user_skin_init (XENO_SKIN_MAGIC ,"native" ,"xeno_native" ); +xeno_user_skin_init (XENO_SKIN_MAGIC ,"native" ,"xeno_native" ,0 );/* Allocate a TSD key for indexing self task pointers. */
src/skins/posix/init.c +1 -1
@@ -40,7 +40,7 @@ void __init_posix_interface(void)int muxid, err; __pse51_muxid = -xeno_user_skin_init (PSE51_SKIN_MAGIC ,"POSIX" ,"xeno_posix" ); +xeno_user_skin_init (PSE51_SKIN_MAGIC ,"POSIX" ,"xeno_posix" ,0 ); muxid =XENOMAI_SYSBIND (RTDM_SKIN_MAGIC ,XENOMAI_FEAT_DEP ,XENOMAI_ABI_REV ,NULL );
src/skins/rtai/init.c +1 -1
@@ -27,5 +27,5 @@ static __attribute__ ((constructor))void __init_rtai_interface (void ) { __rtai_muxid = -xeno_user_skin_init (RTAI_SKIN_MAGIC ,"RTAI" ,"xeno_rtai" ); +xeno_user_skin_init (RTAI_SKIN_MAGIC ,"RTAI" ,"xeno_rtai" ,0 ); }
src/skins/rtdm/init.c +10 -45
65 lines not on this page · raw message
src/skins/uvm/init.c +2 -1
@@ -29,7 +29,8 @@ xnsysinfo_t __uvm_info;static __attribute__ ((constructor))void __init_uvm_interface (void ) { - __uvm_muxid =xeno_user_skin_init (UVM_SKIN_MAGIC ,"UVM" ,"xeno_uvm" ); + __uvm_muxid = +xeno_user_skin_init (UVM_SKIN_MAGIC ,"UVM" ,"xeno_uvm" ,0 );XENOMAI_SYSCALL2 (__xn_sys_info, __uvm_muxid, &__uvm_info); }
src/skins/vrtx/init.c +1 -1
@@ -40,7 +40,7 @@ void __init_xeno_interface(void)TCB *tcb; __vrtx_muxid = -xeno_user_skin_init (VRTX_SKIN_MAGIC ,"VRTX" ,"xeno_vrtx" ); +xeno_user_skin_init (VRTX_SKIN_MAGIC ,"VRTX" ,"xeno_vrtx" ,0 );/* Allocate a TSD key for indexing self task pointers. */
src/skins/vxworks/init.c +1 -1
@@ -38,7 +38,7 @@ static __attribute__ ((constructor))void __init_xeno_interface (void ) { __vxworks_muxid =xeno_user_skin_init (VXWORKS_SKIN_MAGIC , -"VxWorks" ,"xeno_vxworks" ); +"VxWorks" ,"xeno_vxworks" ,0 );/* Allocate a TSD key for indexing self task pointers. */
--- include/asm-arm/syscall.h | 29 ++++++++++++------------ include/asm-blackfin/syscall.h | 6 +++-- include/asm-i386/syscall.h | 7 +++-- include/asm-ia64/syscall.h | 25 ++++++++++---------- include/asm-powerpc/syscall.h | 7 +++-- include/nucleus/bind.h | 19 ++++++++++----- src/skins/rtdm/init.c | 49 +++-------------------------------------- 7 files changed, 56 insertions(+), 86 deletions(-)
include/asm-arm/syscall.h +15 -14
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#define XENO_ARM_SYSCALL 0x009F0042/* carefully chosen... */
@@ -130,20 +131,20 @@ static inline int __xn_interrupted_p(str#define __sys2 (x) #x#define __sys1 (x) __sys2(x) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ - ({ \ - unsigned long __res; \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + ({ \ + unsigned long __res; \ register unsigned long __res_r0 __asm__ ("r0"); \ - ASM_INDECL_##nr; \ - \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ - __asm__ __volatile__ ( \ -" swi " __sys1(XENO_ARM_SYSCALL) \ - : "=r" (__res_r0) \ - : ASM_INPUT_##nr \ - : "memory"); \ - __res = __res_r0; \ - (int) __res; \ + ASM_INDECL_##nr; \ + \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ + __asm__ __volatile__ ( \ +" swi " __sys1(XENO_ARM_SYSCALL) \ + : "=r" (__res_r0) \ + : ASM_INPUT_##nr \ + : "memory"); \ + __res = __res_r0; \ + (int) __res; \ })#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)
include/asm-blackfin/syscall.h +4 -2
@@ -26,7 +26,8 @@ marker. Note: watch out for the p0 sign convention used by Linux (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ -#define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code(shifted_id,op) (shifted_id|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id(id) (id << 24)/* Local syscalls -- the braindamage thing about this arch is the absence of atomic ops usable from user-space; so we export what
@@ -213,7 +214,8 @@ static inline int __xn_interrupted_p(str __res; \ }) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) __emit_syscall##nr(__xn_mux_code(id,op), ##args) +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + __emit_syscall##nr(__xn_mux_code(shifted_id,op), ##args)#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)#define XENOMAI_SYSCALL1 (op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
include/asm-i386/syscall.h +4 -3
@@ -22,7 +22,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -165,9 +166,9 @@ asm (".L__X'%ebx = 1\n\t" : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ ({ \ - int muxcode = __xn_mux_code(id,op); \ + int muxcode = __xn_mux_code(shifted_id,op); \ unsigned resultvar; \ asm volatile ( \ LOADARGS_##nr \
include/asm-ia64/syscall.h +13 -12
@@ -23,7 +23,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|(((id << 16) & 0xff0000UL)|(__xn_sys_mux & 0xffffUL))) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffffUL)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000UL)#ifdef __KERNEL__
@@ -151,17 +152,17 @@ static inline int __xn_interrupted_p(str/* Branch registers. */ \ "b6", "b7" -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ - ({ \ - register long _r15 asm ("r15") = (__xn_mux_code(id,op)); \ - register long _retval asm ("r8"); \ - register long err asm ("r10"); \ - LOAD_ARGS_##nr (args); \ - __asm __volatile ("break %3;;\n\t" \ - : "=r" (_retval), "=r" (_r15), "=r" (err) \ - : "i" (__BREAK_SYSCALL), "1" (_r15) \ - ASM_ARGS_##nr \ - : "memory" ASM_CLOBBERS_##nr); \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ + ({ \ + register long _r15 asm ("r15") = (__xn_mux_code(shifted_id,op)); \ + register long _retval asm ("r8"); \ + register long err asm ("r10"); \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_retval), "=r" (_r15), "=r" (err) \ + : "i" (__BREAK_SYSCALL), "1" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ err < 0 ? -_retval : _retval; }) #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op , ##args)
include/asm-powerpc/syscall.h +4 -3
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -123,7 +124,7 @@ static inline int __xn_interrupted_p(str#define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)#define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ ({ \ register unsigned long __sc_0 __asm__ ("r0"); \ register unsigned long __sc_3 __asm__ ("r3"); \
@@ -132,7 +133,7 @@ static inline int __xn_interrupted_p(str registerunsigned long __sc_6 __asm__ ("r6" ); \ registerunsigned long __sc_7 __asm__ ("r7" ); \ \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0 " \
Quoted 4 lines · Jan Kiszka
...
Based on this conversion is the optimisation patch -v4. There was another quirk hidden inlibpthread_rtwhich binds to RTDM "manually". That's now also covered by the patch.
Grr, missing run-quilt-refresh-before-post.
Jan
--- include/asm-arm/syscall.h | 29 +++++++++++++++-------------- include/asm-blackfin/syscall.h | 6 ++++-- include/asm-i386/syscall.h | 7 ++++--- include/asm-ia64/syscall.h | 25 +++++++++++++------------ include/asm-powerpc/syscall.h | 7 ++++--- include/nucleus/bind.h | 2 +- src/skins/posix/init.c | 2 +- 7 files changed, 42 insertions(+), 36 deletions(-)
include/asm-arm/syscall.h +15 -14
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#define XENO_ARM_SYSCALL 0x009F0042/* carefully chosen... */
@@ -130,20 +131,20 @@ static inline int __xn_interrupted_p(str#define __sys2 (x) #x#define __sys1 (x) __sys2(x) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ - ({ \ - unsigned long __res; \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + ({ \ + unsigned long __res; \ register unsigned long __res_r0 __asm__ ("r0"); \ - ASM_INDECL_##nr; \ - \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ - __asm__ __volatile__ ( \ -" swi " __sys1(XENO_ARM_SYSCALL) \ - : "=r" (__res_r0) \ - : ASM_INPUT_##nr \ - : "memory"); \ - __res = __res_r0; \ - (int) __res; \ + ASM_INDECL_##nr; \ + \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ + __asm__ __volatile__ ( \ +" swi " __sys1(XENO_ARM_SYSCALL) \ + : "=r" (__res_r0) \ + : ASM_INPUT_##nr \ + : "memory"); \ + __res = __res_r0; \ + (int) __res; \ })#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)
include/asm-blackfin/syscall.h +4 -2
@@ -26,7 +26,8 @@ marker. Note: watch out for the p0 sign convention used by Linux (i.e. negative syscall number in orig_p0 meaning "non-syscall entry"). */ -#define __xn_mux_code(id,op) ((id << 24)|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code(shifted_id,op) (shifted_id|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id(id) (id << 24)/* Local syscalls -- the braindamage thing about this arch is the absence of atomic ops usable from user-space; so we export what
@@ -213,7 +214,8 @@ static inline int __xn_interrupted_p(str __res; \ }) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) __emit_syscall##nr(__xn_mux_code(id,op), ##args) +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ + __emit_syscall##nr(__xn_mux_code(shifted_id,op), ##args)#define XENOMAI_SYSCALL0 (op) XENOMAI_DO_SYSCALL(0,0,op)#define XENOMAI_SYSCALL1 (op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
include/asm-i386/syscall.h +4 -3
@@ -22,7 +22,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0x7fff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -165,9 +166,9 @@ asm (".L__X'%ebx = 1\n\t" : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc"); \ (int) resultvar; }) -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ ({ \ - int muxcode = __xn_mux_code(id,op); \ + int muxcode = __xn_mux_code(shifted_id,op); \ unsigned resultvar; \ asm volatile ( \ LOADARGS_##nr \
include/asm-ia64/syscall.h +13 -12
@@ -23,7 +23,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|(((id << 16) & 0xff0000UL)|(__xn_sys_mux & 0xffffUL))) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffffUL)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000UL)#ifdef __KERNEL__
@@ -151,17 +152,17 @@ static inline int __xn_interrupted_p(str/* Branch registers. */ \ "b6", "b7" -#define XENOMAI_SKIN_MUX(nr, id, op, args...) \ - ({ \ - register long _r15 asm ("r15") = (__xn_mux_code(id,op)); \ - register long _retval asm ("r8"); \ - register long err asm ("r10"); \ - LOAD_ARGS_##nr (args); \ - __asm __volatile ("break %3;;\n\t" \ - : "=r" (_retval), "=r" (_r15), "=r" (err) \ - : "i" (__BREAK_SYSCALL), "1" (_r15) \ - ASM_ARGS_##nr \ - : "memory" ASM_CLOBBERS_##nr); \ +#define XENOMAI_SKIN_MUX(nr, shifted_id, op, args...) \ + ({ \ + register long _r15 asm ("r15") = (__xn_mux_code(shifted_id,op)); \ + register long _retval asm ("r8"); \ + register long err asm ("r10"); \ + LOAD_ARGS_##nr (args); \ + __asm __volatile ("break %3;;\n\t" \ + : "=r" (_retval), "=r" (_r15), "=r" (err) \ + : "i" (__BREAK_SYSCALL), "1" (_r15) \ + ASM_ARGS_##nr \ + : "memory" ASM_CLOBBERS_##nr); \ err < 0 ? -_retval : _retval; }) #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op , ##args)
include/asm-powerpc/syscall.h +4 -3
@@ -25,7 +25,8 @@#include <asm-generic/xenomai/syscall.h> -#define __xn_mux_code (id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff)) +#define __xn_mux_code (shifted_id,op) ((op << 24)|shifted_id|(__xn_sys_mux & 0xffff)) +#define __xn_mux_shifted_id (id) ((id << 16) & 0xff0000)#ifdef __KERNEL__
@@ -123,7 +124,7 @@ static inline int __xn_interrupted_p(str#define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)#define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7) -#define XENOMAI_DO_SYSCALL(nr, id, op, args...) \ +#define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \ ({ \ register unsigned long __sc_0 __asm__ ("r0"); \ register unsigned long __sc_3 __asm__ ("r3"); \
@@ -132,7 +133,7 @@ static inline int __xn_interrupted_p(str registerunsigned long __sc_6 __asm__ ("r6" ); \ registerunsigned long __sc_7 __asm__ ("r7" ); \ \ - LOADARGS_##nr(__xn_mux_code(id,op), args); \ + LOADARGS_##nr(__xn_mux_code(shifted_id,op), args); \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %0 " \
include/nucleus/bind.h +1 -1
@@ -101,7 +101,7 @@ xeno_user_skin_init(unsigned skin_magic, }#endif /* !XNSKIN_NO_MLOCK_ALERT */ -return muxid; +return __xn_mux_shifted_id (muxid); }#endif /* _XENO_NUCLEUS_BIND_H */
src/skins/posix/init.c +1 -1
@@ -45,7 +45,7 @@ void __init_posix_interface(void) muxid =XENOMAI_SYSBIND (RTDM_SKIN_MAGIC ,XENOMAI_FEAT_DEP ,XENOMAI_ABI_REV ,NULL );if (muxid >0 ) { - __rtdm_muxid = muxid; + __rtdm_muxid =__xn_mux_shifted_id (muxid); __rtdm_fd_start =FD_SETSIZE -XENOMAI_SKINCALL0 (__rtdm_muxid, __rtdm_fdcount); }
Philippe Gerum
AppliedQuoted 8 lines · Jan Kiszka
Quoted 4 lines · Jan Kiszka
...
Based on this conversion is the optimisation patch -v4. There was another quirk hidden inlibpthread_rtwhich binds to RTDM "manually". That's now also covered by the patch.Grr, missing run-quilt-refresh-before-post.
Applied, thanks.
Quoted 1 line
Jan
Signature · 1 line
Philippe.