Messages in this thread Patch in this message |  | | | Date | Wed, 23 Nov 2005 20:33:38 +0000 (GMT) | | From | Hugh Dickins <> | | 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 <mhf@berlios.de> 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 <hugh@veritas.com>
--- 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 - 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/
|  |