2005-11-18 19:16:59

by Hugh Dickins

[permalink] [raw]
Subject: 2.6.15-rc1-mm2 0x414 Bad page states

Thanks a lot for your PageReserved "Bad page state" reports.

Sorry for being so slow to respond. I've not worked it out yet.

Would each of you please apply the slightly-more-debug-info patch
below, and mail me the first batch of reports that you get when
you try to reproduce the problem (it does assume only one CPU,
which happens to be the case for each of you).

Thanks,
Hugh

--- 2.6.15-rc1-mm2/mm/memory.c 2005-11-18 15:23:09.000000000 +0000
+++ linux/mm/memory.c 2005-11-18 17:56:23.000000000 +0000
@@ -569,6 +569,7 @@ static unsigned long zap_pte_range(struc
unsigned long addr, unsigned long end,
long *zap_work, struct zap_details *details)
{
+ extern struct vm_area_struct *zap_vma;
struct mm_struct *mm = tlb->mm;
pte_t *pte;
spinlock_t *ptl;
@@ -576,6 +577,7 @@ static unsigned long zap_pte_range(struc
int anon_rss = 0;

pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ zap_vma = vma;
do {
pte_t ptent = *pte;
if (pte_none(ptent)) {
@@ -649,6 +651,7 @@ static unsigned long zap_pte_range(struc
pte_clear_full(mm, addr, pte, tlb->fullmm);
} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));

+ zap_vma = NULL;
add_mm_rss(mm, file_rss, anon_rss);
pte_unmap_unlock(pte - 1, ptl);

--- 2.6.15-rc1-mm2/mm/page_alloc.c 2005-11-18 15:23:09.000000000 +0000
+++ linux/mm/page_alloc.c 2005-11-18 18:16:28.000000000 +0000
@@ -36,6 +36,7 @@
#include <linux/memory_hotplug.h>
#include <linux/nodemask.h>
#include <linux/vmalloc.h>
+#include <linux/kallsyms.h>

#include <asm/tlbflush.h>
#include "internal.h"
@@ -122,6 +123,7 @@ static int bad_range(struct zone *zone,
return 0;
}

+struct vm_area_struct *zap_vma;
static void bad_page(const char *function, struct page *page)
{
printk(KERN_EMERG "Bad page state at %s (in process '%s', page %p)\n",
@@ -129,6 +131,13 @@ static void bad_page(const char *functio
printk(KERN_EMERG "flags:0x%0*lx mapping:%p mapcount:%d count:%d\n",
(int)(2*sizeof(unsigned long)), (unsigned long)page->flags,
page->mapping, page_mapcount(page), page_count(page));
+ if (zap_vma) {
+ printk(KERN_EMERG "vm_flags:0x%lx", zap_vma->vm_flags);
+ print_symbol(" %s", (unsigned long)
+ (zap_vma->vm_ops? zap_vma->vm_ops->open: NULL));
+ print_symbol(" %s\n", (unsigned long)
+ (zap_vma->vm_ops? zap_vma->vm_ops->nopage: NULL));
+ }
printk(KERN_EMERG "Backtrace:\n");
dump_stack();
{


2005-11-18 20:12:07

by Dominik Brodowski

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

Hi!

[4294995.698000] Bad page state at free_hot_cold_page (in process 'gaim', page c15eb020)
[4294995.698000] flags:0x80000414 mapping:00000000 mapcount:0 count:0
[4294995.698000] vm_flags:0x800fb snd_pcm_mmap_data_open+0x0/0x11 snd_pcm_mmap_data_nopage+0x0/0xa7
[4294995.698000] Backtrace:
[4294995.698000] [<c0103b59>] dump_stack+0x15/0x17
[4294995.698000] [<c0138ff1>] bad_page+0xab/0xe1
[4294995.698000] [<c01396d2>] free_hot_cold_page+0x5c/0xfe
[4294995.698000] [<c013977e>] free_hot_page+0xa/0xc
[4294995.698000] [<c013f03c>] __page_cache_release+0x8f/0x94
[4294995.698000] [<c013ed1f>] put_page+0x5b/0x5d
[4294995.698000] [<c0148dc9>] free_page_and_swap_cache+0x2c/0x2f
[4294995.698000] [<c014265e>] zap_pte_range+0x1aa/0x227
[4294995.698000] [<c0142779>] unmap_page_range+0x9e/0xe8
[4294995.698000] [<c0142886>] unmap_vmas+0xc3/0x199
[4294995.698000] [<c0145d57>] unmap_region+0x77/0xf2
[4294995.698000] [<c0145ff1>] do_munmap+0xdd/0xf3
[4294995.698000] [<c0146056>] sys_munmap+0x4f/0x68
[4294995.698000] [<c0102cab>] sysenter_past_esp+0x54/0x75
[4294995.698000] Trying to fix it up, but a reboot is needed
[4294995.698000] Bad page state at free_hot_cold_page (in process 'gaim', page c15eb040)
[4294995.698000] flags:0x80000414 mapping:00000000 mapcount:0 count:0
[4294995.698000] vm_flags:0x800fb snd_pcm_mmap_data_open+0x0/0x11 snd_pcm_mmap_data_nopage+0x0/0xa7
[4294995.698000] Backtrace:
[4294995.698000] [<c0103b59>] dump_stack+0x15/0x17
[4294995.698000] [<c0138ff1>] bad_page+0xab/0xe1
[4294995.698000] [<c01396d2>] free_hot_cold_page+0x5c/0xfe
[4294995.698000] [<c013977e>] free_hot_page+0xa/0xc
[4294995.698000] [<c013f03c>] __page_cache_release+0x8f/0x94
[4294995.698000] [<c013ed1f>] put_page+0x5b/0x5d
[4294995.698000] [<c0148dc9>] free_page_and_swap_cache+0x2c/0x2f
[4294995.698000] [<c014265e>] zap_pte_range+0x1aa/0x227
[4294995.698000] [<c0142779>] unmap_page_range+0x9e/0xe8
[4294995.698000] [<c0142886>] unmap_vmas+0xc3/0x199
[4294995.698000] [<c0145d57>] unmap_region+0x77/0xf2
[4294995.698000] [<c0145ff1>] do_munmap+0xdd/0xf3
[4294995.698000] [<c0146056>] sys_munmap+0x4f/0x68
[4294995.698000] [<c0102cab>] sysenter_past_esp+0x54/0x75

and so on.


0000:00:1f.5 Multimedia audio controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (rev 01)
0000:00:1f.6 Modem: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (rev 01)

readlink /sys/devices/pci0000\:00/0000\:00\:1f.5/driver
../../../bus/pci/drivers/Intel ICH
readlink /sys/devices/pci0000\:00/0000\:00\:1f.6/driver
../../../bus/pci/drivers/Intel ICH Modem


Thanks for taking care of this,
Dominik

2005-11-18 20:41:33

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

Hi,

On Friday, 18 of November 2005 21:12, Dominik Brodowski wrote:
> [4294995.698000] Bad page state at free_hot_cold_page (in process 'gaim', page c15eb020)
> [4294995.698000] flags:0x80000414 mapping:00000000 mapcount:0 count:0
> [4294995.698000] vm_flags:0x800fb snd_pcm_mmap_data_open+0x0/0x11 snd_pcm_mmap_data_nopage+0x0/0xa7

I've got pretty much the same:

Nov 18 21:23:22 albercik kernel: Bad page state at free_hot_cold_page (in process 'artsd', page ffff8100019613b8)
Nov 18 21:23:22 albercik kernel: flags:0x4000000000000414 mapping:0000000000000000 mapcount:0 count:0
Nov 18 21:23:22 albercik kernel: vm_flags:0x800fb snd_pcm_mmap_data_open+0x0/0x20 [snd_pcm] snd_pcm_mmap_data_nopage+0x0/0x150 [snd_pcm]
Nov 18 21:23:22 albercik kernel: Backtrace:
Nov 18 21:23:22 albercik kernel:
Nov 18 21:23:22 albercik kernel: Call Trace:<ffffffff80160a5e>{bad_page+238} <ffffffff80161094>{free_hot_cold_page+116}
Nov 18 21:23:22 albercik kernel: <ffffffff801611bb>{free_hot_page+11} <ffffffff80163cc9>{__page_cache_release+217}
Nov 18 21:23:22 albercik kernel: <ffffffff80163d56>{put_page+118} <ffffffff80172508>{free_page_and_swap_cache+56}
Nov 18 21:23:22 albercik kernel: <ffffffff80168fdf>{unmap_vmas+1391} <ffffffff8016c522>{unmap_region+178}
Nov 18 21:23:22 albercik kernel: <ffffffff8016d7be>{do_munmap+558} <ffffffff8016d8b0>{sys_munmap+80}
Nov 18 21:23:22 albercik kernel: <ffffffff8010eb5e>{system_call+126}
Nov 18 21:23:22 albercik kernel: ---------------------------
Nov 18 21:23:22 albercik kernel: | preempt count: 00000002 ]
Nov 18 21:23:26 albercik kernel: | 2 level deep critical section nesting:
Nov 18 21:23:27 albercik kernel: ----------------------------------------
Nov 18 21:23:28 albercik kernel: .. [<ffffffff8016c4c7>] .... unmap_region+0x57/0x150
Nov 18 21:23:29 albercik kernel: .....[<ffffffff8016d7be>] .. ( <= do_munmap+0x22e/0x2d0)
Nov 18 21:23:30 albercik kernel: .. [<ffffffff8035f2a6>] .... _spin_lock+0x16/0x30
Nov 18 21:23:30 albercik kernel: .....[<ffffffff80168e24>] .. ( <= unmap_vmas+0x3b4/0x790)
Nov 18 21:23:31 albercik kernel:
Nov 18 21:23:31 albercik kernel: Hexdump:
Nov 18 21:23:33 albercik kernel: 000: e8 0c 06 2b 00 81 ff ff 14 04 00 00 00 00 00 40
Nov 18 21:23:35 albercik kernel: 010: 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00
Nov 18 21:23:36 albercik kernel: 020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Nov 18 21:23:36 albercik kernel: 030: 00 01 10 00 00 00 00 00 00 02 20 00 00 00 00 00
Nov 18 21:23:36 albercik kernel: 040: 14 04 00 00 00 00 00 40 ff ff ff ff ff ff ff ff
Nov 18 21:23:37 albercik kernel: 050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Nov 18 21:23:37 albercik kernel: 060: 00 00 00 00 00 00 00 00 e0 13 96 01 00 81 ff ff
Nov 18 21:23:38 albercik kernel: 070: e0 13 96 01 00 81 ff ff 14 04 00 00 00 00 00 40
Nov 18 21:23:38 albercik kernel: 080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Nov 18 21:23:41 albercik kernel: 090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Nov 18 21:23:45 albercik kernel: 0a0: 18 14 96 01 00 81 ff ff 18 14 96 01 00 81 ff ff
Nov 18 21:23:46 albercik kernel: 0b0: 14 04 00 00 00 00 00 40 00 00 00 00 00 00 00 00
Nov 18 21:23:51 albercik kernel: Trying to fix it up, but a reboot is needed

and so forth.

> 0000:00:1f.5 Multimedia audio controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (rev 01)
> 0000:00:1f.6 Modem: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller (rev 01)
>
> readlink /sys/devices/pci0000\:00/0000\:00\:1f.5/driver
> ../../../bus/pci/drivers/Intel ICH
> readlink /sys/devices/pci0000\:00/0000\:00\:1f.6/driver
> ../../../bus/pci/drivers/Intel ICH Modem

0000:00:06.0 Multimedia audio controller: nVidia Corporation nForce3 Audio (rev a2)

albercik:~ # readlink /sys/devices/pci0000\:00/0000\:00\:06.0/driver
../../../bus/pci/drivers/Intel ICH

> Thanks for taking care of this,

Ditto. :-)

Greetings,
Rafael

2005-11-19 04:28:44

by Nick Piggin

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

Index: linux-2.6/sound/core/pcm_native.c
===================================================================
--- linux-2.6.orig/sound/core/pcm_native.c 2005-10-09 18:28:51.000000000 +1000
+++ linux-2.6/sound/core/pcm_native.c 2005-11-19 15:29:59.000000000 +1100
@@ -2949,8 +2949,7 @@ static struct page * snd_pcm_mmap_status
return NOPAGE_OOM;
runtime = substream->runtime;
page = virt_to_page(runtime->status);
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
@@ -2992,8 +2991,7 @@ static struct page * snd_pcm_mmap_contro
return NOPAGE_OOM;
runtime = substream->runtime;
page = virt_to_page(runtime->control);
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
@@ -3066,8 +3064,7 @@ static struct page *snd_pcm_mmap_data_no
vaddr = runtime->dma_area + offset;
page = virt_to_page(vaddr);
}
- if (!PageReserved(page))
- get_page(page);
+ get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;


Attachments:
snd-pcm-refcount.patch (1.04 kB)

2005-11-19 04:31:06

by Nick Piggin

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

Nick Piggin wrote:

>
> These look like they want the following patch. Does it help?
>

Wait sorry, I was looking at an old kernel. Patch obviously won't
help.

--
SUSE Labs, Novell Inc.

Send instant messages to your online friends http://au.messenger.yahoo.com

2005-11-19 19:56:58

by Hugh Dickins

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

On Fri, 18 Nov 2005, Hugh Dickins wrote:
>
> Thanks for the info you've sent so far, implicating
> snd_pcm_mmap_data_nopage. But I've still not got it. Will resume
> tomorrow. If you can, would you please each send me your .config
> and your full startup dmesg (in case they help to focus me on which
> paths to look down in sound). You needn't spam akpm or lkml with them.

And thanks for the further info you sent, which allowed me to rebuild my
kernel to reproduce the problem easily with artsd. Though the answer was
staring me in the face from the first info you sent (and did occasionally
flit through my mind without being properly swatted), even in my Subject
line above: why were the page flags 0x414 instead of 0x4414 i.e. what had
happened to the PageCompound flag which I thought one of my patches was
adding?

Whoops, I'd completely missed that now we have to pass __GFP_COMP to
turn on that behaviour, because there are or were a few other places
which get confused by compound page behaviour. There's an excellent,
illuminating, prescient comment on compound pages by Andrew in
ChangeLog-2.6.6: but though he there foresees sound DMA buffers needing
it, I've a suspicion that DRM and some others might also be needing it.

So I'll go on a trawl through the source before finalizing the fix,
but below is the patch you guys need. Does this patch deal with your
Bad page states too, Marc? Does it help your mouse at all somehow?

Hugh

--- 2.6.15-rc1-mm2/sound/core/memalloc.c 2005-11-12 09:01:28.000000000 +0000
+++ linux/sound/core/memalloc.c 2005-11-19 19:03:32.000000000 +0000
@@ -197,6 +197,7 @@ void *snd_malloc_pages(size_t size, gfp_

snd_assert(size > 0, return NULL);
snd_assert(gfp_flags != 0, return NULL);
+ gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
pg = get_order(size);
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) {
mark_pages(virt_to_page(res), pg);
@@ -241,6 +242,7 @@ static void *snd_malloc_dev_pages(struct
snd_assert(dma != NULL, return NULL);
pg = get_order(size);
gfp_flags = GFP_KERNEL
+ | __GFP_COMP /* compound page lets parts be mapped */
| __GFP_NORETRY /* don't trigger OOM-killer */
| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);

2005-11-19 22:42:16

by Dominik Brodowski

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

On Sat, Nov 19, 2005 at 07:57:02PM +0000, Hugh Dickins wrote:
> So I'll go on a trawl through the source before finalizing the fix,
> but below is the patch you guys need. Does this patch deal with your
> Bad page states too, Marc? Does it help your mouse at all somehow?

Works for me.

Thanks,
Dominik

2005-11-20 18:38:32

by Marc Burkhardt

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

* Hugh Dickins <[email protected]> [2005-11-19 19:57:02 +0000]:

> On Fri, 18 Nov 2005, Hugh Dickins wrote:
> >
> > Thanks for the info you've sent so far, implicating
> > snd_pcm_mmap_data_nopage. But I've still not got it. Will resume
> > tomorrow. If you can, would you please each send me your .config
> > and your full startup dmesg (in case they help to focus me on which
> > paths to look down in sound). You needn't spam akpm or lkml with them.
>
> And thanks for the further info you sent, which allowed me to rebuild my
> kernel to reproduce the problem easily with artsd. Though the answer was
> staring me in the face from the first info you sent (and did occasionally
> flit through my mind without being properly swatted), even in my Subject
> line above: why were the page flags 0x414 instead of 0x4414 i.e. what had
> happened to the PageCompound flag which I thought one of my patches was
> adding?
>
> Whoops, I'd completely missed that now we have to pass __GFP_COMP to
> turn on that behaviour, because there are or were a few other places
> which get confused by compound page behaviour. There's an excellent,
> illuminating, prescient comment on compound pages by Andrew in
> ChangeLog-2.6.6: but though he there foresees sound DMA buffers needing
> it, I've a suspicion that DRM and some others might also be needing it.
>
> So I'll go on a trawl through the source before finalizing the fix,
> but below is the patch you guys need. Does this patch deal with your
> Bad page states too, Marc? Does it help your mouse at all somehow?
>

Sorry for the late reply. I was just busy but I'll make the best out of
the sunday morning. :)

After applying the patch the console was quite clean as it used to be.
Thus it seems to work for me as well.

Thanks Hugh,
Marc

2005-11-21 13:03:25

by Christian Kujau

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

Hugh Dickins schrieb:
> So I'll go on a trawl through the source before finalizing the fix,
> but below is the patch you guys need. Does this patch deal with your
> Bad page states too, Marc? Does it help your mouse at all somehow?

yes, it fixes the very same issue (Bad page states) here too.

thank you,
Christian.
--
BOFH excuse #396:

Mail server hit by UniSpammer.

2005-11-22 21:32:43

by Hugh Dickins

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

On Tue, 22 Nov 2005, Michael Frank wrote:
>
> I am getting this also with i810 drm in Vanilla 2.6.15-rc2
> upon exiting apps such as supertux.

Aha, perhaps you're the one we've been waiting for. I've suspected
a DRM issue, but nobody has actually seen one until now, and I didn't
want to put in a patch without live justification.

Would you please try the patch below, and let us know if it fixes your
problem. If so, I'll send it off to Andrew and Linus: the rest of the
PageReserved fixes, including the sound driver Bad page state fixes,
have gone into Linus' git tree today: perhaps this is the missing piece.

If this does not work for you, then presumably you'd be another sound
driver sufferer? and I should send you that patch (or you pick it up
from yesterday's LKML). But right now I'd selfishly like you to test
just this DRM patch below.

Thanks,
Hugh

--- 2.6.15-rc2/drivers/char/drm/drm_memory.c 2005-11-20 19:43:39.000000000 +0000
+++ linux/drivers/char/drm/drm_memory.c 2005-11-21 10:10:45.000000000 +0000
@@ -95,7 +95,7 @@ unsigned long drm_alloc_pages(int order,
unsigned long addr;
unsigned int sz;

- address = __get_free_pages(GFP_KERNEL, order);
+ address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
if (!address)
return 0;

--- 2.6.15-rc2/drivers/char/drm/drm_memory_debug.h 2005-11-20 19:43:39.000000000 +0000
+++ linux/drivers/char/drm/drm_memory_debug.h 2005-11-21 10:11:04.000000000 +0000
@@ -221,7 +221,7 @@ unsigned long DRM(alloc_pages) (int orde
}
spin_unlock(&DRM(mem_lock));

- address = __get_free_pages(GFP_KERNEL, order);
+ address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
if (!address) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[area].fail_count;

2005-11-23 11:07:43

by Dave Airlie

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

On 11/23/05, Michael Frank <[email protected]> wrote:
> On Tuesday 22 November 2005 22:32, Hugh Dickins wrote:
> > On Tue, 22 Nov 2005, Michael Frank wrote:
> > > I am getting this also with i810 drm in Vanilla
> > > 2.6.15-rc2 upon exiting apps such as supertux.
> >
> > Aha, perhaps you're the one we've been waiting for. I've
> > suspected a DRM issue, but nobody has actually seen one
> > until now, and I didn't want to put in a patch without
> > live justification.
> >
> > Would you please try the patch below, and let us know if
> > it fixes your problem. If so, I'll send it off to Andrew
> > and Linus: the rest of the PageReserved fixes, including
> > the sound driver Bad page state fixes, have gone into
> > Linus' git tree today: perhaps this is the missing piece.
> >
> > If this does not work for you, then presumably you'd be
> > another sound driver sufferer? and I should send you
> > that patch (or you pick it up from yesterday's LKML).
> > But right now I'd selfishly like you to test just this
> > DRM patch below.
> >
> > Thanks,
> > Hugh
>
> Your patch fixed the DRM issue.
>
> I also applied the patch (below) posted by you earlier to fix sound issues.
>

I'm at a bit of a loss how this can fix the i810 driver, but maybe I'm
missing something, I'm having a look at the drm_pci_alloc code that
calls pci_alloc_consistent, it may have an issue also (Hugh??)

I've queued up the patch for Linus, along with a couple of other bugfixes...

Dave.

2005-11-23 20:33:36

by Hugh Dickins

[permalink] [raw]
Subject: Re: 2.6.15-rc1-mm2 0x414 Bad page states

On Wed, 23 Nov 2005, Dave Airlie wrote:
> On 11/23/05, Michael Frank <[email protected]> wrote:
> >
> > Your patch fixed the DRM issue.

Thanks a lot for the testing and feedback, Michael.

> I'm at a bit of a loss how this can fix the i810 driver, but maybe I'm
> missing something,

I presume it's going the drm_do_vm_dma_nopage route, and the pages
in the pagelist (though each PAGE_SIZEd itself) have been allocated
from >0-order pages.

> I'm having a look at the drm_pci_alloc code that
> calls pci_alloc_consistent, it may have an issue also (Hugh??)

Just when I thought I could get away from DRM! I've spent a while
groping around there again, and I believe you're right that there
is an issue with drm_pci_alloc too, but that it's not a new issue.

Not a new issue because we've only been changing the behaviour of
PageReserved, and there was no PageReservation around drm_pci_alloc.

But an issue, yes, because pci_alloc_consistent is likely to supply
a >0-order page, with latter constituent 0-order pages having count 0.

Hmm, could this have caused some of my mm/rmap.c BUG_ONs in the past?
Not very likely, I think; but it's not immediately obvious quite how
it would have behaved; certainly "Bad page states" a possibility
(even before the recent changes).

Below is a cowardly patch which I believe will correct this: since
nopage will be a problem here, just go the remap_pfn_range way instead.

I'm not proud of coming up with different adhoc solutions to different
manifestations of the same underlying problem, but pci_alloc_consistent
depends on the architecture, I don't want to go there. Uncompiled,
untested, see what you think.

Though two worries noticed on the way. One, there's drm_addbufs_pci:
that's a bit confusingly named, isn't it, since it's working on the
DMA pagelist, and unrelated to drm_pci_alloc? Two, is it right that
only _DRM_SHM and _DRM_CONSISTENT end up using drm_vm_shm_close,
which does cleanup which the others miss by using drm_vm_close?
No need to explain why I'm wrong! just mentioned in case it's wrong.

> I've queued up the patch for Linus, along with a couple of other bugfixes...

Thanks for looking after that, Dave. Please take care of this one too,
if you agree it's the right thing to do...

_DRM_CONSISTENT memory is allocated in one range by pci_alloc_consistent,
and is therefore likely to be a >0-order page, whose constituent 0-order
pages should not be exposed to nopage and freeing: use remap_pfn_range.

Signed-off-by: Hugh Dickins <[email protected]>

--- 2.6.15-rc2-git3/drivers/char/drm/drm_vm.c 2005-11-20 19:43:39.000000000 +0000
+++ linux/drivers/char/drm/drm_vm.c 2005-11-23 19:15:58.000000000 +0000
@@ -154,8 +154,7 @@ static __inline__ struct page *drm_do_vm

offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
- page = (map->type == _DRM_CONSISTENT) ?
- virt_to_page((void *)i) : vmalloc_to_page((void *)i);
+ page = vmalloc_to_page((void *)i);
if (!page)
return NOPAGE_OOM;
get_page(page);
@@ -636,10 +635,16 @@ int drm_mmap(struct file *filp, struct v
vma->vm_start, vma->vm_end, map->offset + offset);
vma->vm_ops = &drm_vm_ops;
break;
- case _DRM_SHM:
case _DRM_CONSISTENT:
- /* Consistent memory is really like shared memory. It's only
- * allocate in a different way */
+ /* Consistent memory is really like shared memory. But
+ * it's allocated in a different way, so avoid nopage */
+ if (remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(virt_to_page(map->handle)),
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ /* fall through to _DRM_SHM... */
+ case _DRM_SHM:
vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map;
/* Don't let this area swap. Change when