* bade page state while calling munmap() for kmalloc'ed UIO memory
@ 2011-08-29 15:05 Jan Altenberg
2011-08-31 9:58 ` Hans J. Koch
0 siblings, 1 reply; 7+ messages in thread
From: Jan Altenberg @ 2011-08-29 15:05 UTC (permalink / raw)
To: linux-mm; +Cc: Hans J. Koch, b.spranger
Hi,
I'm currently analysing a problem similar to some mmap() issue reported
in the past: https://lkml.org/lkml/2010/7/11/140
So, what I'm trying to do is mapping some physically continuous memory
(allocated by kmalloc) to userspace, using a trivial UIO driver (the
idea is that a device can directly DMA to that buffer):
[...]
#define MEM_SIZE (4 * PAGE_SIZE)
addr = kmalloc(MEM_SIZE, GFP_KERNEL)
[...]
info.mem[0].addr = (unsigned long) addr;
info.mem[0].internal_addr = addr;
info.mem[0].size = MEM_SIZE;
info.mem[0].memtype = UIO_MEM_LOGICAL;
[...]
ret = uio_register_device(&pdev->dev, &info);
Userspace maps that memory range and writes its contents to a file:
[...]
fd = open("/dev/uio0", O_RDWR);
if (fd < 0) {
perror("Can't open UIO device\n");
exit(1);
}
mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if(mem_map == MAP_FAILED) {
perror("Can't map UIO memory\n");
ret = -ENOMEM;
goto out_file;
}
[...]
bytes_written = write(fd_file, mem_map, MAP_SIZE)
[...]
munmap(mem_map);
So, what happens is (I'm currently testing with 3.0.3 on ARM
VersatilePB): When I do the munmap(), I run into the following error:
BUG: Bad page state in process uio_test pfn:078ed
page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
page flags: 0x284(referenced|slab|arch_1)
[<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
[<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
[<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
[<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
[<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
[<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
[<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
[<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
Disabling lock debugging due to kernel taint
BUG: Bad page state in process uio_test pfn:078ee
page:c0409178 count:0 mapcount:0 mapping: (null) index:0x0
page flags: 0x284(referenced|slab|arch_1)
[<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
[<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
[<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
[<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
[<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
[<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
[<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
[<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
BUG: Bad page state in process uio_test pfn:078ef
page:c040919c count:0 mapcount:0 mapping: (null) index:0x0
page flags: 0x284(referenced|slab|arch_1)
[<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
[<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
[<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
[<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
[<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
[<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
[<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
[<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
This happens for every page except the first one. If I change the code
and just touch the first page, everything's working fine. As soon as I
touch one of the other pages, I can see the "bad page state error" for
that page. The kernel is currently built using CONFIG_SLAB (my .config
is based on the versatile_defconfig); if I change to CONFIG_SLUB,
munmap() seems to be happy and I can't see the "bad page state" error.
Any idea what might be wrong here? Am I missing something obvious? (I've
prepared some brown paperbags for that case ;-))
Thanks,
Jan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: bade page state while calling munmap() for kmalloc'ed UIO memory
2011-08-29 15:05 bade page state while calling munmap() for kmalloc'ed UIO memory Jan Altenberg
@ 2011-08-31 9:58 ` Hans J. Koch
0 siblings, 0 replies; 7+ messages in thread
From: Hans J. Koch @ 2011-08-31 9:58 UTC (permalink / raw)
To: Jan Altenberg; +Cc: linux-mm, Hans J. Koch, b.spranger, Andrew Morton, LKML
On Mon, Aug 29, 2011 at 05:05:47PM +0200, Jan Altenberg wrote:
[Since we got no reply on linux-mm, I added lkml and Andrew to Cc: (mm doesn't
seem to have a maintainer...)]
> Hi,
>
> I'm currently analysing a problem similar to some mmap() issue reported
> in the past: https://lkml.org/lkml/2010/7/11/140
The arch there was microblaze, and you are working on arm. That means
the problem appears on at least to archs.
>
> So, what I'm trying to do is mapping some physically continuous memory
> (allocated by kmalloc) to userspace, using a trivial UIO driver (the
> idea is that a device can directly DMA to that buffer):
>
> [...]
> #define MEM_SIZE (4 * PAGE_SIZE)
>
> addr = kmalloc(MEM_SIZE, GFP_KERNEL)
> [...]
> info.mem[0].addr = (unsigned long) addr;
> info.mem[0].internal_addr = addr;
> info.mem[0].size = MEM_SIZE;
> info.mem[0].memtype = UIO_MEM_LOGICAL;
> [...]
> ret = uio_register_device(&pdev->dev, &info);
>
> Userspace maps that memory range and writes its contents to a file:
>
> [...]
>
> fd = open("/dev/uio0", O_RDWR);
> if (fd < 0) {
> perror("Can't open UIO device\n");
> exit(1);
> }
>
> mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
> MAP_PRIVATE, fd, 0);
>
> if(mem_map == MAP_FAILED) {
> perror("Can't map UIO memory\n");
> ret = -ENOMEM;
> goto out_file;
> }
> [...]
> bytes_written = write(fd_file, mem_map, MAP_SIZE)
> [...]
>
> munmap(mem_map);
>From my point of view (I've got Jan's full test case code), this
is a completely correct UIO use case.
>
> So, what happens is (I'm currently testing with 3.0.3 on ARM
> VersatilePB): When I do the munmap(), I run into the following error:
>
> BUG: Bad page state in process uio_test pfn:078ed
> page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
> page flags: 0x284(referenced|slab|arch_1)
> [<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
> [<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
> [<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
> [<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
> [<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
> [<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
> [<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
> [<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
> Disabling lock debugging due to kernel taint
> BUG: Bad page state in process uio_test pfn:078ee
> page:c0409178 count:0 mapcount:0 mapping: (null) index:0x0
> page flags: 0x284(referenced|slab|arch_1)
> [<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
> [<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
> [<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
> [<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
> [<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
> [<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
> [<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
> [<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
> BUG: Bad page state in process uio_test pfn:078ef
> page:c040919c count:0 mapcount:0 mapping: (null) index:0x0
> page flags: 0x284(referenced|slab|arch_1)
> [<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
> [<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
> [<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
> [<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
> [<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
> [<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
> [<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
> [<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
Quite strange that memory that could be mapped with mmap() cannot be
unmapped with munmap().
>
> This happens for every page except the first one.
...which is the next strange thing.
> If I change the code
> and just touch the first page, everything's working fine. As soon as I
> touch one of the other pages, I can see the "bad page state error" for
> that page.
The pages are mapped when you access them through the UIO core page fault
handler.
> The kernel is currently built using CONFIG_SLAB (my .config
> is based on the versatile_defconfig); if I change to CONFIG_SLUB,
> munmap() seems to be happy and I can't see the "bad page state" error.
That is more than strange, that points to some things going really wrong.
>
> Any idea what might be wrong here? Am I missing something obvious? (I've
> prepared some brown paperbags for that case ;-))
>
> Thanks,
> Jan
>
Thanks, Jan, for reporting this!
Hans
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: bade page state while calling munmap() for kmalloc'ed UIO memory
@ 2011-08-31 9:58 ` Hans J. Koch
0 siblings, 0 replies; 7+ messages in thread
From: Hans J. Koch @ 2011-08-31 9:58 UTC (permalink / raw)
To: Jan Altenberg; +Cc: linux-mm, Hans J. Koch, b.spranger, Andrew Morton, LKML
On Mon, Aug 29, 2011 at 05:05:47PM +0200, Jan Altenberg wrote:
[Since we got no reply on linux-mm, I added lkml and Andrew to Cc: (mm doesn't
seem to have a maintainer...)]
> Hi,
>
> I'm currently analysing a problem similar to some mmap() issue reported
> in the past: https://lkml.org/lkml/2010/7/11/140
The arch there was microblaze, and you are working on arm. That means
the problem appears on at least to archs.
>
> So, what I'm trying to do is mapping some physically continuous memory
> (allocated by kmalloc) to userspace, using a trivial UIO driver (the
> idea is that a device can directly DMA to that buffer):
>
> [...]
> #define MEM_SIZE (4 * PAGE_SIZE)
>
> addr = kmalloc(MEM_SIZE, GFP_KERNEL)
> [...]
> info.mem[0].addr = (unsigned long) addr;
> info.mem[0].internal_addr = addr;
> info.mem[0].size = MEM_SIZE;
> info.mem[0].memtype = UIO_MEM_LOGICAL;
> [...]
> ret = uio_register_device(&pdev->dev, &info);
>
> Userspace maps that memory range and writes its contents to a file:
>
> [...]
>
> fd = open("/dev/uio0", O_RDWR);
> if (fd < 0) {
> perror("Can't open UIO device\n");
> exit(1);
> }
>
> mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
> MAP_PRIVATE, fd, 0);
>
> if(mem_map == MAP_FAILED) {
> perror("Can't map UIO memory\n");
> ret = -ENOMEM;
> goto out_file;
> }
> [...]
> bytes_written = write(fd_file, mem_map, MAP_SIZE)
> [...]
>
> munmap(mem_map);
>From my point of view (I've got Jan's full test case code), this
is a completely correct UIO use case.
>
> So, what happens is (I'm currently testing with 3.0.3 on ARM
> VersatilePB): When I do the munmap(), I run into the following error:
>
> BUG: Bad page state in process uio_test pfn:078ed
> page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
> page flags: 0x284(referenced|slab|arch_1)
> [<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
> [<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
> [<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
> [<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
> [<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
> [<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
> [<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
> [<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
> Disabling lock debugging due to kernel taint
> BUG: Bad page state in process uio_test pfn:078ee
> page:c0409178 count:0 mapcount:0 mapping: (null) index:0x0
> page flags: 0x284(referenced|slab|arch_1)
> [<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
> [<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
> [<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
> [<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
> [<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
> [<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
> [<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
> [<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
> BUG: Bad page state in process uio_test pfn:078ef
> page:c040919c count:0 mapcount:0 mapping: (null) index:0x0
> page flags: 0x284(referenced|slab|arch_1)
> [<c0033e50>] (unwind_backtrace+0x0/0xe4) from [<c0079938>] (bad_page+0xcc/0xf8)
> [<c0079938>] (bad_page+0xcc/0xf8) from [<c007a5f0>] (free_pages_prepare+0x6c/0xcc)
> [<c007a5f0>] (free_pages_prepare+0x6c/0xcc) from [<c007a778>] (free_hot_cold_page+0x20/0x18c)
> [<c007a778>] (free_hot_cold_page+0x20/0x18c) from [<c008ccb4>] (unmap_vmas+0x338/0x564)
> [<c008ccb4>] (unmap_vmas+0x338/0x564) from [<c008f0f4>] (unmap_region+0xa4/0x1e0)
> [<c008f0f4>] (unmap_region+0xa4/0x1e0) from [<c0090428>] (do_munmap+0x20c/0x274)
> [<c0090428>] (do_munmap+0x20c/0x274) from [<c00904cc>] (sys_munmap+0x3c/0x50)
> [<c00904cc>] (sys_munmap+0x3c/0x50) from [<c002e680>] (ret_fast_syscall+0x0/0x2c)
Quite strange that memory that could be mapped with mmap() cannot be
unmapped with munmap().
>
> This happens for every page except the first one.
...which is the next strange thing.
> If I change the code
> and just touch the first page, everything's working fine. As soon as I
> touch one of the other pages, I can see the "bad page state error" for
> that page.
The pages are mapped when you access them through the UIO core page fault
handler.
> The kernel is currently built using CONFIG_SLAB (my .config
> is based on the versatile_defconfig); if I change to CONFIG_SLUB,
> munmap() seems to be happy and I can't see the "bad page state" error.
That is more than strange, that points to some things going really wrong.
>
> Any idea what might be wrong here? Am I missing something obvious? (I've
> prepared some brown paperbags for that case ;-))
>
> Thanks,
> Jan
>
Thanks, Jan, for reporting this!
Hans
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: bade page state while calling munmap() for kmalloc'ed UIO memory
2011-08-31 9:58 ` Hans J. Koch
@ 2011-08-31 23:13 ` Andrew Morton
-1 siblings, 0 replies; 7+ messages in thread
From: Andrew Morton @ 2011-08-31 23:13 UTC (permalink / raw)
To: Hans J. Koch; +Cc: Jan Altenberg, linux-mm, b.spranger, LKML
On Wed, 31 Aug 2011 11:58:25 +0200
"Hans J. Koch" <hjk@hansjkoch.de> wrote:
> On Mon, Aug 29, 2011 at 05:05:47PM +0200, Jan Altenberg wrote:
>
> [Since we got no reply on linux-mm, I added lkml and Andrew to Cc: (mm doesn't
> seem to have a maintainer...)]
>
> > Hi,
> >
> > I'm currently analysing a problem similar to some mmap() issue reported
> > in the past: https://lkml.org/lkml/2010/7/11/140
>
> The arch there was microblaze, and you are working on arm. That means
> the problem appears on at least to archs.
>
> >
> > So, what I'm trying to do is mapping some physically continuous memory
> > (allocated by kmalloc) to userspace, using a trivial UIO driver (the
> > idea is that a device can directly DMA to that buffer):
> >
> > [...]
> > #define MEM_SIZE (4 * PAGE_SIZE)
> >
> > addr = kmalloc(MEM_SIZE, GFP_KERNEL)
> > [...]
> > info.mem[0].addr = (unsigned long) addr;
> > info.mem[0].internal_addr = addr;
> > info.mem[0].size = MEM_SIZE;
> > info.mem[0].memtype = UIO_MEM_LOGICAL;
> > [...]
> > ret = uio_register_device(&pdev->dev, &info);
> >
> > Userspace maps that memory range and writes its contents to a file:
> >
> > [...]
> >
> > fd = open("/dev/uio0", O_RDWR);
> > if (fd < 0) {
> > perror("Can't open UIO device\n");
> > exit(1);
> > }
> >
> > mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
> > MAP_PRIVATE, fd, 0);
> >
> > if(mem_map == MAP_FAILED) {
> > perror("Can't map UIO memory\n");
> > ret = -ENOMEM;
> > goto out_file;
> > }
> > [...]
> > bytes_written = write(fd_file, mem_map, MAP_SIZE)
> > [...]
> >
> > munmap(mem_map);
>
> >From my point of view (I've got Jan's full test case code), this
> is a completely correct UIO use case.
>
> >
> > So, what happens is (I'm currently testing with 3.0.3 on ARM
> > VersatilePB): When I do the munmap(), I run into the following error:
> >
> > BUG: Bad page state in process uio_test pfn:078ed
> > page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
> > page flags: 0x284(referenced|slab|arch_1)
PG_slab is set. The kernel is complaining because a page which was
allocated via kmalloc/kmem_cache_alloc was directly passed to the page
allocator for freeing. It should have been passed to kfree().
Presumably the uio driver expects that its memory was allocated via
alloc_pages(), not via kmalloc().
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: bade page state while calling munmap() for kmalloc'ed UIO memory
@ 2011-08-31 23:13 ` Andrew Morton
0 siblings, 0 replies; 7+ messages in thread
From: Andrew Morton @ 2011-08-31 23:13 UTC (permalink / raw)
To: Hans J. Koch; +Cc: Jan Altenberg, linux-mm, b.spranger, LKML
On Wed, 31 Aug 2011 11:58:25 +0200
"Hans J. Koch" <hjk@hansjkoch.de> wrote:
> On Mon, Aug 29, 2011 at 05:05:47PM +0200, Jan Altenberg wrote:
>
> [Since we got no reply on linux-mm, I added lkml and Andrew to Cc: (mm doesn't
> seem to have a maintainer...)]
>
> > Hi,
> >
> > I'm currently analysing a problem similar to some mmap() issue reported
> > in the past: https://lkml.org/lkml/2010/7/11/140
>
> The arch there was microblaze, and you are working on arm. That means
> the problem appears on at least to archs.
>
> >
> > So, what I'm trying to do is mapping some physically continuous memory
> > (allocated by kmalloc) to userspace, using a trivial UIO driver (the
> > idea is that a device can directly DMA to that buffer):
> >
> > [...]
> > #define MEM_SIZE (4 * PAGE_SIZE)
> >
> > addr = kmalloc(MEM_SIZE, GFP_KERNEL)
> > [...]
> > info.mem[0].addr = (unsigned long) addr;
> > info.mem[0].internal_addr = addr;
> > info.mem[0].size = MEM_SIZE;
> > info.mem[0].memtype = UIO_MEM_LOGICAL;
> > [...]
> > ret = uio_register_device(&pdev->dev, &info);
> >
> > Userspace maps that memory range and writes its contents to a file:
> >
> > [...]
> >
> > fd = open("/dev/uio0", O_RDWR);
> > if (fd < 0) {
> > perror("Can't open UIO device\n");
> > exit(1);
> > }
> >
> > mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
> > MAP_PRIVATE, fd, 0);
> >
> > if(mem_map == MAP_FAILED) {
> > perror("Can't map UIO memory\n");
> > ret = -ENOMEM;
> > goto out_file;
> > }
> > [...]
> > bytes_written = write(fd_file, mem_map, MAP_SIZE)
> > [...]
> >
> > munmap(mem_map);
>
> >From my point of view (I've got Jan's full test case code), this
> is a completely correct UIO use case.
>
> >
> > So, what happens is (I'm currently testing with 3.0.3 on ARM
> > VersatilePB): When I do the munmap(), I run into the following error:
> >
> > BUG: Bad page state in process uio_test pfn:078ed
> > page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
> > page flags: 0x284(referenced|slab|arch_1)
PG_slab is set. The kernel is complaining because a page which was
allocated via kmalloc/kmem_cache_alloc was directly passed to the page
allocator for freeing. It should have been passed to kfree().
Presumably the uio driver expects that its memory was allocated via
alloc_pages(), not via kmalloc().
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: bade page state while calling munmap() for kmalloc'ed UIO memory
2011-08-31 23:13 ` Andrew Morton
@ 2011-09-01 18:55 ` Hans J. Koch
-1 siblings, 0 replies; 7+ messages in thread
From: Hans J. Koch @ 2011-09-01 18:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Hans J. Koch, Jan Altenberg, linux-mm, b.spranger, LKML
On Wed, Aug 31, 2011 at 04:13:07PM -0700, Andrew Morton wrote:
> On Wed, 31 Aug 2011 11:58:25 +0200
> "Hans J. Koch" <hjk@hansjkoch.de> wrote:
>
> > On Mon, Aug 29, 2011 at 05:05:47PM +0200, Jan Altenberg wrote:
> >
> > [Since we got no reply on linux-mm, I added lkml and Andrew to Cc: (mm doesn't
> > seem to have a maintainer...)]
> >
> > > Hi,
> > >
> > > I'm currently analysing a problem similar to some mmap() issue reported
> > > in the past: https://lkml.org/lkml/2010/7/11/140
> >
> > The arch there was microblaze, and you are working on arm. That means
> > the problem appears on at least to archs.
> >
> > >
> > > So, what I'm trying to do is mapping some physically continuous memory
> > > (allocated by kmalloc) to userspace, using a trivial UIO driver (the
> > > idea is that a device can directly DMA to that buffer):
> > >
> > > [...]
> > > #define MEM_SIZE (4 * PAGE_SIZE)
> > >
> > > addr = kmalloc(MEM_SIZE, GFP_KERNEL)
> > > [...]
> > > info.mem[0].addr = (unsigned long) addr;
> > > info.mem[0].internal_addr = addr;
> > > info.mem[0].size = MEM_SIZE;
> > > info.mem[0].memtype = UIO_MEM_LOGICAL;
> > > [...]
> > > ret = uio_register_device(&pdev->dev, &info);
> > >
> > > Userspace maps that memory range and writes its contents to a file:
> > >
> > > [...]
> > >
> > > fd = open("/dev/uio0", O_RDWR);
> > > if (fd < 0) {
> > > perror("Can't open UIO device\n");
> > > exit(1);
> > > }
> > >
> > > mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
> > > MAP_PRIVATE, fd, 0);
> > >
> > > if(mem_map == MAP_FAILED) {
> > > perror("Can't map UIO memory\n");
> > > ret = -ENOMEM;
> > > goto out_file;
> > > }
> > > [...]
> > > bytes_written = write(fd_file, mem_map, MAP_SIZE)
> > > [...]
> > >
> > > munmap(mem_map);
> >
> > >From my point of view (I've got Jan's full test case code), this
> > is a completely correct UIO use case.
> >
> > >
> > > So, what happens is (I'm currently testing with 3.0.3 on ARM
> > > VersatilePB): When I do the munmap(), I run into the following error:
> > >
> > > BUG: Bad page state in process uio_test pfn:078ed
> > > page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
> > > page flags: 0x284(referenced|slab|arch_1)
>
> PG_slab is set. The kernel is complaining because a page which was
> allocated via kmalloc/kmem_cache_alloc was directly passed to the page
> allocator for freeing. It should have been passed to kfree().
>
> Presumably the uio driver expects that its memory was allocated via
> alloc_pages(), not via kmalloc().
Thanks for that hint. I'll check and will update UIO documentation
accordingly if necessary.
BUT the following problems are still threatening my mental health:
If userspace gets a valid and working pointer from mmap(), it is
entitled to expect munmap() to work on that pointer, too, isn't it?
Shouldn't mmap() fail in such a case?
The kernel's behavior should be the same, no matter which SLAB or
SLUB is chosen.
Or am I following wrong philosophies?
Thanks,
Hans
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: bade page state while calling munmap() for kmalloc'ed UIO memory
@ 2011-09-01 18:55 ` Hans J. Koch
0 siblings, 0 replies; 7+ messages in thread
From: Hans J. Koch @ 2011-09-01 18:55 UTC (permalink / raw)
To: Andrew Morton; +Cc: Hans J. Koch, Jan Altenberg, linux-mm, b.spranger, LKML
On Wed, Aug 31, 2011 at 04:13:07PM -0700, Andrew Morton wrote:
> On Wed, 31 Aug 2011 11:58:25 +0200
> "Hans J. Koch" <hjk@hansjkoch.de> wrote:
>
> > On Mon, Aug 29, 2011 at 05:05:47PM +0200, Jan Altenberg wrote:
> >
> > [Since we got no reply on linux-mm, I added lkml and Andrew to Cc: (mm doesn't
> > seem to have a maintainer...)]
> >
> > > Hi,
> > >
> > > I'm currently analysing a problem similar to some mmap() issue reported
> > > in the past: https://lkml.org/lkml/2010/7/11/140
> >
> > The arch there was microblaze, and you are working on arm. That means
> > the problem appears on at least to archs.
> >
> > >
> > > So, what I'm trying to do is mapping some physically continuous memory
> > > (allocated by kmalloc) to userspace, using a trivial UIO driver (the
> > > idea is that a device can directly DMA to that buffer):
> > >
> > > [...]
> > > #define MEM_SIZE (4 * PAGE_SIZE)
> > >
> > > addr = kmalloc(MEM_SIZE, GFP_KERNEL)
> > > [...]
> > > info.mem[0].addr = (unsigned long) addr;
> > > info.mem[0].internal_addr = addr;
> > > info.mem[0].size = MEM_SIZE;
> > > info.mem[0].memtype = UIO_MEM_LOGICAL;
> > > [...]
> > > ret = uio_register_device(&pdev->dev, &info);
> > >
> > > Userspace maps that memory range and writes its contents to a file:
> > >
> > > [...]
> > >
> > > fd = open("/dev/uio0", O_RDWR);
> > > if (fd < 0) {
> > > perror("Can't open UIO device\n");
> > > exit(1);
> > > }
> > >
> > > mem_map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
> > > MAP_PRIVATE, fd, 0);
> > >
> > > if(mem_map == MAP_FAILED) {
> > > perror("Can't map UIO memory\n");
> > > ret = -ENOMEM;
> > > goto out_file;
> > > }
> > > [...]
> > > bytes_written = write(fd_file, mem_map, MAP_SIZE)
> > > [...]
> > >
> > > munmap(mem_map);
> >
> > >From my point of view (I've got Jan's full test case code), this
> > is a completely correct UIO use case.
> >
> > >
> > > So, what happens is (I'm currently testing with 3.0.3 on ARM
> > > VersatilePB): When I do the munmap(), I run into the following error:
> > >
> > > BUG: Bad page state in process uio_test pfn:078ed
> > > page:c0409154 count:0 mapcount:0 mapping: (null) index:0x0
> > > page flags: 0x284(referenced|slab|arch_1)
>
> PG_slab is set. The kernel is complaining because a page which was
> allocated via kmalloc/kmem_cache_alloc was directly passed to the page
> allocator for freeing. It should have been passed to kfree().
>
> Presumably the uio driver expects that its memory was allocated via
> alloc_pages(), not via kmalloc().
Thanks for that hint. I'll check and will update UIO documentation
accordingly if necessary.
BUT the following problems are still threatening my mental health:
If userspace gets a valid and working pointer from mmap(), it is
entitled to expect munmap() to work on that pointer, too, isn't it?
Shouldn't mmap() fail in such a case?
The kernel's behavior should be the same, no matter which SLAB or
SLUB is chosen.
Or am I following wrong philosophies?
Thanks,
Hans
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-09-01 18:55 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-29 15:05 bade page state while calling munmap() for kmalloc'ed UIO memory Jan Altenberg
2011-08-31 9:58 ` Hans J. Koch
2011-08-31 9:58 ` Hans J. Koch
2011-08-31 23:13 ` Andrew Morton
2011-08-31 23:13 ` Andrew Morton
2011-09-01 18:55 ` Hans J. Koch
2011-09-01 18:55 ` Hans J. Koch
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.