linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Sharing memory between kernel and user space
@ 2006-05-30 22:32 Brian D. McGrew
  2006-05-30 22:46 ` H. Peter Anvin
  0 siblings, 1 reply; 7+ messages in thread
From: Brian D. McGrew @ 2006-05-30 22:32 UTC (permalink / raw)
  To: linux-kernel

I have a question about the best way to share memory between user and
kernel space.

Let's say I have a common structure;

struct counter {
	u_long interrupt_counts;
	bool saw_interupt;
}

And I need to be able to modify these elements from both the kernel and
user space.  What is the best way to allocate this???  I've tried
several methods including __get_free_pages, alloc_pages, vmalloc and so
on; and thus far, I'm just confused myself.

Can someone help me out here with a quick example of some sort???

Thanks,

:b!

Brian D. McGrew { brian@visionpro.com || brian@doubledimension.com }
--
> This is a test.  This is only a test!
  Had this been an actual emergency, you would have been
  told to cancel this test and seek professional assistance!


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

* Re: Sharing memory between kernel and user space
  2006-05-30 22:32 Sharing memory between kernel and user space Brian D. McGrew
@ 2006-05-30 22:46 ` H. Peter Anvin
  0 siblings, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2006-05-30 22:46 UTC (permalink / raw)
  To: linux-kernel

Followup to:  <14CFC56C96D8554AA0B8969DB825FEA0012B331A@chicken.machinevisionproducts.com>
By author:    "Brian D. McGrew" <brian@visionpro.com>
In newsgroup: linux.dev.kernel
>
> I have a question about the best way to share memory between user and
> kernel space.
> 

In general, allocate the memory in kernel space (via get_free_page et
al), and make accessible to userspace via mmap on a device node.

	-hpa

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

* RE: Sharing memory between kernel and user space.
@ 2006-05-31 20:38 Brian D. McGrew
  0 siblings, 0 replies; 7+ messages in thread
From: Brian D. McGrew @ 2006-05-31 20:38 UTC (permalink / raw)
  To: linux-kernel

I got a lot of good help in the last couple days, thank you to everyone
who responded; I made major progress but I'm still having a hang up and
a bit confused.

I my driver, I allocate this structure:

typedef struct rtc_shared {
    unsigned long       snap_addrs_loc;
    time_t              ntimestamp;
} RtcShared;

In the driver like this:

static int
alloc_rtc_usr_shared(RtcSoftDev *rtc_sp)
{
    unsigned long addr;
    unsigned long bytes = PAGE_SIZE << get_order(RTC_COMMON_SIZE);
    unsigned long sz;

    rtc_sp->shared_host_mem =
        __get_free_pages(GFP_KERNEL, get_order(RTC_COMMON_SIZE));

    if (rtc_sp->shared_host_mem == NULL) {
        debug_out(("alloc_rtc_usr_shared: out of memory.\n"));
        return(0);
    }

    memset((void *)rtc_sp->shared_host_mem, 0, bytes);

    for (addr = rtc_sp->shared_host_mem, sz = bytes;
        sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {

            SetPageReserved(virt_to_page(addr));
    }

    return(0);
}

And then in my driver mmap routine:

int
rtc_mmap(struct file *filep, struct vm_area_struct *vma)
{
    RtcSoftDev *rtc_sp = filep->private_data;

    unsigned long start = vma->vm_start;
    unsigned long size = vma->vm_end - vma->vm_start;
    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
    unsigned long page = ((rtc_sp->iobase + offset) >> PAGE_SHIFT);

    if (offset > __pa(high_memory) || (filep->f_flags & O_SYNC)) {
        vma->vm_flags |= VM_IO;
    }

    vma->vm_flags |= VM_RESERVED;

    if (offset == RTC_COMMON_VADDR) {
        debug_out(("RTC_COMMON_VADDR: %x\n", offset));

        // page = virt_to_phys((void*)((unsigned
long)rtc_sp->shared_host_mem));
        // page = page_to_pfn(virt_to_page(phys_to_virt(__pa(page))));
        while (size > 0) {
            debug_out(("START: %#lx, SIZE: %#lx, OFFSET: %#lx, PAGE:
%#lx\n",
                start, size, offset, page));

            if (remap_pfn_range(vma,
                start,
                    page,
                        PAGE_SIZE,
                            PAGE_SHARED)) {
                return(-EAGAIN);
            }

            start += PAGE_SIZE;
            page += PAGE_SIZE;

            if (size > PAGE_SIZE) {
                size -= PAGE_SIZE;
            } else {
                size = 0;
            }
        }
    }

    else {
        debug_out(("RTC_???_OFFSET --- WE'RE BROKEN --- %x\n", offset));
    }

    return(0);
}

Now the driver like that loads and attaches without blowing up.
However, from userspace, when I open("/dev/mvp_rtc", O_RDWR) and then
try and mmap it, when I read it back, I can read back rtc_shared but I
can't read rtc_shared->snap_addrs_loc.

My main hope is that someone will spot something I'm obviously doing
wrong but if not, my next question is:

Is the virtual address that I get back from the kernel in
all_rtc_usr_shared going to be the same address that I read in
userspace?  Because right now I'm getting back something like 0xc11a0000
from the kernel and then I'm seeing something like 0xbf73000 in
userspace.

