All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai] Memory paging trouble
@ 2014-07-16 11:23 Paal Tamas
  2014-07-16 11:29 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 12+ messages in thread
From: Paal Tamas @ 2014-07-16 11:23 UTC (permalink / raw)
  To: xenomai

Dear All, I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory paging problem inmy user mode app. I don't get any error message, only the contents of my memory buffer gets messed up. I try to describe what I see and what I suspect in as less words as possible: I allocate (using malloc) a buffer which is  more then 3 memory pages long (a page is 4096bytes in my case). I write a few bytes to the beginning, then a few bytes to the end, save the contents ina file. After that I fill the rest of the buffer from the beginning till the end and save the contents again into a file. I write unsigned int values into it starting with zero counting up to 3999.After this procedure the buffer should look like this (I indicate the memory page boundaries according to my test app): Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999 But the content of the buffer looks like this: Page1.0.833Page22882.3905Page3288
 2.3905Page42882.3905Page53906.3999 It seems that the second and third pages, which were not added to the virtual memory of the process in the first cycle (because I wrote data only into the address ranges of the first and  fourth pages then) are 'missing", and the content of the fourth page show up on the address range of the second and third page. I see this strange behaviour only if I allocate this buffer in a Xenomai thread. If I do the allocation in the main thread of the process (e.g. in the main() function) the memory will not be corrupt!If I compile the same source code to native Linux and running on the same hardware, on the same kernel, it works fine, no memory corruption can be seen this time either. I found the following workarounds:WA1.: Initialize the buffer from the beginning to the end in a linear fashion after allocation (e.g. writing the bytes one after the other, ensure to add the memory pages one afte the other to the process).WA2.: Use calloc() instead of mal
 loc() which is the same workaround as WA1 wa!
 s. I am struggling with this issue since a week. Please help me where to search for the problem. In Xenomai, in the Linux kernel or in the stdlib? One more strange thing that I am not sure if it has anything to do with this issue. I do not get any runtime error if I DON'T call mlockall()! Why is that? I read somewhere that some libraries call mlockall() during initialization. Is it true? Thank you,Tamas 

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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 11:23 [Xenomai] Memory paging trouble Paal Tamas
@ 2014-07-16 11:29 ` Gilles Chanteperdrix
  2014-07-16 11:39   ` Gilles Chanteperdrix
  2014-07-16 12:16   ` Paal Tamas
  0 siblings, 2 replies; 12+ messages in thread
From: Gilles Chanteperdrix @ 2014-07-16 11:29 UTC (permalink / raw)
  To: Paal Tamas, xenomai

On 07/16/2014 01:23 PM, Paal Tamas wrote:
> Dear All, I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel
> on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory
> paging problem inmy user mode app. I don't get any error message,
> only the contents of my memory buffer gets messed up. I try to
> describe what I see and what I suspect in as less words as possible:
> I allocate (using malloc) a buffer which is  more then 3 memory pages
> long (a page is 4096bytes in my case). I write a few bytes to the
> beginning, then a few bytes to the end, save the contents ina file.
> After that I fill the rest of the buffer from the beginning till the
> end and save the contents again into a file. I write unsigned int
> values into it starting with zero counting up to 3999.After this
> procedure the buffer should look like this (I indicate the memory
> page boundaries according to my test app):
> Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999
> But the content of the buffer looks like this:
> Page1.0.833Page22882.3905Page3288 2.3905Page42882.3905Page53906.3999
> It seems that the second and third pages, which were not added to the
> virtual memory of the process in the first cycle (because I wrote
> data only into the address ranges of the first and  fourth pages
> then) are 'missing", and the content of the fourth page show up
> on the address range of the second and third page. I see this strange
> behaviour only if I allocate this buffer in a Xenomai thread. If I do
> the allocation in the main thread of the process (e.g. in the main()
> function) the memory will not be corrupt!If I compile the same source
> code to native Linux and running on the same hardware, on the same
> kernel, it works fine, no memory corruption can be seen this time
> either. I found the following workarounds:WA1.: Initialize the buffer
> from the beginning to the end in a linear fashion after allocation
> (e.g. writing the bytes one after the other, ensure to add the memory
> pages one afte the other to the process).WA2.: Use calloc() instead
> of mal loc() which is the same workaround as WA1 wa! s. I am
> struggling with this issue since a week. Please help me where to
> search for the problem. In Xenomai, in the Linux kernel or in the
> stdlib? One more strange thing that I am not sure if it has anything
> to do with this issue. I do not get any runtime error if I DON'T
> call mlockall()! Why is that? I read somewhere that some libraries
> call mlockall() during initialization. Is it true? Thank you,Tamas 

Quite frankly, your mail is unreadable. Could you try and post a clear
and readable mail, preferably with a piece of code allowing to
reproduce the issue you meet?
-- 
                                                                Gilles.


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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 11:29 ` Gilles Chanteperdrix
@ 2014-07-16 11:39   ` Gilles Chanteperdrix
  2014-07-16 12:16   ` Paal Tamas
  1 sibling, 0 replies; 12+ messages in thread
From: Gilles Chanteperdrix @ 2014-07-16 11:39 UTC (permalink / raw)
  To: Paal Tamas, xenomai

On 07/16/2014 01:29 PM, Gilles Chanteperdrix wrote:
> On 07/16/2014 01:23 PM, Paal Tamas wrote:
>> Dear All, I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel
>> on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory
>> paging problem inmy user mode app. I don't get any error message,
>> only the contents of my memory buffer gets messed up. I try to
>> describe what I see and what I suspect in as less words as possible:
>> I allocate (using malloc) a buffer which is  more then 3 memory pages
>> long (a page is 4096bytes in my case). I write a few bytes to the
>> beginning, then a few bytes to the end, save the contents ina file.
>> After that I fill the rest of the buffer from the beginning till the
>> end and save the contents again into a file. I write unsigned int
>> values into it starting with zero counting up to 3999.After this
>> procedure the buffer should look like this (I indicate the memory
>> page boundaries according to my test app):
>> Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999
>> But the content of the buffer looks like this:
>> Page1.0.833Page22882.3905Page3288 2.3905Page42882.3905Page53906.3999
>> It seems that the second and third pages, which were not added to the
>> virtual memory of the process in the first cycle (because I wrote
>> data only into the address ranges of the first and  fourth pages
>> then) are 'missing", and the content of the fourth page show up
>> on the address range of the second and third page. I see this strange
>> behaviour only if I allocate this buffer in a Xenomai thread. If I do
>> the allocation in the main thread of the process (e.g. in the main()
>> function) the memory will not be corrupt!If I compile the same source
>> code to native Linux and running on the same hardware, on the same
>> kernel, it works fine, no memory corruption can be seen this time
>> either. I found the following workarounds:WA1.: Initialize the buffer
>> from the beginning to the end in a linear fashion after allocation
>> (e.g. writing the bytes one after the other, ensure to add the memory
>> pages one afte the other to the process).WA2.: Use calloc() instead
>> of mal loc() which is the same workaround as WA1 wa! s. I am
>> struggling with this issue since a week. Please help me where to
>> search for the problem. In Xenomai, in the Linux kernel or in the
>> stdlib? One more strange thing that I am not sure if it has anything
>> to do with this issue. I do not get any runtime error if I DON'T
>> call mlockall()! Why is that? I read somewhere that some libraries
>> call mlockall() during initialization. Is it true? Thank you,Tamas 
> 
> Quite frankly, your mail is unreadable. Could you try and post a clear
> and readable mail, preferably with a piece of code allowing to
> reproduce the issue you meet?
> 
(xenomai mailing list converts html mail, so, using html is useless).

