shared memory problem on ARM v5TE using threads

christian pellegrin chripell at gmail.com
Tue Dec 15 06:01:56 EST 2009


On Tue, Dec 15, 2009 at 8:50 AM, saeed bishara <saeed.bishara at gmail.com> wrote:
> On Mon, Dec 14, 2009 at 10:14 PM, Nicolas Pitre <nico at fluxnic.net> wrote:
>> On Mon, 14 Dec 2009, christian pellegrin wrote:
>>>
>>> Has someone a suggestion on how to write a test-case for this?
>>
>> I don't think there is any peripheral that runs in PIO mode on
>> Kirkwood... except the NAND flash.
> the sata can be configured to use pio instead of dma, this can be done
> by adding libata.force=pio to the command line.
>>

Thanks for your answers, unfortunately it turned out to be quite easy
to write a program [0] that shows exactly what Russell described. :-(

On the Ferocecon [1] sometimes *both* the read via private mapping and
via simple lseek/read give the wrong result. On another arm without L2
cache [2] it happens sometimes that private mapping gives the wrong
result (I'm not sure it's ok, but it seems reasonable because the
mapping is private) but the read via lseek/read is always ok.

[0]:
/*
  dd if=/dev/zero of=prova count=1 bs=1k
  before running this
 */

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{
  int fd, fd1;
  char *s1, *s2, *p;
  volatile char x;

  fd = open("prova", O_RDWR);
  assert(fd);

  fd1 = open("prova", O_RDWR);
  assert(fd1);

  p = mmap(NULL, 1024, PROT_WRITE|PROT_READ, MAP_PRIVATE,
	   fd1, 0);
  assert((long) p != -1);

  x = *p;

  s1 = mmap(NULL, 1024, PROT_WRITE|PROT_READ, MAP_SHARED,
	     fd, 0);
  assert((long) s1 != -1);
  s2 = mmap(NULL, 1024, PROT_WRITE|PROT_READ, MAP_SHARED,
	     fd, 0);
  assert((long) s2 != -1);

  fprintf(stderr,"s1 %p s2 %p p %p\n", s1, s2, p);
  fprintf(stderr, "1: s1 %d s2 %d p %d\n", s1[0], s2[0], p[0]);

  s1[0] = 'a';
  s2[0] = 'b';

  msync(s1, 1024, MS_SYNC);
  msync(s2, 1024, MS_SYNC);

  assert(lseek(fd1, SEEK_SET, 0) == 0);
  assert(read(fd1, &x, 1) == 1);
  fprintf(stderr, "2: s1 %d s2 %d p %d x %d\n", s1[0], s2[0], p[0], x);

  return 0;
}

[1]:
debian-armel:~/cachep# uname -a
Linux debian-armel 2.6.32-rc7-openrd #36 PREEMPT Tue Dec 15 11:07:00
CET 2009 armv5tel GNU/Linux
debian-armel:~/cachep# cat /proc/cpuinfo
Processor	: Feroceon 88FR131 rev 1 (v5l)
BogoMIPS	: 1196.03
Features	: swp half thumb fastmult edsp
CPU implementer	: 0x56
CPU architecture: 5TE
CPU variant	: 0x2
CPU part	: 0x131
CPU revision	: 1

Hardware	: Marvell OpenRD Base Board
Revision	: 0000
Serial		: 0000000000000000

[2]:
root at familiar:/var/tmp# uname -a
Linux familiar 2.6.23-dixe #58 PREEMPT Fri Dec 4 11:33:26 CET 2009
armv4tl unknown
root at familiar:/var/tmp# cat /proc/cpuinfo
Processor       : ARM920T rev 0 (v4l)
BogoMIPS        : 88.84
Features        : swp half thumb
CPU implementer : 0x41
CPU architecture: 4T
CPU variant     : 0x1
CPU part        : 0x920
CPU revision    : 0
Cache type      : write-back
Cache clean     : cp15 c7 ops
Cache lockdown  : format A
Cache format    : Harvard
I size          : 16384
I assoc         : 64
I line length   : 32
I sets          : 8
D size          : 16384
D assoc         : 64
D line length   : 32
D sets          : 8

Hardware        : Atmel AT91RM9200-DK
Revision        : 0000
Serial          : 0000000000000000


-- 
Christian Pellegrin, see http://www.evolware.org/chri/
"Real Programmers don't play tennis, or any other sport which requires
you to change clothes. Mountain climbing is OK, and Real Programmers
wear their climbing boots to work in case a mountain should suddenly
spring up in the middle of the computer room."



More information about the linux-arm-kernel mailing list