Thanks again for all the help and with a little more coaching I just
might get this blasted thing working before I retire 99 years from now!

:b!

Brian D. McGrew { brian@visionpro.com || brian@doubledimension.com }
--
> This is a test.  This is only a test!
  Had this been an actual emergency, you would have been
  told to cancel this test and seek professional assistance!


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

* Re: Sharing memory between kernel and user space
  2006-05-30 22:53 Brian D. McGrew
  2006-05-30 23:21 ` Christopher Friesen
@ 2006-05-31 12:33 ` Jonathan Corbet
  1 sibling, 0 replies; 7+ messages in thread
From: Jonathan Corbet @ 2006-05-31 12:33 UTC (permalink / raw)
  To: Brian D. McGrew; +Cc: linux-kernel

> I'm using the 2.6.16.16 kernel.  Is there any chance that I could
> trouble you for a snippet of code to do that?  I've tried every
> combination I can think of.

The memory mapping chapter of LDD3 (http://lwn.net/Kernel/LDD3/) has a
pretty thorough description of how to share both kernel- and user-space
memory, with code examples.

jon

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

* RE: Sharing memory between kernel and user space
@ 2006-05-31  0:09 Brian D. McGrew
  0 siblings, 0 replies; 7+ messages in thread
From: Brian D. McGrew @ 2006-05-31  0:09 UTC (permalink / raw)
  To: H. Peter Anvin, linux-kernel

As you recommended I do a __get_free_pages in the kernel and then from
user space I try and mmap the memory.

The mmap is successful but then when I go back and try and read from
that location I get a 'can't read of address 0xbf7c8000 (which is the
address the kernel gave me back).

???

:b!

Brian D. McGrew { brian@visionpro.com || brian@doubledimension.com }
--
> This is a test.  This is only a test!
  Had this been an actual emergency, you would have been
  told to cancel this test and seek professional assistance!
-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of H. Peter Anvin
Sent: Tuesday, May 30, 2006 3:46 PM
To: linux-kernel@vger.kernel.org
Subject: Re: Sharing memory between kernel and user space

Followup to:
<14CFC56C96D8554AA0B8969DB825FEA0012B331A@chicken.machinevisionproducts.
com>
By author:    "Brian D. McGrew" <brian@visionpro.com>
In newsgroup: linux.dev.kernel
>
> I have a question about the best way to share memory between user and
> kernel space.
> 

In general, allocate the memory in kernel space (via get_free_page et
al), and make accessible to userspace via mmap on a device node.

	-hpa
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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

* Re: Sharing memory between kernel and user space
  2006-05-30 22:53 Brian D. McGrew
@ 2006-05-30 23:21 ` Christopher Friesen
  2006-05-31 12:33 ` Jonathan Corbet
  1 sibling, 0 replies; 7+ messages in thread
From: Christopher Friesen @ 2006-05-30 23:21 UTC (permalink / raw)
  To: Brian D. McGrew; +Cc: H. Peter Anvin, linux-kernel

Brian D. McGrew wrote:
> I'm using the 2.6.16.16 kernel.  Is there any chance that I could
> trouble you for a snippet of code to do that?  I've tried every
> combination I can think of.

You could try looking at how /dev/kmem does it.

Also, be aware that the size of "unsigned long" can vary between the 
kernel and userspace if you have a 64-bit machine.

Chris

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

* RE: Sharing memory between kernel and user space
@ 2006-05-30 22:53 Brian D. McGrew
  2006-05-30 23:21 ` Christopher Friesen
  2006-05-31 12:33 ` Jonathan Corbet
  0 siblings, 2 replies; 7+ messages in thread
From: Brian D. McGrew @ 2006-05-30 22:53 UTC (permalink / raw)
  To: H. Peter Anvin, linux-kernel

I'm using the 2.6.16.16 kernel.  Is there any chance that I could
trouble you for a snippet of code to do that?  I've tried every
combination I can think of.

Thank you,

:b!

Brian D. McGrew { brian@visionpro.com || brian@doubledimension.com }
--
> This is a test.  This is only a test!
  Had this been an actual emergency, you would have been
  told to cancel this test and seek professional assistance!

-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of H. Peter Anvin
Sent: Tuesday, May 30, 2006 3:46 PM
To: linux-kernel@vger.kernel.org
Subject: Re: Sharing memory between kernel and user space

Followup to:
<14CFC56C96D8554AA0B8969DB825FEA0012B331A@chicken.machinevisionproducts.
com>
By author:    "Brian D. McGrew" <brian@visionpro.com>
In newsgroup: linux.dev.kernel
>
> I have a question about the best way to share memory between user and
> kernel space.
> 

In general, allocate the memory in kernel space (via get_free_page et
al), and make accessible to userspace via mmap on a device node.

	-hpa
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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

end of thread, other threads:[~2006-05-31 20:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-30 22:32 Sharing memory between kernel and user space Brian D. McGrew
2006-05-30 22:46 ` H. Peter Anvin
2006-05-30 22:53 Brian D. McGrew
2006-05-30 23:21 ` Christopher Friesen
2006-05-31 12:33 ` Jonathan Corbet
2006-05-31  0:09 Brian D. McGrew
2006-05-31 20:38 Brian D. McGrew

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).