-- 
                                                                Gilles.


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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 11:29 ` Gilles Chanteperdrix
  2014-07-16 11:39   ` Gilles Chanteperdrix
@ 2014-07-16 12:16   ` Paal Tamas
  2014-07-16 12:29     ` Gilles Chanteperdrix
  2014-07-16 12:30     ` Paal Tamas
  1 sibling, 2 replies; 12+ messages in thread
From: Paal Tamas @ 2014-07-16 12:16 UTC (permalink / raw)
  To: Gilles Chanteperdrix, xenomai

Gilles, Hopefully this time it will be better. You can find the test code at the end of the email.
 I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory paging problem inmy user mode app. I don&#39;t get any error message, only the contents of my memory buffer gets messed up. I try to describe what I see and what I suspect in as less words as possible: I allocate (using malloc) a buffer which is  more then 3 memory pages long (a page is 4096bytes in my case). I write a few bytes to the beginning, then a few bytes to the end, save the contents ina file. After that I fill the rest of the buffer from the beginning till the end and save the contents again into a file. I write unsigned int values into it starting with zero counting up to 3999.After this procedure the buffer should look like this (I indicate the memory page boundaries according to my test app): Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999 But the content of the buffer looks like this: Page1.0.833Page22882.3905Page32882.3905Page42882.3905Page53906.3999 It seems that the second and third pages, which were not added to the virtual memory of the process in the first cycle (because I wrote data only into the address ranges of the first and  fourth pages then) are &#39;missing", and the content of the fourth page show up on the address range of the second and third page. I see this strange behaviour only if I allocate this buffer in a Xenomai thread. If I do the allocation in the main thread of the process (e.g. in the main() function) the memory will not be corrupt!If I compile the same source code to native Linux and running on the same hardware, on the same kernel, it works fine, no memory corruption can be seen this time either. I found the following workarounds:WA1.: Initialize the buffer from the beginning to the end in a linear fashion after allocation (e.g. writing the bytes one after the other, ensure to add the memory pages one afte the other to the process).WA2.: Use calloc() instead of malloc() which is the same workaround as WA1 was. I am struggling with this issue since a week. Please help me where to search for the problem. In Xenomai, in the Linux kernel or in the stdlib? One more strange thing that I am not sure if it has anything to do with this issue. I do not get any runtime error if I DON&#39;T call mlockall()! Why is that? I read somewhere that some libraries call mlockall() during initialization. Is it true? Thank you,Tamas The code: #include <stdio.h>
#include <string.h>

#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

#include <sys/mman.h>

#define ALLOC_IN_THREAD
//#define ALLOC_IN_MAIN

#define MEMTEST_IN_THREAD
//#define MEMTEST_IN_MAIN

typedef unsigned int UInt32;
typedef unsigned char Bool;
typedef unsigned char UInt8;
#define TRUE 1
#define FALSE 0

static UInt32 *src_Src1;
static UInt32 src_Src1_maxSize,src_Src1_actualSize;
static UInt8 *src_Src2;
static UInt32 src_Src2_maxSize,src_Src2_actualSize;
static Bool src_Src3;

void printErrno(char *str)
{
   printf("%s: %d:%s\n",str,errno,strerror(errno));
}

void usecdelay(UInt32 time)
{
struct timespec delay;  // structure for providing timeout
   delay.tv_sec = time / (1000*1000); // sec
   delay.tv_nsec = (time % (1000*1000)) * 1000;
   nanosleep(&delay, NULL);
}

void FillArray(UInt32 pin_DestECount)
{
   UInt32 i;
   for(i=0; i<pin_DestECount;i++)
   {
     src_Src1[i] = i;      
   }
   src_Src1_actualSize=pin_DestECount;
   return;
}

void CopyArrayUInt32ToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
{
   if (pin_Enable) {

      if (pin_Offset >= src_Src2_maxSize) {
         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
         return;
      }
      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
      UInt8* pNext =&(src_Src2[pin_Offset]);
/*      *pNext=(UInt8)(src_Src1_actualSize&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>8)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>16)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>24)&0xFF); pNext++;
      *pNext=(UInt8)(src_Src1_maxSize&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>8)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>16)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>24)&0xFF); pNext++;
      writableSize-=8;*/
      UInt32 i;
      for(i=0;i<src_Src1_actualSize;i++)
      {
         *pNext=(UInt8)(*((UInt32*)(&src_Src1[i]))&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>8)&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>16)&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>24)&0xFF); pNext++;
         writableSize-=4;
      }
      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
          src_Src2_actualSize=src_Src2_maxSize-writableSize;
      }
   }
   return;
}

void CopyBoolToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
{
   if (pin_Enable) {

      if (pin_Offset >= src_Src2_maxSize) {
         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
         return;
      }
      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
      UInt8* pNext =&(src_Src2[pin_Offset]);
      *pNext=(UInt8)src_Src3; pNext++;
      writableSize--;
      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
          src_Src2_actualSize=src_Src2_maxSize-writableSize;
      }
   }
   return;
}

static UInt32 cycle=0;
void body()
{
FILE *fp;
   src_Src2_actualSize=0;
   CopyArrayUInt32ToU8aBody(TRUE, 0);

   fp=fopen("testdata.txt","at");
   fprintf(fp,"After write from the beginning of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle);
   UInt32 i;
   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
   fclose(fp);

   CopyBoolToU8aBody(TRUE, 16008);

   fp=fopen("testdata.txt","at");
   fprintf(fp,"After write to the end of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle);
   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
   fclose(fp);

   cycle++;

}

Bool terminateThread=FALSE;
Bool threadTerminated=FALSE;

static void *LinuxThreadFunc(void *ptr)
{
UInt32 cntr=0;
   printf("-- thread1: is running\n");
#ifdef ALLOC_IN_THREAD
   printf("Allocating the buffers in the thread.\n");
//      src_Src1=(UInt32*)new UInt32[2000];
printf("malloc1...\n");
usecdelay(10000);
      src_Src1=(UInt32*)malloc(4000*sizeof(UInt32));
usecdelay(10000);
printf("...ok\n");
usecdelay(10000);

//      src_Src1=(UInt32*)calloc(2000*8,1);
      src_Src1_maxSize=4000;src_Src1_actualSize=0;
//      src_Src2=(UInt8*) new UInt8[16013l];
printf("malloc2...\n");
usecdelay(10000);
      src_Src2=(UInt8*) malloc(16013l);
usecdelay(10000);
printf("...ok\n");
usecdelay(10000);
//      src_Src2=(UInt8*) calloc(16013l,1);
      src_Src2_maxSize=16013l;src_Src2_actualSize=0;
#endif
   while(!terminateThread)
   {
#ifdef MEMTEST_IN_THREAD     
      if(cntr==1) FillArray(src_Src1_maxSize);
      printf("-- thread1: cycle:%d test\n",cntr);
      body();
#else
      printf("-- thread1: cycle:%d empty\n",cntr);
#endif
      usecdelay(500000);
      cntr++;
   }
   threadTerminated=TRUE;
}


//--------------------------------------------------------------
int main (int argc, char* argv[])
{
int ret;
pthread_attr_t threadAttr;
pthread_t thread=0;  // thread identifier
FILE *fp;
UInt32 cntr=0;
    ret=mlockall(MCL_CURRENT | MCL_FUTURE);
   printf("mlockall returned %d\n",ret);

   fp=fopen("testdata.txt","wt");
   fprintf(fp,"Xenomai memory allocation issue test.\n");
   fclose(fp);

#ifdef ALLOC_IN_MAIN
   printf("Allocating the buffers in main()\n");
//      src_Src1=(UInt32*)new UInt32[2000];
   src_Src1=(UInt32*)malloc(4000*4);
   src_Src1_maxSize=2000;src_Src1_actualSize=0;
//      src_Src2=(UInt8*) new UInt8[16013l];
   src_Src2=(UInt8*) malloc(16013l);
   src_Src2_maxSize=16013l;src_Src2_actualSize=0;
#endif

   printf("- Create a new thread (thread1)\n");
 // initialize the thread attribute
   if(pthread_attr_init(&threadAttr)!=0)
   {
      printErrno("Thread(): pthread_attr_init() error :");
      return -1;
   }
// Set thread to detached state. No need for pthread_join
   if(pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED)!=0)
   {
      printErrno("Thread(): pthread_attr_setdetachstate() error :");
      pthread_attr_destroy(&threadAttr);
      return -2;
   }
// Create the thread
   if(pthread_create(&thread, &threadAttr, LinuxThreadFunc, 0)!=0)
   {
      printErrno("Thread(): pthread_create() error :");
      pthread_attr_destroy(&threadAttr);
      return -3;
   }
// Destroy the thread attributes
   if(pthread_attr_destroy(&threadAttr)!=0)
   {
      printErrno("Thread(): pthread_attr_destroy() error :");
      return -4;
   }
   printf("- Thread create OK (thread1)\n");
   UInt32 i;
   for(i=0;i<3;i++)
   {
#ifdef MEMTEST_IN_MAIN   
      if(cntr==1) FillArray(src_Src1_maxSize);
      body();
      printf("main loop is testing.\n");
#else
      printf("main loop is empty.\n");
#endif
      usecdelay(500000);
      cntr++;
   }

   terminateThread=TRUE;
   printf("- Wait for the thread (thread1) to exit\n");
   do
   {
      usecdelay(10000);
   }while(!threadTerminated);
   printf("- Thread1 terminated\n");
   free(src_Src2);
   free(src_Src1);
//   delete[] src_Src2;
//   delete[] src_Src1;
end:
   return 0;
}
 
Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>On 07/16/2014 01:23 PM, Paal Tamas wrote:
>> Dear All, I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel
>> on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory
>> paging problem inmy user mode app. I don&#39;t get any error message,
>> only the contents of my memory buffer gets messed up. I try to
>> describe what I see and what I suspect in as less words as possible:
>> I allocate (using malloc) a buffer which is  more then 3 memory pages
>> long (a page is 4096bytes in my case). I write a few bytes to the
>> beginning, then a few bytes to the end, save the contents ina file.
>> After that I fill the rest of the buffer from the beginning till the
>> end and save the contents again into a file. I write unsigned int
>> values into it starting with zero counting up to 3999.After this
>> procedure the buffer should look like this (I indicate the memory
>> page boundaries according to my test app):
>> Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999
>> But the content of the buffer looks like this:
>> Page1.0.833Page22882.3905Page3288 2.3905Page42882.3905Page53906.3999
>> It seems that the second and third pages, which were not added to the
>> virtual memory of the process in the first cycle (because I wrote
>> data only into the address ranges of the first and  fourth pages
>> then) are &#39;missing", and the content of the fourth page show up
>> on the address range of the second and third page. I see this strange
>> behaviour only if I allocate this buffer in a Xenomai thread. If I do
>> the allocation in the main thread of the process (e.g. in the main()
>> function) the memory will not be corrupt!If I compile the same source
>> code to native Linux and running on the same hardware, on the same
>> kernel, it works fine, no memory corruption can be seen this time
>> either. I found the following workarounds:WA1.: Initialize the buffer
>> from the beginning to the end in a linear fashion after allocation
>> (e.g. writing the bytes one after the other, ensure to add the memory
>> pages one afte the other to the process).WA2.: Use calloc() instead
>> of mal loc() which is the same workaround as WA1 wa! s. I am
>> struggling with this issue since a week. Please help me where to
>> search for the problem. In Xenomai, in the Linux kernel or in the
>> stdlib? One more strange thing that I am not sure if it has anything
>> to do with this issue. I do not get any runtime error if I DON&#39;T
>> call mlockall()! Why is that? I read somewhere that some libraries
>> call mlockall() during initialization. Is it true? Thank you,Tamas 
>
>Quite frankly, your mail is unreadable. Could you try and post a clear
>and readable mail, preferably with a piece of code allowing to
>reproduce the issue you meet?
>-- 
>                                                                Gilles.

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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 12:16   ` Paal Tamas
@ 2014-07-16 12:29     ` Gilles Chanteperdrix
  2014-07-16 12:30     ` Paal Tamas
  1 sibling, 0 replies; 12+ messages in thread
