Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-07-01 Thread Philippe Gerum
On Thu, 2006-06-29 at 13:20 +0200, Jan Kiszka wrote:
 Jan Kiszka wrote:
 
  Here comes an update of the irqbench patch.

 And this add-on fixes a classic copypaste issue.
 

Merged, along with the generic trace support. Thanks.

-- 
Philippe.



___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-07-01 Thread Jan Kiszka
Philippe Gerum wrote:
 On Thu, 2006-06-29 at 13:20 +0200, Jan Kiszka wrote:
 Jan Kiszka wrote:

 Here comes an update of the irqbench patch.
   
 And this add-on fixes a classic copypaste issue.

 
 Merged, along with the generic trace support. Thanks.
 

Almost :) - but it's fixed now.

Jan

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-29 Thread Jan Kiszka
Jan Kiszka wrote:

 Here comes an update of the irqbench patch.
   
And this add-on fixes a classic copypaste issue.

Jan


---
 ksrc/drivers/testing/irqbench.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

Index: xenomai/ksrc/drivers/testing/irqbench.c
===
--- xenomai.orig/ksrc/drivers/testing/irqbench.c
+++ xenomai/ksrc/drivers/testing/irqbench.c
@@ -444,7 +444,7 @@ static struct rtdm_device device = {
 proc_name:  device.device_name,
 };
 
-int __init __timerbench_init(void)
+int __init __irqbench_init(void)
 {
 int ret;
 
@@ -460,11 +460,11 @@ int __init __timerbench_init(void)
 }
 
 
-void __exit __timerbench_exit(void)
+void __exit __irqbench_exit(void)
 {
 rtdm_dev_unregister(device, 1000);
 }
 
 
-module_init(__timerbench_init);
-module_exit(__timerbench_exit);
+module_init(__irqbench_init);
+module_exit(__irqbench_exit);





