All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Mode switch when using RT heap on ARM
@ 2008-11-10  9:58 Wolfgang Grandegger
  2008-11-10 11:42 ` Gilles Chanteperdrix
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Wolfgang Grandegger @ 2008-11-10  9:58 UTC (permalink / raw)
  To: xenomai-help

[-- Attachment #1: Type: text/plain, Size: 253 bytes --]

Hello,

I realized that accessing memory allocated with rt_heap_alloc() causes
mode switches on ARM i.mx31. The attached patch provides a demo program
to demonstrate the problem, which actually does *not* show up on my
PowerPC TQM5200 board.

Wolfgang.

[-- Attachment #2: example-rtheap.patch --]
[-- Type: text/x-diff, Size: 4702 bytes --]

---
 examples/native/Makefile |    4 -
 examples/native/rtheap.c |  164 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+), 1 deletion(-)

Index: xenomai-2.4.x/examples/native/rtheap.c
===================================================================
--- /dev/null
+++ xenomai-2.4.x/examples/native/rtheap.c
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/heap.h>
+
+#define USE_HEAP
+//#define USE_SIGXCPU
+
+#define HEAP_SIZE (1024*1024)
+#define HEAP_MODE 0		/* Local heap. */
+
+RT_HEAP heap_desc;
+RT_TASK demo_task;
+
+
+static int block_sizes[] = {16, 20, 90, 150, 310, 800, 1000};
+
+/* NOTE: error handling omitted. */
+
+void demo(void *arg)
+{
+	RTIME now, previous;
+	void *block;
+	int sizes = sizeof(block_sizes) / sizeof(int);
+	int count = 0;
+	int size, err;
+	int *ptr;
+
+#ifdef USE_SIGXCPU
+	/* Ask Xenomai to warn us upon switches to secondary mode. */
+	rt_task_set_mode(0, T_WARNSW, NULL);
+#endif
+
+	/*
+	 * Arguments: &task (NULL=self),
+	 *            start time,
+	 *            period (here: 1 s)
+	 */
+	rt_task_set_periodic(NULL, TM_NOW, 10000000);
+	previous = rt_timer_read();
+
+	while (1) {
+		rt_task_wait_period(NULL);
+		now = rt_timer_read();
+
+		size = block_sizes[count % sizes];
+#ifdef USE_HEAP
+		/*
+		 * Request a 16-bytes block, asking for a non-blocking call
+		 * since only Xenomai tasks may block.
+		 */
+		err = rt_heap_alloc(&heap_desc, size, TM_NONBLOCK, &block);
+		if (err) {
+			printf("rt_heap_alloc() failed with %d\n", err);
+			break;
+		}
+
+		ptr = (int *)block;
+		*ptr = 0xdeadbeef;
+		if (*ptr != 0xdeadbeef) {
+			printf("Write/read test to heap failed\n");
+			break;
+		}
+
+		ptr = (int *)(block + size - sizeof(int));
+		*ptr = 0xbeefface;
+		if (*ptr != 0xbeefface) {
+			printf("Write/read test to heap failed\n");
+			break;
+		}
+
+		/* Free the block: */
+		rt_heap_free(&heap_desc, block);
+#endif
+
+		/*
+		 * NOTE: printf may have unexpected impact on the timing of
+		 *       your program. It is used here in the critical loop
+		 *       only for demonstration purposes.
+		 */
+		if ((count % 100) == 9) {
+			rt_printf("%d: Time since last turn: %ld.%06ld ms\n",
+				  count,
+				  (long)(now - previous) / 1000000,
+				  (long)(now - previous) % 1000000);
+			previous = now;
+		}
+		count++;
+	}
+}
+
+void catch_signal(int sig)
+{
+	printf("%s: sig=%d\n", __func__, sig);
+}
+
+#ifdef USE_SIGXCPU
+void catch_signal_msw(int sig)
+{
+	void *bt[32];
+	int nentries;
+		
+	rt_printf("%s: sig=%d\n", __func__, sig);
+
+	/* Dump a backtrace of the frame which caused the switch to
+	   secondary mode: */
+	nentries = backtrace(bt,sizeof(bt) / sizeof(bt[0]));
+	backtrace_symbols_fd(bt,nentries,fileno(stdout));
+}
+#endif
+
+int main(int argc, char* argv[])
+{
+	void *block;
+	int err;
+
+	signal(SIGTERM, catch_signal);
+	signal(SIGINT, catch_signal);
+#ifdef USE_SIGXCPU
+	signal(SIGXCPU, catch_signal_msw);
+#endif
+
+	/* Avoids memory swapping for this program */
+	mlockall(MCL_CURRENT | MCL_FUTURE);
+
+	/*
+	 * Create a 256Kb heap usable for dynamic memory allocation of
+	 * variable-size blocks in kernel space.
+	 */
+
+	err = rt_heap_create(&heap_desc, "MyHeapName", HEAP_SIZE, HEAP_MODE);
+	if (err)
+		return err;
+
+	/* Perform auto-init of rt_print buffers if the task doesn't do so */
+	rt_print_auto_init(1);
+
+	/* Initialise the rt_print buffer for this task explicitly */
+	rt_print_init(4096, "Task 1");
+
+	/*
+	 * Arguments: &task,
+	 *            name,
+	 *            stack size (0=default),
+	 *            priority,
+	 *            mode (FPU, start suspended, ...)
+	 */
+	rt_task_create(&demo_task, "trivial", 0, 99, 0);
+
+	/*
+	 * Arguments: &task,
+	 *            task function,
+	 *            function argument
+	 */
+	rt_task_start(&demo_task, &demo, NULL);
+
+	pause();
+
+	rt_task_delete(&demo_task);
+}
Index: xenomai-2.4.x/examples/native/Makefile
===================================================================
--- xenomai-2.4.x.orig/examples/native/Makefile
+++ xenomai-2.4.x/examples/native/Makefile
@@ -1,7 +1,7 @@
 ###### CONFIGURATION ######
 
 ### List of applications to be build
-APPLICATIONS = trivial-periodic sigxcpu rtprint
+APPLICATIONS = trivial-periodic sigxcpu rtprint rtheap
 
 ### Note: to override the search path for the xeno-config script, use "make XENO=..."
 
@@ -54,6 +54,8 @@ endif
 rtprint: rtprint.c
 	$(CC) $(CFLAGS) $? $(LDFLAGS) -lrtdk -o $@
 
+rtheap: rtheap.c
+	$(CC) $(CFLAGS) $? $(LDFLAGS) -lrtdk -o $@
 
 
 ###### KERNEL MODULE BUILD (no change required normally) ######

^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: [Xenomai-help] Mode switch when using RT heap on ARM
@ 2008-11-11 11:24 Gilles Chanteperdrix
  0 siblings, 0 replies; 25+ messages in thread
From: Gilles Chanteperdrix @ 2008-11-11 11:24 UTC (permalink / raw)
  To: xenomai



Wolfgang Grandegger wrote:
> Gilles Chanteperdrix wrote:
>> Wolfgang Grandegger wrote:
>>> Gilles Chanteperdrix wrote:
>>>> Wolfgang Grandegger wrote:
>>>>> Gilles Chanteperdrix wrote:
>>>>>> Wolfgang Grandegger wrote:
>>>>>>> Hello,
>>>>>>>
>>>>>>> I realized that accessing memory allocated with rt_heap_alloc()
causes
>>>>>>> mode switches on ARM i.mx31. The attached patch provides a demo
program
>>>>>>> to demonstrate the problem, which actually does *not* show up on
my PowerPC TQM5200 board.
>>>>>> On ARM, we normally map the heaps uncacheable, this should not be
necessary on ARMv6, but I am afraid we then get the fault on first
access.
>>>>> Is each cache-line of the heap not touched automatically when the heap
>>>>> gets created? I thought it's necessary for other archs as well.
>>>> No, the thing which comes near to this is the workaround in I-pipe of
the
>>>> way pages are write-protected upon fork. But this happens only upon
fork.
>>>> I am not sure I understand all the subtleties of ARM memory
>>>> management,
>>>> but I think this fault on first write is the way the "dirty" bit is
implemented.
>>> Well, it seems not to be that simple. My attached rtheap example program
>>> behaves the following way:
>>>
>>> - Heap-mode=0: I see plenty of mode switches also for read-only:
>>
>> Maybe that is expected on ARM ? But what I do not understand is that
you get 300 modes switches where as your example makes two faults every
10ms during 10 seconds, so, you should see something like 1000 modes
switches.
>
> And even more because the program writes/reads at the beginning and end
of the buffer. I realized that as well. Not every read/write seems to
provoke a mode switch.

Maybe because when the heap returns the same page, if the fault really
happens on first write, you do not see the fault again.

>
>>>   # cat /proc/xenomai/stat ;sleep 10; cat /proc/xenomai/stat
>>>   CPU  PID    MSW        CSW        PF    STAT       %CPU  NAME
>>>     0  0      0          2951       0     00400080   99.7  ROOT 0  929
   102        398        3     00300184    0.0  rtheap 0  0      0
         23005      0     00000000    0.1  IRQ29:
>>> [timer]
>>>   CPU  PID    MSW        CSW        PF    STAT       %CPU  NAME
>>>     0  0      0          4287       0     00400080   99.4  ROOT 0  929
   435        1734       3     00300184    0.4  rtheap 0  0      0
         25010      0     00000000    0.1  IRQ29:
>>> [timer]
>>>
>>> - Heap-mode=H_NONCACHED: I see just 2 mode switches but the system
>>>   gets very slow:
>>
>> That is expected. But where do you get the 2 mode switches ?
>
> When the task writes to the heap memory for the first time. And I just
realized that the write/read to the end of the buffer makes real
trouble. The task seems to hang (or wait for something):
>
> -bash-3.2# cat sched
> CPU  PID    PRI      PERIOD     TIMEOUT    TIMEBASE  STAT       NAME
>   0  0       99      0          0          master    R          ROOT 0 
1114    99      100000000  0          master    X          rtheap
>
> At the same time the system gets slow.
>
> So far I understood from your comments that rtheap is not really usable
on ARM, right? What other option do I have?

No, I would have expected heap to be usable when non cachable, but to be
slow, that is just what I said.

-- 
                    Gilles.



-- 
                    Gilles.



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

end of thread, other threads:[~2008-11-17 13:41 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-10  9:58 [Xenomai-help] Mode switch when using RT heap on ARM Wolfgang Grandegger
2008-11-10 11:42 ` Gilles Chanteperdrix
2008-11-10 12:32   ` Wolfgang Grandegger
2008-11-10 12:35     ` Wolfgang Grandegger
     [not found]     ` <c54f288fee2b8a5ee68a00c27056c6ed.squirrel@domain.hid>
2008-11-10 18:55       ` Wolfgang Grandegger
2008-11-10 19:02         ` Gilles Chanteperdrix
2008-11-10 20:05           ` Wolfgang Grandegger
2008-11-11 22:46             ` Gilles Chanteperdrix
2008-11-12  8:55               ` Wolfgang Grandegger
2008-11-12  9:12                 ` Philippe Gerum
2008-11-12 10:24                   ` Gilles Chanteperdrix
2008-11-12 10:50                   ` Wolfgang Grandegger
2008-11-12 11:12                     ` Philippe Gerum
2008-11-12 11:20                       ` Wolfgang Grandegger
2008-11-13 17:57 ` Gilles Chanteperdrix
2008-11-13 18:27   ` Wolfgang Grandegger
2008-11-13 18:23     ` Gilles Chanteperdrix
2008-11-13 18:39       ` Wolfgang Grandegger
2008-11-13 18:15 ` Gilles Chanteperdrix
2008-11-13 20:15   ` Wolfgang Grandegger
2008-11-14  8:22     ` Gilles Chanteperdrix
2008-11-14  9:46       ` Wolfgang Grandegger
2008-11-14  9:45         ` Gilles Chanteperdrix
2008-11-17 13:41     ` Gilles Chanteperdrix
  -- strict thread matches above, loose matches on Subject: below --
2008-11-11 11:24 Gilles Chanteperdrix

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.