From: Gilles Chanteperdrix @ 2014-07-16 12:29 UTC (permalink / raw)
  To: Paal Tamas, xenomai

On 07/16/2014 02:16 PM, Paal Tamas wrote:
> Gilles, Hopefully this time it will be better.

No, it is not, see:
http://www.xenomai.org/pipermail/xenomai/2014-July/031316.html

Please send a plain text mail.


-- 
                                                                Gilles.


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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 12:16   ` Paal Tamas
  2014-07-16 12:29     ` Gilles Chanteperdrix
@ 2014-07-16 12:30     ` Paal Tamas
  2014-07-16 12:42       ` Paal Tamas
  1 sibling, 1 reply; 12+ messages in thread
From: Paal Tamas @ 2014-07-16 12:30 UTC (permalink / raw)
  To: xenomai

One more try: Gilles, Hopefully this time it will be better.Besides, I attached the test app source too. I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware. I am using the Posix skin.
I have a memory paging problem inmy user mode app. I don&#39;t get any error message, only the contents of my memory buffer gets messed up. I try to describe what I see and what I suspect in as less words as possible:I allocate (using malloc) a buffer which is  more then 3 memory pages long (a page is 4096bytes in my case). I write a few bytes to the beginning, then a few bytes to the end, save the contents ina file. After that I fill the rest of the buffer from the beginning till the end and save the contents again into a file. I write unsigned int values into it starting with zero counting up to 3999.
After this procedure the buffer should look like this (I indicate the memory page boundaries according to my test app):Page1
.
0
.
833
Page2
834
.
1857
Page3
1858
.
2881
Page4
2882
.
3905
Page5
3906
.
3999But the content of the buffer looks like this:Page1
.
0
.
833
Page2
2882
.
3905
Page3
2882
.
3905
Page4
2882
.
3905
Page5
3906
.
3999 It seems that the second and third pages, which were not added to the virtual memory of the process in the first cycle (because I wrote data only into the address ranges of the first and  fourth pages then) are &#39;missing", and the content of the fourth page show up on the address range of the second and third page.I see this strange behaviour only if I allocate this buffer in a Xenomai thread. If I do the allocation in the main thread of the process (e.g. in the main() function) the memory will not be corrupt!
If I compile the same source code to native Linux and running on the same hardware, on the same kernel, it works fine, no memory corruption can be seen this time either.  I found the following workarounds:
WA1.: Initialize the buffer from the beginning to the end in a linear fashion after allocation (e.g. writing the bytes one after the other, ensure to add the memory pages one afte the other to the process).
WA2.: Use calloc() instead of malloc() which is the same workaround as WA1 was.I am struggling with this issue since a week. Please help me where to search for the problem. In Xenomai, in the Linux kernel or in the stdlib? One more strange thing that I am not sure if it has anything to do with this issue. I do not get any runtime error if I DON&#39;T call mlockall()! Why is that? I read somewhere that some libraries call mlockall() during initialization. Is it true? Thank you,
Tamas  The code: #include <stdio.h>
#include <string.h>

#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

#include <sys/mman.h>

#define ALLOC_IN_THREAD
//#define ALLOC_IN_MAIN

