From: Greg KH <gregkh@suse.de>
To: Peter Crosthwaite <peter.crosthwaite@petalogix.com>
Cc: linux-kernel@vger.kernel.org, hjk@linutronix.de,
Michal Simek <michal.simek@petalogix.com>,
John Williams <john.williams@petalogix.com>
Subject: Re: UIO: munmap bug for boot time allocated memory
Date: Thu, 8 Jul 2010 16:39:23 -0700 [thread overview]
Message-ID: <20100708233923.GB8671@suse.de> (raw)
In-Reply-To: <AANLkTikuRjaAUF5KOn1QnVU8VnUiSNPkoKkkBdipXooY@mail.gmail.com>
On Wed, Jul 07, 2010 at 04:36:02PM +1000, Peter Crosthwaite wrote:
> Hi,
>
> I'm currently experiencing a kernel bug when munmap'ing a UIO memory region.
> The uio memory region is a large (up to 48MB) buffer allocated by a UIO
> driver at boot time using alloc_bootmem_low_pages(). The idea is once the
> large buffer is allocated, devices can DMA directly to the buffer which is
> user space accessible. The system is tested as working, with the DMA device
> being able to fill the buffer and user space being able to see the correct
> data, except that it throws a bug once user space munmaps the UIO region.
> The bug is a "bad page state". I have summarized the kernel space the
> driver, the user space program and the bug below. My first question is - is
> there anything fundamentally incorrect with this approach / is there a
> better way?
>
> The kernel version is (2.6.31.11) and architecture is MicroBlaze.
>
> What happens in the kernel space driver:
>
> -The buffer is allocated at boot time using alloc_bootmem_low_pages()
>
> unsigned buf_size = 0x00010000; /*size of 64k */
> b_virt = alloc_bootmem_low_pages(PAGE_
> ALIGN(buf_size));
>
> -The address returned is set as the base address for a UIO memory region
> and the UIO device is created:
>
> struct uio_info * usdma_uio_info;
> ... //name version and IRQ are set
> usdma_uio_info->mem[0].addr =b_virt; //This is the address returned
> by alloc_bootmem_low_pages()
Yeah, but is this a valid address that userspace has access to? Or is
this a "virtual" address? I thought you had to "remap" this memory to
properly access it but I don't know this architecture good enough to be
sure about that.
Have a pointer to your whole kernel driver anywhere?
> usdma_uio_info->mem[0].size = buf_size;
> usdma_uio_info->mem[0].memtype = UIO_MEM_LOGICAL;
> usdma_uio_info->mem[0].internal_addr = b_virt;
> uio_register_device(dev, usdma_uio_info);
>
> What happens in the user space program:
>
> -The UIO device is opened and mmap'ed (to in_ptr)
>
> in_fd=open("/dev/uio0",O_RDWR);
> char * in_ptr=mmap(NULL, size, PROT_READ, MAP_SHARED, in_fd, 0);
> if(!in_ptr) {
> perror("mmap:");
> return -1;
> }
>
> -Write the buffer out to some random file (out_fd)
>
> for (bytes_written = 0; bytes_written < size;) {
> bytes_written += write(out_fd, in_ptr+bytes_written, size);
> }
Is this showing the correct data?
> -The UIO memory region is unmap (this is when the error occurs)
>
> munmap(in_ptr, size);
>
> The bug:
>
> The output from dmesg (after the user space program is run) is below. This
> output happens multiple times, i.e. the bug is replicated for all the mapped
> pages. Curiously, the bug only happens when the pages are touched by the
> user space program, e.g. if the example user space program given above does
> not write() the buffer contents out to file, the bug does not occur (and the
> munmap completes successfully).
>
> Further investigation revealed that the reason the bad_page function was
> being called is that free_hot_cold_pages (mm/page_alloc.c) does not like
> pages with either the PG_slab or PG_buddy flags set. The bug will always
> show one of these flags being set (PG_slab = 0x00000080 in the case below),
> for the page that is being freed. Which flag is set depends on the size of
> the buffer - small buffers its PG_slab large buffers its PG_buddy.
>
> My second question is should the kernel be trying to free these pages (using
> free_hot_cold_page) at all?? - Considering my kernel space driver still has
> them mapped locally??
Good question, who is trying to free them?
wierd.
greg k-h
next parent reply other threads:[~2010-07-08 23:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <AANLkTikuRjaAUF5KOn1QnVU8VnUiSNPkoKkkBdipXooY@mail.gmail.com>
2010-07-08 23:39 ` Greg KH [this message]
2010-07-21 7:17 ` UIO: munmap bug for boot time allocated memory Peter Crosthwaite
2010-07-21 9:09 ` Hans J. Koch
2010-07-11 23:51 Peter Crosthwaite
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=20100708233923.GB8671@suse.de \
--to=gregkh@suse.de \
--cc=hjk@linutronix.de \
--cc=john.williams@petalogix.com \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.simek@petalogix.com \
--cc=peter.crosthwaite@petalogix.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