signature.asc
Description: OpenPGP digital signature
___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-28 Thread Gilles Chanteperdrix
[EMAIL PROTECTED] wrote:
  Index: xenomai/src/testsuite/irqbench/irqbench.c
  ===
  --- /dev/null
  +++ xenomai/src/testsuite/irqbench/irqbench.c
  @@ -0,0 +1,301 @@
  +/*
  + * Copyright (C) 2006 Jan Kiszka [EMAIL PROTECTED].
  + *
  + * Xenomai is free software; you can redistribute it and/or modify it
  + * under the terms of the GNU General Public License as published by
  + * the Free Software Foundation; either version 2 of the License, or
  + * (at your option) any later version.
  + *
  + * Xenomai is distributed in the hope that it will be useful, but
  + * WITHOUT ANY WARRANTY; without even the implied warranty of
  + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  + * General Public License for more details.
  + *
  + * You should have received a copy of the GNU General Public License
  + * along with Xenomai; if not, write to the Free Software Foundation,
  + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  + */
  +
  +#include limits.h
  +#include stdio.h
  +#include stdlib.h
  +#include string.h
  +#include signal.h
  +#include unistd.h
  +#include sys/io.h
  +#include sys/mman.h
  +
  +
  +#define SERPORT 0
  +#define PARPORT 1
  +
  +/* --- Serial port --- */
  +
  +#define MCR_DTR 0x01
  +#define MCR_RTS 0x02
  +#define MCR_OUT20x08
  +
  +#define MSR_DELTA   0x0F
  +
  +#define LCR(base) (base + 3) /* Line Control Register */
  +#define MCR(base) (base + 4) /* Modem Control Register */
  +#define LSR(base) (base + 5) /* Line Status Register */
  +#define MSR(base) (base + 6) /* Modem Status Register */
  +
  +/* --- Parallel port --- */
  +
  +#define CTRL_INIT   0x04
  +
  +#define STAT_STROBE 0x10
  +
  +#define DATA(base) (base + 0) /* Data register */
  +#define STAT(base) (base + 1) /* Status register */
  +#define CTRL(base) (base + 2) /* Control register */
  +
  +double tsc2ns_scale;
  +long long min_lat = LLONG_MAX;
  +long long max_lat = LLONG_MIN;
  +long long avg_lat = 0;
  +long outer_loops = 0;
  +int warmup = 1;
  +
  +static inline long long rdtsc(void)
  +{
  +unsigned long long tsc;
  +
  +__asm__ __volatile__(rdtsc : =A (tsc));
  +return tsc;
  +}
  +
  +
  +static long tsc2ns(long long tsc)
  +{
  +if ((tsc  LONG_MAX) || (tsc  LONG_MIN)) {
  +fprintf(stderr, irqbench: overflow (%lld ns)!\n,
  +(long long)(tsc2ns_scale * (double)tsc));
  +exit(2);
  +}
  +return (long)(tsc2ns_scale * (double)tsc);
  +}
  +
  +
  +static inline long long ns2tsc(long long ns)
  +{
  +return (long long)(((double)ns) / tsc2ns_scale);
  +}
  +
  +
  +void calibrate_tsc(void)
  +{
  +FILE *proc;
  +char *lineptr = NULL;
  +size_t len;
  +double cpu_mhz;
  +
  +proc = fopen(/proc/cpuinfo, r);
  +if (proc == NULL) {
  +perror(irqbench: Unable to open /proc/cpuinfo);
  +exit(1);
  +}
  +
  +while (getline(lineptr, len, proc) != -1)
  +if (strncmp(lineptr, cpu MHz, 7) == 0) {
  +sscanf(strchr(lineptr, ':') + 1, %lf, cpu_mhz);
  +break;
  +}
  +
  +if (lineptr)
  +free(lineptr);
  +fclose(proc);
  +
  +printf(CPU frequency: %.3lf MHz\n, cpu_mhz);
  +
  +tsc2ns_scale = 1000.0 / cpu_mhz;
  +}
  +
  +
  +void sighand(int signal)
  +{
  +if (!warmup) {
  +avg_lat /= outer_loops;
  +printf(---\n%.3f / %.3f / %.3f us\n,
  +   ((double)min_lat) / 1000.0, ((double)avg_lat) / 1000.0,
  +   ((double)max_lat) / 1000.0);
  +}
  +exit(0);
  +}
  +
  +
  +int main(int argc, char *argv[])
  +{
  +int port_type   = SERPORT;
  +unsigned long   port_ioaddr = 0x3F8;
  +long long   period = 10;
  +long long   timeout;
  +long long   start, delay;
  +unsigned inttoggle;
  +int trigger_trace = 0;
  +int c;
  +
  +
  +signal(SIGINT, sighand);
  +signal(SIGTERM, sighand);
  +signal(SIGHUP, sighand);
  +signal(SIGALRM, sighand);
  +
  +calibrate_tsc();
  +
  +while ((c = getopt(argc,argv,p:T:o:a:f)) != EOF)
  +switch (c) {
  +case 'p':
  +period = atoi(optarg) * 1000;
  +break;
  +
  +case 'T':
  +alarm(atoi(optarg));
  +break;
  +
  +case 'o':
  +port_type = atoi(optarg);
  +break;
  +
  +case 'a':
  +port_ioaddr = strtol(optarg, NULL,
  +(strncmp(optarg, 0x, 2) == 0) ? 16 : 10);
  +break;
  +
  +case 'f':
  +trigger_trace = 1;
  +break;
  +
  +default:
  +fprintf(stderr, usage: irqbench [options]\n
  +  

Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-28 Thread Jan Kiszka
Gilles Chanteperdrix wrote:
 [EMAIL PROTECTED] wrote:
   Index: xenomai/src/testsuite/irqbench/irqbench.c
   ===
   --- /dev/null
   +++ xenomai/src/testsuite/irqbench/irqbench.c
   @@ -0,0 +1,301 @@
   +/*
   + * Copyright (C) 2006 Jan Kiszka [EMAIL PROTECTED].
   + *
   + * Xenomai is free software; you can redistribute it and/or modify it
   + * under the terms of the GNU General Public License as published by
   + * the Free Software Foundation; either version 2 of the License, or
   + * (at your option) any later version.
   + *
   + * Xenomai is distributed in the hope that it will be useful, but
   + * WITHOUT ANY WARRANTY; without even the implied warranty of
   + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   + * General Public License for more details.
   + *
   + * You should have received a copy of the GNU General Public License
   + * along with Xenomai; if not, write to the Free Software Foundation,
   + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   + */
   +
   +#include limits.h
   +#include stdio.h
   +#include stdlib.h
   +#include string.h
   +#include signal.h
   +#include unistd.h
   +#include sys/io.h
   +#include sys/mman.h
   +
   +
   +#define SERPORT 0
   +#define PARPORT 1
   +
   +/* --- Serial port --- */
   +
   +#define MCR_DTR 0x01
   +#define MCR_RTS 0x02
   +#define MCR_OUT20x08
   +
   +#define MSR_DELTA   0x0F
   +
   +#define LCR(base) (base + 3) /* Line Control Register */
   +#define MCR(base) (base + 4) /* Modem Control Register */
   +#define LSR(base) (base + 5) /* Line Status Register */
   +#define MSR(base) (base + 6) /* Modem Status Register */
   +
   +/* --- Parallel port --- */
   +
   +#define CTRL_INIT   0x04
   +
   +#define STAT_STROBE 0x10
   +
   +#define DATA(base) (base + 0) /* Data register */
   +#define STAT(base) (base + 1) /* Status register */
   +#define CTRL(base) (base + 2) /* Control register */
   +
   +double tsc2ns_scale;
   +long long min_lat = LLONG_MAX;
   +long long max_lat = LLONG_MIN;
   +long long avg_lat = 0;
   +long outer_loops = 0;
   +int warmup = 1;
   +
   +static inline long long rdtsc(void)
   +{
   +unsigned long long tsc;
   +
   +__asm__ __volatile__(rdtsc : =A (tsc));
   +return tsc;
   +}
   +
   +
   +static long tsc2ns(long long tsc)
   +{
   +if ((tsc  LONG_MAX) || (tsc  LONG_MIN)) {
   +fprintf(stderr, irqbench: overflow (%lld ns)!\n,
   +(long long)(tsc2ns_scale * (double)tsc));
   +exit(2);
   +}
   +return (long)(tsc2ns_scale * (double)tsc);
   +}
   +
   +
   +static inline long long ns2tsc(long long ns)
   +{
   +return (long long)(((double)ns) / tsc2ns_scale);
   +}
   +
   +
   +void calibrate_tsc(void)
   +{
   +FILE *proc;
   +char *lineptr = NULL;
   +size_t len;
   +double cpu_mhz;
   +
   +proc = fopen(/proc/cpuinfo, r);
   +if (proc == NULL) {
   +perror(irqbench: Unable to open /proc/cpuinfo);
   +exit(1);
   +}
   +
   +while (getline(lineptr, len, proc) != -1)
   +if (strncmp(lineptr, cpu MHz, 7) == 0) {
   +sscanf(strchr(lineptr, ':') + 1, %lf, cpu_mhz);
   +break;
   +}
   +
   +if (lineptr)
   +free(lineptr);
   +fclose(proc);
   +
   +printf(CPU frequency: %.3lf MHz\n, cpu_mhz);
   +
   +tsc2ns_scale = 1000.0 / cpu_mhz;
   +}
   +
   +
   +void sighand(int signal)
   +{
   +if (!warmup) {
   +avg_lat /= outer_loops;
   +printf(---\n%.3f / %.3f / %.3f us\n,
   +   ((double)min_lat) / 1000.0, ((double)avg_lat) / 1000.0,
   +   ((double)max_lat) / 1000.0);
   +}
   +exit(0);
   +}
   +
   +
   +int main(int argc, char *argv[])
   +{
   +int port_type   = SERPORT;
   +unsigned long   port_ioaddr = 0x3F8;
   +long long   period = 10;
   +long long   timeout;
   +long long   start, delay;
   +unsigned inttoggle;
   +int trigger_trace = 0;
   +int c;
   +
   +
   +signal(SIGINT, sighand);
   +signal(SIGTERM, sighand);
   +signal(SIGHUP, sighand);
   +signal(SIGALRM, sighand);
   +
   +calibrate_tsc();
   +
   +while ((c = getopt(argc,argv,p:T:o:a:f)) != EOF)
   +switch (c) {
   +case 'p':
   +period = atoi(optarg) * 1000;
   +break;
   +
   +case 'T':
   +alarm(atoi(optarg));
   +break;
   +
   +case 'o':
   +port_type = atoi(optarg);
   +break;
   +
   +case 'a':
   +port_ioaddr = strtol(optarg, NULL,
   +(strncmp(optarg, 0x, 2) == 0) ? 16 : 10);
   + 

Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-28 Thread Gilles Chanteperdrix
Jan Kiszka wrote:
   Is there no way to make this code easier to port for example by using
   native or posix services for timings measurement and by abstracting the
   non portable part and moving them to include/asm-i386 ?
  
  This tool is intentionally left Xenomai-free. You can put it on any x86
  box around (and I assume that there is almost always some...) and run
  the test. Thus, no need for a second RT-patched system.
  
  Anyway, suggestions or patches to add a porting layer are welcome. The
  following points need to be addressed: time measuring, irq protection,
  hardware access. I just wonder if this is worth the effort.

I do not understand: it appears to me that Xenomai trunk does not
compile on other architectures than x86 when applying the IRQ latency
benchmark patch. So, something needs to be done. It may be the enabling
of an automake conditional in configure.in when compiling for x86.

  
   
   Also note that calling printf from a signal handler risk deadlocking if
   the signal handler get called on the return path of the write call that
   take place in the middle of a printf call on the main thread.
   
  
  Ok, then we also need a fix for the latency test (this is where I
  grabbed that pattern from). Is there a high risk that this locks up? I
  wonder why I never observed or heard of problems with latency.

The latency test used to deadlock, that is why the summary printed on
signal is printed on stderr. Unfortunately, there seem to be one display
left on stdout, so it should still deadlock. The reason why we never see
the deadlock is (perhaps) that the continuous intermediate results are
printed on the context of the display thread, whereas the termination
signals are preferably delivered by the kernel to the main thread,
that only calls pause. Which makes the use of stderr in signals handlers
pointless.

Anyway, since your program is frequently using printf on the context of
the main thread, the risk of deadlock is real.

-- 


Gilles Chanteperdrix.

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-28 Thread Dmitry Adamushko

On 28/06/06, Gilles Chanteperdrix [EMAIL PROTECTED] wrote:

Jan Kiszka wrote:
 
  Ok, then we also need a fix for the latency test (this is where I
  grabbed that pattern from). Is there a high risk that this locks up? I
  wonder why I never observed or heard of problems with latency.

The latency test used to deadlock, that is why the summary printed on
signal is printed on stderr. Unfortunately, there seem to be one display
left on stdout, so it should still deadlock. The reason why we never see
the deadlock is (perhaps) that the continuous intermediate results are
printed on the context of the display thread, whereas the termination
signals are preferably delivered by the kernel to the main thread,
that only calls pause. Which makes the use of stderr in signals handlers
pointless.


It's very likely so.

The main thread would use instead something like :
...
while (!sig_term_received)
   pause();

do_cleanup_chores();
return 0;

cleanup_upon_sig() should only set the sig_term_received flag up.

Then all other threads must block signal delivering with sigprocmask()
so that the main thread is the only one which accepts signals.

btw, according to POSIX 1003.1-2003, the write() call is amongst safe ones.
http://www.die.net/doc/linux/man/man2/signal.2.html

So write(1, ); heh... not that nice? :)


--
Best regards,
Dmitry Adamushko

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-28 Thread Dmitry Adamushko


 Then all other threads must block signal delivering with sigprocmask()
 so that the main thread is the only one which accepts signals.

Is that required, i.e. does pause() only wake up if the signal handler
executed in the main thread's context? Then cyclictest contains a bug as
well...


If strictly speaking, then yes, it's required. But I expect your fix
to be working perfectly, just because the current linux implementation
always favors the main thread when it comes to choosing a thread to
handle the signal.

look at signal.c :: __group_complete_signal() routine where the actual
magic happens.

from the comments

/*
* Now find a thread we can wake up to take the signal off the queue.
*
* If the main thread wants the signal, it gets first crack.
* Probably the least surprising to the average bear.
*/

...

As I understand, the only case when another thread may handle the
signal indeed is when the main thread has already another pending
signal. But even then nothing bad happens as pause() (in the main
thread) will be interrupted by this pending signal. Just finished
will be set up by some other thread but it doesn't really matter.


--
Best regards,
Dmitry Adamushko

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-28 Thread Gilles Chanteperdrix
Jan Kiszka wrote:
   
   Also note that calling printf from a signal handler risk deadlocking if
   the signal handler get called on the return path of the write call that
   take place in the middle of a printf call on the main thread.
   
  
  Ok, then we also need a fix for the latency test (this is where I
  grabbed that pattern from). Is there a high risk that this locks up? I
  wonder why I never observed or heard of problems with latency.

The mutex used by the stdio lib depends on the file descriptor, so, it
is possible to use a different file descriptor in the signal handler and
on the interrupted context.

-- 


Gilles Chanteperdrix.

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[Xenomai-core] [PATCH 6/6] Introduce IRQ latency benchmark

2006-06-26 Thread jan . kiszka
This patch introduces another rttesting driver, xeno_irqbench, for measuring 
external IRQ latencies. The irqbench device is controlled by a user-mode tool 
irqloop. A second tool for plain Linux, irqbench, is provided to trigger the 
event over serial or parallel cross-link (the latter is incomplete yet) and 
measure the reaction latency.

---
 configure.in   |1 
 include/rtdm/rttesting.h   |   38 ++
 ksrc/drivers/Makefile  |2 
 ksrc/drivers/testing/Kconfig   |   21 +
 ksrc/drivers/testing/Makefile  |   13 -
 ksrc/drivers/testing/irqbench.c|  472 +
 src/testsuite/Makefile.am  |2 
 src/testsuite/irqbench/Makefile.am |   47 +++
 src/testsuite/irqbench/irqbench.c  |  301 +++
 src/testsuite/irqbench/irqloop.c   |  169 +
 src/testsuite/irqbench/runinfo |1 
 11 files changed, 1056 insertions(+), 11 deletions(-)

Index: xenomai/include/rtdm/rttesting.h
===
--- xenomai.orig/include/rtdm/rttesting.h
+++ xenomai/include/rtdm/rttesting.h
@@ -94,6 +94,28 @@ typedef struct rttst_tmbench_config {
 } rttst_tmbench_config_t;
 
 
+#define RTTST_IRQBENCH_USER_TASK0
+#define RTTST_IRQBENCH_KERNEL_TASK  1
+#define RTTST_IRQBENCH_HANDLER  2
+
+#define RTTST_IRQBENCH_SERPORT  0
+#define RTTST_IRQBENCH_PARPORT  1
+
+struct rttst_irqbench_config {
+int mode;
+int priority;
+int calibration_loops;
+unsigned intport_type;
+unsigned long   port_ioaddr;
+unsigned intport_irq;
+} rttst_irqbench_config_t;
+
+struct rttst_irqbench_stats {
+unsigned long long  irqs_received;
+unsigned long long  irqs_acknowledged;
+} rttst_irqbench_stats_t;
+
+
 #define RTTST_SWTEST_FPU0x1
 #define RTTST_SWTEST_USE_FPU0x2 /* Only for kernel-space tasks. */
 
@@ -134,6 +156,22 @@ struct rttst_swtest_dir {
 _IOWR(RTIOC_TYPE_TESTING, 0x11, struct rttst_overall_bench_res)
 
 
+#define RTTST_RTIOC_IRQBENCH_START \
+_IOW(RTIOC_TYPE_TESTING, 0x20, struct rttst_irqbench_config)
+
+#define RTTST_RTIOC_IRQBENCH_STOP \
+_IO(RTIOC_TYPE_TESTING, 0x21)
+
+#define RTTST_RTIOC_IRQBENCH_GET_STATS \
+_IOR(RTIOC_TYPE_TESTING, 0x22, struct rttst_irqbench_stats)
+
+#define RTTST_RTIOC_IRQBENCH_WAIT_IRQ \
+_IO(RTIOC_TYPE_TESTING, 0x23)
+
+#define RTTST_RTIOC_IRQBENCH_REPLY_IRQ \
+_IO(RTIOC_TYPE_TESTING, 0x24)
+
+
 #define RTTST_RTIOC_SWTEST_SET_TASKS_COUNT \
 _IOW(RTIOC_TYPE_TESTING, 0x30, unsigned long)
 
Index: xenomai/configure.in
===
--- xenomai.orig/configure.in
+++ xenomai/configure.in
@@ -602,6 +602,7 @@ AC_CONFIG_FILES([ \
src/testsuite/switchbench/Makefile \
src/testsuite/cyclic/Makefile \
src/testsuite/switchtest/Makefile \
+   src/testsuite/irqbench/Makefile \
include/Makefile \
include/asm-generic/Makefile \
include/asm-blackfin/Makefile \
Index: xenomai/ksrc/drivers/Makefile
===
--- xenomai.orig/ksrc/drivers/Makefile
+++ xenomai/ksrc/drivers/Makefile
@@ -11,7 +11,7 @@ else
 subdir-$(CONFIG_XENO_DRIVERS_16550A) += 16550A
 
 subdir-$(CONFIG_XENO_DRIVERS_TIMERBENCH) += testing
-
+subdir-$(CONFIG_XENO_DRIVERS_IRQBENCH)   += testing
 subdir-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += testing
 
 include $(TOPDIR)/Rules.make
Index: xenomai/ksrc/drivers/testing/Kconfig
===
--- xenomai.orig/ksrc/drivers/testing/Kconfig
+++ xenomai/ksrc/drivers/testing/Kconfig
@@ -6,10 +6,19 @@ config XENO_DRIVERS_TIMERBENCH
Kernel-based benchmark driver for timer latency evaluation.
See testsuite/latency for a possible front-end.
 
+config XENO_DRIVERS_IRQBENCH
+   depends on XENO_SKIN_RTDM
+   tristate IRQ benchmark driver
+   default n
+   help
+   Loopback driver for IRQ latency evaluation over serial or parallel
+   port links. Additionally requires user-space helper and a logging tool
+   (see testsuite/irqbench).
+
 config XENO_DRIVERS_SWITCHTEST
-depends on XENO_SKIN_RTDM
-tristate Context switch unit testing driver
-default n
-help
-Kernel-based driver for unit testing context switches and 
-FPU switches.
+   depends on XENO_SKIN_RTDM
+   tristate Context switch unit testing driver
+   default n
+   help
+   Kernel-based driver for unit testing context switches and
+   FPU switches.
Index: xenomai/ksrc/drivers/testing/Makefile
===
--- xenomai.orig/ksrc/drivers/testing/Makefile
+++ xenomai/ksrc/drivers/testing/Makefile
@@