#define MEMTEST_IN_THREAD
//#define MEMTEST_IN_MAIN

typedef unsigned int UInt32;
typedef unsigned char Bool;
typedef unsigned char UInt8;
#define TRUE 1
#define FALSE 0

static UInt32 *src_Src1;
static UInt32 src_Src1_maxSize,src_Src1_actualSize;
static UInt8 *src_Src2;
static UInt32 src_Src2_maxSize,src_Src2_actualSize;
static Bool src_Src3;

void printErrno(char *str)
{
   printf("%s: %d:%s\n",str,errno,strerror(errno));
}

void usecdelay(UInt32 time)
{
struct timespec delay;  // structure for providing timeout
   delay.tv_sec = time / (1000*1000); // sec
   delay.tv_nsec = (time % (1000*1000)) * 1000;
   nanosleep(&delay, NULL);
}

void FillArray(UInt32 pin_DestECount)
{
   UInt32 i;
   for(i=0; i<pin_DestECount;i++)
   {
     src_Src1[i] = i;      
   }
   src_Src1_actualSize=pin_DestECount;
   return;
}

void CopyArrayUInt32ToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
{
   if (pin_Enable) {

      if (pin_Offset >= src_Src2_maxSize) {
         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
         return;
      }
      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
      UInt8* pNext =&(src_Src2[pin_Offset]);
/*      *pNext=(UInt8)(src_Src1_actualSize&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>8)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>16)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>24)&0xFF); pNext++;
      *pNext=(UInt8)(src_Src1_maxSize&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>8)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>16)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>24)&0xFF); pNext++;
      writableSize-=8;*/
      UInt32 i;
      for(i=0;i<src_Src1_actualSize;i++)
      {
         *pNext=(UInt8)(*((UInt32*)(&src_Src1[i]))&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>8)&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>16)&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>24)&0xFF); pNext++;
         writableSize-=4;
      }
      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
          src_Src2_actualSize=src_Src2_maxSize-writableSize;
      }
   }
   return;
}

void CopyBoolToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
{
   if (pin_Enable) {

      if (pin_Offset >= src_Src2_maxSize) {
         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
         return;
      }
      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
      UInt8* pNext =&(src_Src2[pin_Offset]);
      *pNext=(UInt8)src_Src3; pNext++;
      writableSize--;
      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
          src_Src2_actualSize=src_Src2_maxSize-writableSize;
      }
   }
   return;
}

