Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: Tom Appermont <tea@sonycom.com>
To: linux-mips@oss.sgi.com
Subject: shared memory
Date: Tue, 28 Aug 2001 19:17:25 +0200	[thread overview]
Message-ID: <20010828191725.A1221@sonycom.com> (raw)

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


Howdy,

Attached are two files (shmm.c and test.c). The first is a simple
implementation of a kernel module that allocates RAM for sharing
memory with a user space application. The second file implements
a simple test to verify that the shared buffer behaves as 
expected, by writing something in shared memory and requesting
the module to check if what was written by the application is 
also visible in kernel space. 

While this works as expected on PC, it does not at all work as
expected on my mips platform (R5231): What is written in user
space is not immediately visible in kernel space. This is with
very recent kernel sources (2.4.8) but the same problem exists
with an older (2.4.5) kernel.

There have been a few mails about mmap() problems in the last 
couple of months, but with very little interesting response. Is 
this a known problem or am I stupidly overlooking something?


Greetz,

Tom



[-- Attachment #2: shmm.c --]
[-- Type: text/plain, Size: 2581 bytes --]

#ifndef __KERNEL__
#  define __KERNEL__
#endif
#ifndef MODULE
#  define MODULE
#endif

#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>

#include <linux/kernel.h>
#include <linux/malloc.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <asm/system.h> 
#include <asm/atomic.h>
#include <asm/uaccess.h>

static int major;
static volatile int* shb;
static unsigned int order;

static ssize_t
shmm_write(struct file* file, char* buffer, size_t length, loff_t *offset)
{
    int i;
    copy_from_user(&i, buffer, sizeof(int)); 
    if (i != *shb) {
	printk("counter = %d, *shb = %d\n", i, *shb);
    }
    return sizeof(int);
}

static inline pgprot_t pgprot_noncached(pgprot_t _prot)
{
#ifdef CONFIG_MIPS
    unsigned long prot = pgprot_val(_prot);   
    prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
    return __pgprot(prot);
#endif
}


static struct page *
shmm_vm_nopage(struct vm_area_struct *vma,
               unsigned long address,
               int write_access)
{
    unsigned long         physical;
    unsigned long         offset;
    struct page*          pageptr;

    if (address > vma->vm_end) return NOPAGE_SIGBUS; 
    offset   = address - vma->vm_start;
    physical = (unsigned long)shb + offset;
    pageptr = virt_to_page(physical);
 
    vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

    atomic_inc(&pageptr->count); 
    return pageptr;
}

struct vm_operations_struct shmm_vm_ops = {
    nopage:  shmm_vm_nopage
};

static int
shmm_mmap(struct file *file, struct vm_area_struct *vma)
{
  unsigned long vsize     = vma->vm_end - vma->vm_start;
  unsigned long npages    = vsize / PAGE_SIZE;

  order = 0;
  while ((1 << order) < npages) order++;
  npages = 1 << order;
  printk("npages requested = %d, order = %d\n", npages, order);
  shb = (int*)__get_dma_pages(GFP_KERNEL, order);
  if (0 == shb) {
    return -ENOMEM;
  }

  memset(shb,0,npages * PAGE_SIZE);

  vma->vm_ops = &shmm_vm_ops;
  vma->vm_flags |=  VM_LOCKED | VM_SHM; 
  
  return 0;
}


static struct file_operations shmm_fops = {
  write:          shmm_write,
  mmap:           shmm_mmap
};
 
static int shmm_init(void)
{
  /* Dynamically allocate major number.
   * cat /proc/devices to get number in userland.
   */
  major = register_chrdev(0, "shmm", &shmm_fops);
  if (major < 0) {
    printk("register_chrdev() failed.\n");
    return major;
  }

  return  0;
}
 
static void shmm_cleanup(void)
{
  unregister_chrdev(major,"shmm");
}
 
module_init(shmm_init);
module_exit(shmm_cleanup);


[-- Attachment #3: test.c --]
[-- Type: text/plain, Size: 721 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
 
 
int main(void)
{
  int shmm;
  volatile int counter = 0;
  volatile int* address;

  shmm = open("/dev/shmm", O_RDWR);
  if (shmm < 0) {
    printf("File not found\n");
    return 1;
  }
 
  address = mmap(0, getpagesize(), PROT_WRITE | PROT_READ,
                 MAP_PRIVATE , shmm, 0);
 
  if (address == (void *)-1) {
      printf(stderr,"mmap(): %s\n",strerror(errno));
      exit(1);
  }

  while(1) {
    *address = counter;
    write(shmm, &counter, sizeof(counter));
    counter++;
  }

  munmap((void*)address,getpagesize());
  close(shmm);
}

             reply	other threads:[~2001-08-28 17:17 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-08-28 17:17 Tom Appermont [this message]
2001-08-29  3:37 ` shared memory Ralf Baechle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010828191725.A1221@sonycom.com \
    --to=tea@sonycom.com \
    --cc=linux-mips@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox