lkml.org 
[lkml]   [2003]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Linux 2.4.22-pre10-ac1 DRI doesn't work with


On 7 Aug 2003, Alan Cox wrote:

> On Mer, 2003-08-06 at 15:38, Mitch@0Bits.COM wrote:
> > I think with the new vmap changes that went in in -pre7 means
> > you will need to get a new drm module (like from X cvs or
> > http://dri.sourceforge.net/downloads.phtml) and recompile it
> > with the new kernel headers which will then pick up the define
> > -DVMAP_4_ARGS in the Makefile and give you a good module that works.
> >
> > The DRI kernel trees need updating.
>
> That doesn't seem a 2.4.22 candidate thing to me. If vmap broke the DRI
> then the vmap patch wants reverting for 2.4.22 IMHO, and looking at for
> 2.4.23.

I dont understand how the vmap change can break DRM.

The vmap patch only changes internal mm/vmalloc.c code (vmalloc() call
acts exactly the same way as before AFAICS).

Anyway, Mitch (or Erik who's seeing the problem), can please revert the
vmap() change to check if its causing the mentioned problem?

The patch is attached. Apply it with -R.
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1016.1.2 -> 1.1016.1.3
# kernel/ksyms.c 1.77 -> 1.78
# mm/vmalloc.c 1.15 -> 1.16
# include/linux/vmalloc.h 1.2 -> 1.3
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/07/18 hch@lst.de 1.1016.1.3
# [PATCH] vmap() backport
#
# Hi Marcelo,
#
# this patch backports vmap() from 2.5. vmap() is needed for
#
# - XFS
# - proper AGP support on ia64 and ppc
# (- latest ALSA seems to have some use for in on 2.5)
#
# the 2.4 implementation is not as sound as the 2.5 one but far less
# intrusive. It has been tested for more than a year in the XFS tree
# and -aa and in -ac for a while.
# --------------------------------------------
#
diff -Nru a/include/linux/vmalloc.h b/include/linux/vmalloc.h
--- a/include/linux/vmalloc.h Thu Aug 7 10:21:35 2003
+++ b/include/linux/vmalloc.h Thu Aug 7 10:21:35 2003
@@ -21,6 +21,9 @@

extern struct vm_struct * get_vm_area (unsigned long size, unsigned long flags);
extern void vfree(void * addr);
+#define vunmap(addr) vfree(addr)
+extern void * vmap(struct page **pages, int count,
+ unsigned long flags, pgprot_t prot);
extern void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot);
extern long vread(char *buf, char *addr, unsigned long count);
extern void vmfree_area_pages(unsigned long address, unsigned long size);
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c Thu Aug 7 10:21:35 2003
+++ b/kernel/ksyms.c Thu Aug 7 10:21:35 2003
@@ -112,6 +112,7 @@
EXPORT_SYMBOL(kfree);
EXPORT_SYMBOL(vfree);
EXPORT_SYMBOL(__vmalloc);
+EXPORT_SYMBOL(vmap);
EXPORT_SYMBOL(vmalloc_to_page);
EXPORT_SYMBOL(mem_map);
EXPORT_SYMBOL(remap_page_range);
diff -Nru a/mm/vmalloc.c b/mm/vmalloc.c
--- a/mm/vmalloc.c Thu Aug 7 10:21:35 2003
+++ b/mm/vmalloc.c Thu Aug 7 10:21:35 2003
@@ -93,7 +93,8 @@
}

static inline int alloc_area_pte (pte_t * pte, unsigned long address,
- unsigned long size, int gfp_mask, pgprot_t prot)
+ unsigned long size, int gfp_mask,
+ pgprot_t prot, struct page ***pages)
{
unsigned long end;

@@ -103,9 +104,20 @@
end = PMD_SIZE;
do {
struct page * page;
- spin_unlock(&init_mm.page_table_lock);
- page = alloc_page(gfp_mask);
- spin_lock(&init_mm.page_table_lock);
+
+ if (!pages) {
+ spin_unlock(&init_mm.page_table_lock);
+ page = alloc_page(gfp_mask);
+ spin_lock(&init_mm.page_table_lock);
+ } else {
+ page = (**pages);
+ (*pages)++;
+
+ /* Add a reference to the page so we can free later */
+ if (page)
+ atomic_inc(&page->count);
+
+ }
if (!pte_none(*pte))
printk(KERN_ERR "alloc_area_pte: page already exists\n");
if (!page)
@@ -117,7 +129,9 @@
return 0;
}

-static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, int gfp_mask, pgprot_t prot)
+static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address,
+ unsigned long size, int gfp_mask,
+ pgprot_t prot, struct page ***pages)
{
unsigned long end;

@@ -129,7 +143,8 @@
pte_t * pte = pte_alloc(&init_mm, pmd, address);
if (!pte)
return -ENOMEM;
- if (alloc_area_pte(pte, address, end - address, gfp_mask, prot))
+ if (alloc_area_pte(pte, address, end - address,
+ gfp_mask, prot, pages))
return -ENOMEM;
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
@@ -137,8 +152,11 @@
return 0;
}

-inline int vmalloc_area_pages (unsigned long address, unsigned long size,
- int gfp_mask, pgprot_t prot)
+static inline int __vmalloc_area_pages (unsigned long address,
+ unsigned long size,
+ int gfp_mask,
+ pgprot_t prot,
+ struct page ***pages)
{
pgd_t * dir;
unsigned long end = address + size;
@@ -155,7 +173,7 @@
break;

ret = -ENOMEM;
- if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot))
+ if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot, pages))
break;

address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -168,6 +186,12 @@
return ret;
}

+int vmalloc_area_pages(unsigned long address, unsigned long size,
+ int gfp_mask, pgprot_t prot)
+{
+ return __vmalloc_area_pages(address, size, gfp_mask, prot, NULL);
+}
+
struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
{
unsigned long addr, next;
@@ -246,7 +270,30 @@
if (!area)
return NULL;
addr = area->addr;
- if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) {
+ if (__vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask,
+ prot, NULL)) {
+ vfree(addr);
+ return NULL;
+ }
+ return addr;
+}
+
+void * vmap(struct page **pages, int count,
+ unsigned long flags, pgprot_t prot)
+{
+ void * addr;
+ struct vm_struct *area;
+ unsigned long size = count << PAGE_SHIFT;
+
+ if (!size || size > (max_mapnr << PAGE_SHIFT))
+ return NULL;
+ area = get_vm_area(size, flags);
+ if (!area) {
+ return NULL;
+ }
+ addr = area->addr;
+ if (__vmalloc_area_pages(VMALLOC_VMADDR(addr), size, 0,
+ prot, &pages)) {
vfree(addr);
return NULL;
}
\
 
 \ /
  Last update: 2005-03-22 13:47    [W:0.079 / U:0.592 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site