static UInt32 cycle=0;
void body()
{
FILE *fp;
   src_Src2_actualSize=0;
   CopyArrayUInt32ToU8aBody(TRUE, 0);

   fp=fopen("testdata.txt","at");
   fprintf(fp,"After write from the beginning of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle);
   UInt32 i;
   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
   fclose(fp);

   CopyBoolToU8aBody(TRUE, 16008);

   fp=fopen("testdata.txt","at");
   fprintf(fp,"After write to the end of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle);
   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
   fclose(fp);

   cycle++;

}

Bool terminateThread=FALSE;
Bool threadTerminated=FALSE;

static void *LinuxThreadFunc(void *ptr)
{
UInt32 cntr=0;
   printf("-- thread1: is running\n");
#ifdef ALLOC_IN_THREAD
   printf("Allocating the buffers in the thread.\n");
//      src_Src1=(UInt32*)new UInt32[2000];
printf("malloc1...\n");
usecdelay(10000);
      src_Src1=(UInt32*)malloc(4000*sizeof(UInt32));
usecdelay(10000);
printf("...ok\n");
usecdelay(10000);

//      src_Src1=(UInt32*)calloc(2000*8,1);
      src_Src1_maxSize=4000;src_Src1_actualSize=0;
//      src_Src2=(UInt8*) new UInt8[16013l];
printf("malloc2...\n");
usecdelay(10000);
      src_Src2=(UInt8*) malloc(16013l);
usecdelay(10000);
printf("...ok\n");
usecdelay(10000);
//      src_Src2=(UInt8*) calloc(16013l,1);
      src_Src2_maxSize=16013l;src_Src2_actualSize=0;
#endif
   while(!terminateThread)
   {
#ifdef MEMTEST_IN_THREAD     
      if(cntr==1) FillArray(src_Src1_maxSize);
      printf("-- thread1: cycle:%d test\n",cntr);
      body();
#else
      printf("-- thread1: cycle:%d empty\n",cntr);
#endif
      usecdelay(500000);
      cntr++;
   }
   threadTerminated=TRUE;
}


//--------------------------------------------------------------
int main (int argc, char* argv[])
{
int ret;
pthread_attr_t threadAttr;
pthread_t thread=0;  // thread identifier
FILE *fp;
UInt32 cntr=0;
    ret=mlockall(MCL_CURRENT | MCL_FUTURE);
   printf("mlockall returned %d\n",ret);

   fp=fopen("testdata.txt","wt");
   fprintf(fp,"Xenomai memory allocation issue test.\n");
   fclose(fp);

#ifdef ALLOC_IN_MAIN
   printf("Allocating the buffers in main()\n");
//      src_Src1=(UInt32*)new UInt32[2000];
   src_Src1=(UInt32*)malloc(4000*4);
   src_Src1_maxSize=2000;src_Src1_actualSize=0;
//      src_Src2=(UInt8*) new UInt8[16013l];
   src_Src2=(UInt8*) malloc(16013l);
   src_Src2_maxSize=16013l;src_Src2_actualSize=0;
#endif

   printf("- Create a new thread (thread1)\n");
 // initialize the thread attribute
   if(pthread_attr_init(&threadAttr)!=0)
   {
      printErrno("Thread(): pthread_attr_init() error :");
      return -1;
   }
// Set thread to detached state. No need for pthread_join
   if(pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED)!=0)
   {
      printErrno("Thread(): pthread_attr_setdetachstate() error :");
      pthread_attr_destroy(&threadAttr);
      return -2;
   }
// Create the thread
   if(pthread_create(&thread, &threadAttr, LinuxThreadFunc, 0)!=0)
   {
      printErrno("Thread(): pthread_create() error :");
      pthread_attr_destroy(&threadAttr);
      return -3;
   }
// Destroy the thread attributes
   if(pthread_attr_destroy(&threadAttr)!=0)
   {
      printErrno("Thread(): pthread_attr_destroy() error :");
      return -4;
   }
   printf("- Thread create OK (thread1)\n");
   UInt32 i;
   for(i=0;i<3;i++)
   {
#ifdef MEMTEST_IN_MAIN   
      if(cntr==1) FillArray(src_Src1_maxSize);
      body();
      printf("main loop is testing.\n");
#else
      printf("main loop is empty.\n");
#endif
      usecdelay(500000);
      cntr++;
   }

   terminateThread=TRUE;
   printf("- Wait for the thread (thread1) to exit\n");
   do
   {
      usecdelay(10000);
   }while(!threadTerminated);
   printf("- Thread1 terminated\n");
   free(src_Src2);
   free(src_Src1);
//   delete[] src_Src2;
//   delete[] src_Src1;
end:
   return 0;
}
 
Paal Tamas <paal_to@freemail.hu> írta:
>Gilles, Hopefully this time it will be better. You can find the test code at the end of the email.
> I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory paging problem inmy user mode app. I don&#39;t get any error message, only the contents of my memory buffer gets messed up. I try to describe what I see and what I suspect in as less words as possible: I allocate (using malloc) a buffer which is  more then 3 memory pages long (a page is 4096bytes in my case). I write a few bytes to the beginning, then a few bytes to the end, save the contents ina file. After that I fill the rest of the buffer from the beginning till the end and save the contents again into a file. I write unsigned int values into it starting with zero counting up to 3999.After this procedure the buffer should look like this (I indicate the memory page boundaries according to my test app): Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999 But the content of the buffer looks like this: Page1.0.833Page22882.3905Page32882.3905Page42882.3905Page53906.3999 It seems that the second and third pages, which were not added to the virtual memory of the process in the first cycle (because I wrote data only into the address ranges of the first and  fourth pages then) are &#39;missing", and the content of the fourth page show up on the address range of the second and third page. I see this strange behaviour only if I allocate this buffer in a Xenomai thread. If I do the allocation in the main thread of the process (e.g. in the main() function) the memory will not be corrupt!If I compile the same source code to native Linux and running on the same hardware, on the same kernel, it works fine, no memory corruption can be seen this time either. I found the following workarounds:WA1.: Initialize the buffer from the beginning to the end in a linear fashion after allocation (e.g. writing the bytes one after the other, ensure to add the memory pages one afte the other to the process).WA2.: Use calloc() instead of malloc() which is the same workaround as WA1 was. I am struggling with this issue since a week. Please help me where to search for the problem. In Xenomai, in the Linux kernel or in the stdlib? One more strange thing that I am not sure if it has anything to do with this issue. I do not get any runtime error if I DON&#39;T call mlockall()! Why is that? I read somewhere that some libraries call mlockall() during initialization. Is it true? Thank you,Tamas The code: #include <stdio.h>
>#include <string.h>
>
>#include <errno.h>
>#include <stdlib.h>
>#include <time.h>
>#include <pthread.h>
>
>#include <sys/mman.h>
>
>#define ALLOC_IN_THREAD
>//#define ALLOC_IN_MAIN
>
>#define MEMTEST_IN_THREAD
>//#define MEMTEST_IN_MAIN
>
>typedef unsigned int UInt32;
>typedef unsigned char Bool;
>typedef unsigned char UInt8;
>#define TRUE 1
>#define FALSE 0
>
>static UInt32 *src_Src1;
>static UInt32 src_Src1_maxSize,src_Src1_actualSize;
>static UInt8 *src_Src2;
>static UInt32 src_Src2_maxSize,src_Src2_actualSize;
>static Bool src_Src3;
>
>void printErrno(char *str)
>{
>   printf("%s: %d:%s\n",str,errno,strerror(errno));
>}
>
>void usecdelay(UInt32 time)
>{
>struct timespec delay;  // structure for providing timeout
>   delay.tv_sec = time / (1000*1000); // sec
>   delay.tv_nsec = (time % (1000*1000)) * 1000;
>   nanosleep(&delay, NULL);
>}
>
>void FillArray(UInt32 pin_DestECount)
>{
>   UInt32 i;
>   for(i=0; i<pin_DestECount;i++)
>   {
>     src_Src1[i] = i;      
>   }
>   src_Src1_actualSize=pin_DestECount;
>   return;
>}
>
>void CopyArrayUInt32ToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
>{
>   if (pin_Enable) {
>
>      if (pin_Offset >= src_Src2_maxSize) {
>         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
>         return;
>      }
>      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
>      UInt8* pNext =&(src_Src2[pin_Offset]);
>/*      *pNext=(UInt8)(src_Src1_actualSize&0xFF); pNext++;
>      *pNext=(UInt8)((src_Src1_actualSize>>8)&0xFF); pNext++;
>      *pNext=(UInt8)((src_Src1_actualSize>>16)&0xFF); pNext++;
>      *pNext=(UInt8)((src_Src1_actualSize>>24)&0xFF); pNext++;
>      *pNext=(UInt8)(src_Src1_maxSize&0xFF); pNext++;
>      *pNext=(UInt8)((src_Src1_maxSize>>8)&0xFF); pNext++;
>      *pNext=(UInt8)((src_Src1_maxSize>>16)&0xFF); pNext++;
>      *pNext=(UInt8)((src_Src1_maxSize>>24)&0xFF); pNext++;
>      writableSize-=8;*/
>      UInt32 i;
>      for(i=0;i<src_Src1_actualSize;i++)
>      {
>         *pNext=(UInt8)(*((UInt32*)(&src_Src1[i]))&0xFF); pNext++;
>         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>8)&0xFF); pNext++;
>         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>16)&0xFF); pNext++;
>         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>24)&0xFF); pNext++;
>         writableSize-=4;
>      }
>      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
>          src_Src2_actualSize=src_Src2_maxSize-writableSize;
>      }
>   }
>   return;
>}
>
>void CopyBoolToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
>{
>   if (pin_Enable) {
>
>      if (pin_Offset >= src_Src2_maxSize) {
>         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
>         return;
>      }
>      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
>      UInt8* pNext =&(src_Src2[pin_Offset]);
>      *pNext=(UInt8)src_Src3; pNext++;
>      writableSize--;
>      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
>          src_Src2_actualSize=src_Src2_maxSize-writableSize;
>      }
>   }
>   return;
>}
>
>static UInt32 cycle=0;
>void body()
>{
>FILE *fp;
>   src_Src2_actualSize=0;
>   CopyArrayUInt32ToU8aBody(TRUE, 0);
>
>   fp=fopen("testdata.txt","at");
>   fprintf(fp,"After write from the beginning of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle);
>   UInt32 i;
>   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
>   fclose(fp);
>
>   CopyBoolToU8aBody(TRUE, 16008);
>
>   fp=fopen("testdata.txt","at");
>   fprintf(fp,"After write to the end of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle);
>   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
>   fclose(fp);
>
>   cycle++;
>
>}
>
>Bool terminateThread=FALSE;
>Bool threadTerminated=FALSE;
>
>static void *LinuxThreadFunc(void *ptr)
>{
>UInt32 cntr=0;
>   printf("-- thread1: is running\n");
>#ifdef ALLOC_IN_THREAD
>   printf("Allocating the buffers in the thread.\n");
>//      src_Src1=(UInt32*)new UInt32[2000];
>printf("malloc1...\n");
>usecdelay(10000);
>      src_Src1=(UInt32*)malloc(4000*sizeof(UInt32));
>usecdelay(10000);
>printf("...ok\n");
>usecdelay(10000);
>
>//      src_Src1=(UInt32*)calloc(2000*8,1);
>      src_Src1_maxSize=4000;src_Src1_actualSize=0;
>//      src_Src2=(UInt8*) new UInt8[16013l];
>printf("malloc2...\n");
>usecdelay(10000);
>      src_Src2=(UInt8*) malloc(16013l);
>usecdelay(10000);
>printf("...ok\n");
>usecdelay(10000);
>//      src_Src2=(UInt8*) calloc(16013l,1);
>      src_Src2_maxSize=16013l;src_Src2_actualSize=0;
>#endif
>   while(!terminateThread)
>   {
>#ifdef MEMTEST_IN_THREAD     
>      if(cntr==1) FillArray(src_Src1_maxSize);
>      printf("-- thread1: cycle:%d test\n",cntr);
>      body();
>#else
>      printf("-- thread1: cycle:%d empty\n",cntr);
>#endif
>      usecdelay(500000);
>      cntr++;
>   }
>   threadTerminated=TRUE;
>}
>
>
>//--------------------------------------------------------------
>int main (int argc, char* argv[])
>{
>int ret;
>pthread_attr_t threadAttr;
>pthread_t thread=0;  // thread identifier
>FILE *fp;
>UInt32 cntr=0;
>    ret=mlockall(MCL_CURRENT | MCL_FUTURE);
>   printf("mlockall returned %d\n",ret);
>
>   fp=fopen("testdata.txt","wt");
>   fprintf(fp,"Xenomai memory allocation issue test.\n");
>   fclose(fp);
>
>#ifdef ALLOC_IN_MAIN
>   printf("Allocating the buffers in main()\n");
>//      src_Src1=(UInt32*)new UInt32[2000];
>   src_Src1=(UInt32*)malloc(4000*4);
>   src_Src1_maxSize=2000;src_Src1_actualSize=0;
>//      src_Src2=(UInt8*) new UInt8[16013l];
>   src_Src2=(UInt8*) malloc(16013l);
>   src_Src2_maxSize=16013l;src_Src2_actualSize=0;
>#endif
>
>   printf("- Create a new thread (thread1)\n");
> // initialize the thread attribute
>   if(pthread_attr_init(&threadAttr)!=0)
>   {
>      printErrno("Thread(): pthread_attr_init() error :");
>      return -1;
>   }
>// Set thread to detached state. No need for pthread_join
>   if(pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED)!=0)
>   {
>      printErrno("Thread(): pthread_attr_setdetachstate() error :");
>      pthread_attr_destroy(&threadAttr);
>      return -2;
>   }
>// Create the thread
>   if(pthread_create(&thread, &threadAttr, LinuxThreadFunc, 0)!=0)
>   {
>      printErrno("Thread(): pthread_create() error :");
>      pthread_attr_destroy(&threadAttr);
>      return -3;
>   }
>// Destroy the thread attributes
>   if(pthread_attr_destroy(&threadAttr)!=0)
>   {
>      printErrno("Thread(): pthread_attr_destroy() error :");
>      return -4;
>   }
>   printf("- Thread create OK (thread1)\n");
>   UInt32 i;
>   for(i=0;i<3;i++)
>   {
>#ifdef MEMTEST_IN_MAIN   
>      if(cntr==1) FillArray(src_Src1_maxSize);
>      body();
>      printf("main loop is testing.\n");
>#else
>      printf("main loop is empty.\n");
>#endif
>      usecdelay(500000);
>      cntr++;
>   }
>
>   terminateThread=TRUE;
>   printf("- Wait for the thread (thread1) to exit\n");
>   do
>   {
>      usecdelay(10000);
>   }while(!threadTerminated);
>   printf("- Thread1 terminated\n");
>   free(src_Src2);
>   free(src_Src1);
>//   delete[] src_Src2;
>//   delete[] src_Src1;
>end:
>   return 0;
>}
> 
>Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>>On 07/16/2014 01:23 PM, Paal Tamas wrote:
>>> Dear All, I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel
>>> on an i.MX6 ARM hardware. I am using the Posix skin.I have a memory
>>> paging problem inmy user mode app. I don&#39;t get any error message,
>>> only the contents of my memory buffer gets messed up. I try to
>>> describe what I see and what I suspect in as less words as possible:
>>> I allocate (using malloc) a buffer which is  more then 3 memory pages
>>> long (a page is 4096bytes in my case). I write a few bytes to the
>>> beginning, then a few bytes to the end, save the contents ina file.
>>> After that I fill the rest of the buffer from the beginning till the
>>> end and save the contents again into a file. I write unsigned int
>>> values into it starting with zero counting up to 3999.After this
>>> procedure the buffer should look like this (I indicate the memory
>>> page boundaries according to my test app):
>>> Page1.0.833Page2834.1857Page31858.2881Page42882.3905Page53906.3999
>>> But the content of the buffer looks like this:
>>> Page1.0.833Page22882.3905Page3288 2.3905Page42882.3905Page53906.3999
>>> It seems that the second and third pages, which were not added to the
>>> virtual memory of the process in the first cycle (because I wrote
>>> data only into the address ranges of the first and  fourth pages
>>> then) are &#39;missing", and the content of the fourth page show up
>>> on the address range of the second and third page. I see this strange
>>> behaviour only if I allocate this buffer in a Xenomai thread. If I do
>>> the allocation in the main thread of the process (e.g. in the main()
>>> function) the memory will not be corrupt!If I compile the same source
>>> code to native Linux and running on the same hardware, on the same
>>> kernel, it works fine, no memory corruption can be seen this time
>>> either. I found the following workarounds:WA1.: Initialize the buffer
>>> from the beginning to the end in a linear fashion after allocation
>>> (e.g. writing the bytes one after the other, ensure to add the memory
>>> pages one afte the other to the process).WA2.: Use calloc() instead
>>> of mal loc() which is the same workaround as WA1 wa! s. I am
>>> struggling with this issue since a week. Please help me where to
>>> search for the problem. In Xenomai, in the Linux kernel or in the
>>> stdlib? One more strange thing that I am not sure if it has anything
>>> to do with this issue. I do not get any runtime error if I DON&#39;T
>>> call mlockall()! Why is that? I read somewhere that some libraries
>>> call mlockall() during initialization. Is it true? Thank you,Tamas 
>>
>>Quite frankly, your mail is unreadable. Could you try and post a clear
>>and readable mail, preferably with a piece of code allowing to
>>reproduce the issue you meet?
>>-- 
>>                                                                Gilles.
>_______________________________________________
>Xenomai mailing list
>Xenomai@xenomai.org
>http://www.xenomai.org/mailman/listinfo/xenomai

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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 12:30     ` Paal Tamas
@ 2014-07-16 12:42       ` Paal Tamas
  2014-07-17 20:25         ` Gilles Chanteperdrix
  0 siblings, 1 reply; 12+ messages in thread
From: Paal Tamas @ 2014-07-16 12:42 UTC (permalink / raw)
  To: xenomai

I keep on trying:

Gilles,

Hopefully this time it will be better.

Besides, you can find the test app sourcecode at the end.

I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware. I am using the Posix skin.
I have a memory paging problem inmy user mode app. I don't get any error message, only the contents of my memory buffer gets messed up. I try to describe what I see and what I suspect in as less words as possible:

I allocate (using malloc) a buffer which is  more then 3 memory pages long (a page is 4096bytes in my case). I write a few bytes to the beginning, then a few bytes to the end, save the contents ina file. After that I fill the rest of the buffer from the beginning till the end and save the contents again into a file. I write unsigned int values into it starting with zero counting up to 3999.
After this procedure the buffer should look like this (I indicate the memory page boundaries according to my test app):

Page1
.
0
.
833
Page2
834
.
1857
Page3
1858
.
2881
Page4
2882
.
3905
Page5
3906
.
3999

But the content of the buffer looks like this:

Page1
.
0
.
833
Page2
2882
.
3905
Page3
2882
.
3905
Page4
2882
.
3905
Page5
3906
.
3999

It seems that the second and third pages, which were not added to the virtual memory of the process in the first cycle (because I wrote data only into the address ranges of the first and  fourth pages then) are 'missing", and the content of the fourth page show up on the address range of the second and third page.

I see this strange behaviour only if I allocate this buffer in a Xenomai thread. If I do the allocation in the main thread of the process (e.g. in the main() function) the memory will not be corrupt!
If I compile the same source code to native Linux and running on the same hardware, on the same kernel, it works fine, no memory corruption can be seen this time either.

I found the following workarounds:
WA1.: Initialize the buffer from the beginning to the end in a linear fashion after allocation (e.g. writing the bytes one after the other, ensure to add the memory pages one afte the other to the process).
WA2.: Use calloc() instead of malloc() which is the same workaround as WA1 was.

I am struggling with this issue since a week. Please help me where to search for the problem. In Xenomai, in the Linux kernel or in the stdlib?

One more strange thing that I am not sure if it has anything to do with this issue. I do not get any runtime error if I DON'T call mlockall()! Why is that? I read somewhere that some libraries call mlockall() during initialization. Is it true?

Thank you,
Tamas

The code: 

#include <stdio.h>
#include <string.h>

#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

#include <sys/mman.h>

#define ALLOC_IN_THREAD
//#define ALLOC_IN_MAIN

#define MEMTEST_IN_THREAD
//#define MEMTEST_IN_MAIN

typedef unsigned int UInt32;
typedef unsigned char Bool;
typedef unsigned char UInt8;
#define TRUE 1
#define FALSE 0

static UInt32 *src_Src1;
static UInt32 src_Src1_maxSize,src_Src1_actualSize;
static UInt8 *src_Src2;
static UInt32 src_Src2_maxSize,src_Src2_actualSize;
static Bool src_Src3;

void printErrno(char *str)
{
   printf("%s: %d:%s\n",str,errno,strerror(errno));
}

void usecdelay(UInt32 time)
{
struct timespec delay;  // structure for providing timeout
   delay.tv_sec = time / (1000*1000); // sec
   delay.tv_nsec = (time % (1000*1000)) * 1000;
   nanosleep(&delay, NULL);
}

void FillArray(UInt32 pin_DestECount)
{
   UInt32 i;
   for(i=0; i<pin_DestECount;i++)
   {
     src_Src1[i] = i;       
   }
   src_Src1_actualSize=pin_DestECount;
   return;
}

void CopyArrayUInt32ToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
{
   if (pin_Enable) {

      if (pin_Offset >= src_Src2_maxSize) {
         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
         return;
      }
      UInt32 writableSize=src_Src2_maxSize-pin_Offset; 
      UInt8* pNext =&(src_Src2[pin_Offset]); 
/*      *pNext=(UInt8)(src_Src1_actualSize&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>8)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>16)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_actualSize>>24)&0xFF); pNext++;
      *pNext=(UInt8)(src_Src1_maxSize&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>8)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>16)&0xFF); pNext++;
      *pNext=(UInt8)((src_Src1_maxSize>>24)&0xFF); pNext++;
      writableSize-=8;*/
      UInt32 i;
      for(i=0;i<src_Src1_actualSize;i++)
      {
         *pNext=(UInt8)(*((UInt32*)(&src_Src1[i]))&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>8)&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>16)&0xFF); pNext++;
         *pNext=(UInt8)(((*((UInt32*)(&src_Src1[i])))>>24)&0xFF); pNext++;
         writableSize-=4;
      }
      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
          src_Src2_actualSize=src_Src2_maxSize-writableSize;
      }
   }
   return;
}

void CopyBoolToU8aBody(Bool pin_Enable, UInt32 pin_Offset)
{
   if (pin_Enable) {

      if (pin_Offset >= src_Src2_maxSize) {
         printf("EID_ARM_OFFSET_IS_TOO_LARGE\n");
         return;
      }
      UInt32 writableSize=src_Src2_maxSize-pin_Offset;
      UInt8* pNext =&(src_Src2[pin_Offset]);
      *pNext=(UInt8)src_Src3; pNext++;
      writableSize--;
      if (src_Src2_actualSize < src_Src2_maxSize-writableSize) {
          src_Src2_actualSize=src_Src2_maxSize-writableSize;
      }
   }
   return;
}

static UInt32 cycle=0;
void body()
{
FILE *fp;
   src_Src2_actualSize=0;
   CopyArrayUInt32ToU8aBody(TRUE, 0);

   fp=fopen("testdata.txt","at");
   fprintf(fp,"After write from the beginning of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle); 
   UInt32 i;
   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
   fclose(fp);

   CopyBoolToU8aBody(TRUE, 16008);

   fp=fopen("testdata.txt","at");
   fprintf(fp,"After write to the end of the buffer: len=%d, cycle=%d\n",src_Src2_actualSize,cycle); 
   for(i=0; i<src_Src2_actualSize;i+=sizeof(UInt32))fprintf(fp,"%d:%d\n",i,(UInt32)(*((UInt32*)&(src_Src2[i]))));
   fclose(fp);

   cycle++;

}

Bool terminateThread=FALSE;
Bool threadTerminated=FALSE;

static void *LinuxThreadFunc(void *ptr)
{
UInt32 cntr=0;
   printf("-- thread1: is running\n");
#ifdef ALLOC_IN_THREAD
   printf("Allocating the buffers in the thread.\n");
//      src_Src1=(UInt32*)new UInt32[2000];
printf("malloc1...\n");
usecdelay(10000);
      src_Src1=(UInt32*)malloc(4000*sizeof(UInt32));
usecdelay(10000);
printf("...ok\n");
usecdelay(10000);

//      src_Src1=(UInt32*)calloc(2000*8,1);
      src_Src1_maxSize=4000;src_Src1_actualSize=0;
//      src_Src2=(UInt8*) new UInt8[16013l];
printf("malloc2...\n");
usecdelay(10000);
      src_Src2=(UInt8*) malloc(16013l);
usecdelay(10000);
printf("...ok\n");
usecdelay(10000);
//      src_Src2=(UInt8*) calloc(16013l,1);
      src_Src2_maxSize=16013l;src_Src2_actualSize=0;
#endif
   while(!terminateThread)
   {
#ifdef MEMTEST_IN_THREAD      
      if(cntr==1) FillArray(src_Src1_maxSize);
      printf("-- thread1: cycle:%d test\n",cntr);
      body();
#else
      printf("-- thread1: cycle:%d empty\n",cntr);
#endif
      usecdelay(500000);
      cntr++;
   }
   threadTerminated=TRUE;
}


//--------------------------------------------------------------
int main (int argc, char* argv[])
{
int ret;
pthread_attr_t threadAttr;
pthread_t thread=0;  // thread identifier
FILE *fp;
UInt32 cntr=0;
	ret=mlockall(MCL_CURRENT | MCL_FUTURE); 
   printf("mlockall returned %d\n",ret);

   fp=fopen("testdata.txt","wt");
   fprintf(fp,"Xenomai memory allocation issue test.\n"); 
   fclose(fp);

#ifdef ALLOC_IN_MAIN 
   printf("Allocating the buffers in main()\n");
//      src_Src1=(UInt32*)new UInt32[2000];
   src_Src1=(UInt32*)malloc(4000*4);
   src_Src1_maxSize=2000;src_Src1_actualSize=0;
//      src_Src2=(UInt8*) new UInt8[16013l];
   src_Src2=(UInt8*) malloc(16013l);
   src_Src2_maxSize=16013l;src_Src2_actualSize=0;
#endif

   printf("- Create a new thread (thread1)\n");
 // initialize the thread attribute
   if(pthread_attr_init(&threadAttr)!=0)
   {
      printErrno("Thread(): pthread_attr_init() error :");
      return -1;
   }
// Set thread to detached state. No need for pthread_join
   if(pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED)!=0)
   {
      printErrno("Thread(): pthread_attr_setdetachstate() error :");
      pthread_attr_destroy(&threadAttr);
      return -2;
   }
// Create the thread
   if(pthread_create(&thread, &threadAttr, LinuxThreadFunc, 0)!=0)
   {
      printErrno("Thread(): pthread_create() error :");
      pthread_attr_destroy(&threadAttr);
      return -3;
   }
// Destroy the thread attributes
   if(pthread_attr_destroy(&threadAttr)!=0)
   {
      printErrno("Thread(): pthread_attr_destroy() error :");
      return -4;
   }
   printf("- Thread create OK (thread1)\n");
   UInt32 i;
   for(i=0;i<3;i++)
   {
#ifdef MEMTEST_IN_MAIN    
      if(cntr==1) FillArray(src_Src1_maxSize);
      body();
      printf("main loop is testing.\n");
#else
      printf("main loop is empty.\n");
#endif
      usecdelay(500000);
      cntr++;
   }

   terminateThread=TRUE;
   printf("- Wait for the thread (thread1) to exit\n");
   do
   {
      usecdelay(10000);
   }while(!threadTerminated);
   printf("- Thread1 terminated\n");
   free(src_Src2);
   free(src_Src1);
//   delete[] src_Src2;
//   delete[] src_Src1;
end:
   return 0;
}



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

* Re: [Xenomai] Memory paging trouble
  2014-07-16 12:42       ` Paal Tamas
@ 2014-07-17 20:25         ` Gilles Chanteperdrix
  2014-07-18  9:10           ` Paal Tamas
  0 siblings, 1 reply; 12+ messages in thread
From: Gilles Chanteperdrix @ 2014-07-17 20:25 UTC (permalink / raw)
  To: Paal Tamas, xenomai

On 07/16/2014 02:42 PM, Paal Tamas wrote:
> I keep on trying:
> 
> Gilles,
> 
> Hopefully this time it will be better.
> 
> Besides, you can find the test app sourcecode at the end.
> 
> I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware.

Do you have the same issue with a recent patch, like the one for 3.8 or
for 3.10?

-- 
                                                                Gilles.


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

* Re: [Xenomai] Memory paging trouble
  2014-07-17 20:25         ` Gilles Chanteperdrix
@ 2014-07-18  9:10           ` Paal Tamas
  2014-07-18 10:01             ` Gilles Chanteperdrix
  0 siblings, 1 reply; 12+ messages in thread
From: Paal Tamas @ 2014-07-18  9:10 UTC (permalink / raw)
  To: Gilles Chanteperdrix, xenomai



Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>On 07/16/2014 02:42 PM, Paal Tamas wrote:
>> I keep on trying:
>> 
>> Gilles,
>> 
>> Hopefully this time it will be better.
>> 
>> Besides, you can find the test app sourcecode at the end.
>> 
>> I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware.
>
>Do you have the same issue with a recent patch, like the one for 3.8 or
>for 3.10?
>
>-- 
>                                                                Gilles.

Do you mean to patch the 3.015 Linux kernel using a xenomai patch for the 3.8 or 3.10 versions? No I did not try it.

Tamas

>


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

* Re: [Xenomai] Memory paging trouble
  2014-07-18  9:10           ` Paal Tamas
@ 2014-07-18 10:01             ` Gilles Chanteperdrix
  2014-07-18 12:23               ` Paal Tamas
  0 siblings, 1 reply; 12+ messages in thread
From: Gilles Chanteperdrix @ 2014-07-18 10:01 UTC (permalink / raw)
  To: Paal Tamas, xenomai

On 07/18/2014 11:10 AM, Paal Tamas wrote:
> 
> 
> Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>> On 07/16/2014 02:42 PM, Paal Tamas wrote:
>>> I keep on trying:
>>>
>>> Gilles,
>>>
>>> Hopefully this time it will be better.
>>>
>>> Besides, you can find the test app sourcecode at the end.
>>>
>>> I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware.
>>
>> Do you have the same issue with a recent patch, like the one for 3.8 or
>> for 3.10?
>>
>> -- 
>>                                                                Gilles.
> 
> Do you mean to patch the 3.015 Linux kernel using a xenomai patch for the 3.8 or 3.10 versions? No I did not try it.

No, I mean patching Linux 3.8 or Linux 3.10 with the corresponding patch.


-- 
                                                                Gilles.


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

* Re: [Xenomai] Memory paging trouble
  2014-07-18 10:01             ` Gilles Chanteperdrix
@ 2014-07-18 12:23               ` Paal Tamas
  2014-07-18 12:47                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 12+ messages in thread
From: Paal Tamas @ 2014-07-18 12:23 UTC (permalink / raw)
  To: Gilles Chanteperdrix, xenomai



Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>On 07/18/2014 11:10 AM, Paal Tamas wrote:
>> 
>> 
>> Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>>> On 07/16/2014 02:42 PM, Paal Tamas wrote:
>>>> I keep on trying:
>>>>
>>>> Gilles,
>>>>
>>>> Hopefully this time it will be better.
>>>>
>>>> Besides, you can find the test app sourcecode at the end.
>>>>
>>>> I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware.
>>>
>>> Do you have the same issue with a recent patch, like the one for 3.8 or
>>> for 3.10?
>>>
>>> -- 
>>>                                                                Gilles.
>> 
>> Do you mean to patch the 3.015 Linux kernel using a xenomai patch for the 3.8 or 3.10 versions? No I did not try it.
>
>No, I mean patching Linux 3.8 or Linux 3.10 with the corresponding patch.
>
>
>-- 
>                                                                Gilles.
>
Unfortunately the latest BSP for my board (VAR-SOM-MX6) is for kernel 3.0.35. 
It was a nightmare to add xenomai support to it.  I had to start with 3.0.15 (since there was no direct Adeos and Xeno path for the 3.0.35).... I don't want to start the whole procedure from the beginning again...
Is there any other way to start with?

Thanks,
Tamas


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

* Re: [Xenomai] Memory paging trouble
  2014-07-18 12:23               ` Paal Tamas
@ 2014-07-18 12:47                 ` Gilles Chanteperdrix
  0 siblings, 0 replies; 12+ messages in thread
From: Gilles Chanteperdrix @ 2014-07-18 12:47 UTC (permalink / raw)
  To: Paal Tamas, xenomai

On 07/18/2014 02:23 PM, Paal Tamas wrote:
> 
> 
> Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>> On 07/18/2014 11:10 AM, Paal Tamas wrote:
>>>
>>>
>>> Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org> írta:
>>>> On 07/16/2014 02:42 PM, Paal Tamas wrote:
>>>>> I keep on trying:
>>>>>
>>>>> Gilles,
>>>>>
>>>>> Hopefully this time it will be better.
>>>>>
>>>>> Besides, you can find the test app sourcecode at the end.
>>>>>
>>>>> I am using Xeno 2.6.3 together with a 3.0.15 Linux kernel on an i.MX6 ARM hardware.
>>>>
>>>> Do you have the same issue with a recent patch, like the one for 3.8 or
>>>> for 3.10?
>>>>
>>>> -- 
>>>>                                                                Gilles.
>>>
>>> Do you mean to patch the 3.015 Linux kernel using a xenomai patch for the 3.8 or 3.10 versions? No I did not try it.
>>
>> No, I mean patching Linux 3.8 or Linux 3.10 with the corresponding patch.
>>
>>
>> -- 
>>                                                                Gilles.
>>
> Unfortunately the latest BSP for my board (VAR-SOM-MX6) is for kernel 3.0.35. 
> It was a nightmare to add xenomai support to it.  I had to start with 3.0.15 (since there was no direct Adeos and Xeno path for the 3.0.35).... I don't want to start the whole procedure from the beginning again...
> Is there any other way to start with?

The point is, you do not need the whole BSP to run your program. So, if
you can boot a recent kernel with only support for serial console, that
would be enough to run your test and see if you have any issues.

> 
> Thanks,
> Tamas
> 


-- 
                                                                Gilles.


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

end of thread, other threads:[~2014-07-18 12:47 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-16 11:23 [Xenomai] Memory paging trouble Paal Tamas
2014-07-16 11:29 ` Gilles Chanteperdrix
2014-07-16 11:39   ` Gilles Chanteperdrix
2014-07-16 12:16   ` Paal Tamas
2014-07-16 12:29     ` Gilles Chanteperdrix
2014-07-16 12:30     ` Paal Tamas
2014-07-16 12:42       ` Paal Tamas
2014-07-17 20:25         ` Gilles Chanteperdrix
2014-07-18  9:10           ` Paal Tamas
2014-07-18 10:01             ` Gilles Chanteperdrix
2014-07-18 12:23               ` Paal Tamas
2014-07-18 12:47                 ` 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.