Here is the original patch comment, with my own comments below.
Please apply patch to 4.2.99.x, with plans of a better long term 
solution for the future planned for later.

===================================================================
Patch by Chris Ahna:
 
Fixes critical page size problems on ia64 architecture.  See
following URL for details:
 
https://external-lists.valinux.com/archives/linux-ia64/2001-August/002037.html
===================================================================
 
 

This probably should be rewritten to be outside of the drivers
themselves so that it doesn't have to be done per-driver.  I'm
applying this to our XFree86 for now however until I've got time
to investigate doing it more generically.  Architectures like 
Itanium, and Alpha, and probably many others as well do not use 
4Kb page size, at least not by default, and they may have a 
different page size from one machine to the next, or from one OS 
kernel build to the next.  Linux allows the page size to be 
configured at build time for processors that support it, however 
the current XFree86 source either hard codes a fixed page size, 
such as the case for Alpha, or uses a default of 4K which breaks 
on other architectures.  Some Alpha machines use 8Kb for example.

The proper long term fix for this IMHO is to make either a DRI 
global variable, or an X server global variable to store the 
architecture's pagesize and pagemask at server startup, and let 
drivers and modules use this information as needed.  I think the 
best place is probably in xf86Globals.c, but I want to 
investigate it more first.

The server should call an OS function to get the page size once 
only, and then everywhere that needs to know it should use the 
global.  There are 2 choices at least for this that I am aware 
of, and they are:

1) getpagesize()
2) setconf(_SC_PAGESIZE)

getpagesize() is considered legacy in POSIX, and not guaranteed 
to be on all systems.  HPUX does not have it for example.  
setconf(_SC_PAGESIZE) is defined by SuSv3 at least, and perhaps 
SuSv2 although I'd have to confirm that.

In order to maximize portability, it would be best to determine 
if the OS has setconf() and use it, and if not, to fall back to 
getpagesize() instead, and if that isn't supported, to perhaps 
allow 2 Imake defines to set the pagesize at buildtime.

The only problem I can see with this, is the case where 2 
operating systems both on the same architecture, where one 
supports setconf() lets say and the other does not.  If we hard 
code setconf on the OS building the X server, it is theoretically 
possible that it wont run on other OS's and thus break the binary 
compatibility across architectures idea.

Thinking about that some more, I decided that if the call is done
in the X server itself, it should not be a problem really because
it is the drivers that are cross OS in one arch, not the server
itself.  Also, to maximize portability anally, one could do a run
time test of return of getconf() and if not supported, fall back
to setconf() and then to hard coded compile time defaults.

Any comments about any of this?



-- 
Mike A. Harris     ftp://people.redhat.com/mharris
OS Systems Engineer - XFree86 maintainer - Red Hat
Patch by Chris Ahna:

Fixes critical page size problems on ia64 architecture.  See following URL for
details:

https://external-lists.valinux.com/archives/linux-ia64/2001-August/002037.html

Comment by [EMAIL PROTECTED]:

This probably should be rewritten to be outside of the drivers themselves so
that it doesn't have to be done per-driver.  I'm applying this to our
XFree86 for now however until I've got time to investigate doing it more
generically.

diff -ur xc/programs/Xserver/hw/xfree86/drivers/ati.ORIG/r128_dri.c 
xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c
--- xc/programs/Xserver/hw/xfree86/drivers/ati.ORIG/r128_dri.c  2002-10-20 
02:48:27.000000000 +0900
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c       2002-10-20 
+03:05:24.000000000 +0900
@@ -54,15 +54,7 @@
 #include "GL/glxtokens.h"
 #include "sarea.h"
 
-/* ?? HACK - for now, put this here... */
-/* ?? Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
-#if defined(__alpha__)
-# define DRM_PAGE_SIZE 8192
-#elif defined(__ia64__)
-# define DRM_PAGE_SIZE getpagesize()
-#else
-# define DRM_PAGE_SIZE 4096
-#endif
+static size_t r128_drm_page_size;
 
 /* Initialize the visual configs that are supported by the hardware.
    These are combined with the visual configs that the indirect
@@ -489,11 +481,11 @@
 
                                /* Initialize the CCE ring buffer data */
     info->ringStart       = info->agpOffset;
-    info->ringMapSize     = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+    info->ringMapSize     = info->ringSize*1024*1024 + r128_drm_page_size;
     info->ringSizeLog2QW  = R128MinBits(info->ringSize*1024*1024/8) - 1;
 
     info->ringReadOffset  = info->ringStart + info->ringMapSize;
-    info->ringReadMapSize = DRM_PAGE_SIZE;
+    info->ringReadMapSize = r128_drm_page_size;
 
                                /* Reserve space for vertex/indirect buffers */
     info->bufStart        = info->ringReadOffset + info->ringReadMapSize;
@@ -642,11 +634,11 @@
 
                                /* Initialize the CCE ring buffer data */
     info->ringStart       = info->agpOffset;
-    info->ringMapSize     = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+    info->ringMapSize     = info->ringSize*1024*1024 + r128_drm_page_size;
     info->ringSizeLog2QW  = R128MinBits(info->ringSize*1024*1024/8) - 1;
 
     info->ringReadOffset  = info->ringStart + info->ringMapSize;
-    info->ringReadMapSize = DRM_PAGE_SIZE;
+    info->ringReadMapSize = r128_drm_page_size;
 
                                /* Reserve space for vertex/indirect buffers */
     info->bufStart        = info->ringReadOffset + info->ringReadMapSize;
@@ -1003,6 +993,8 @@
        break;
     }
 
+    r128_drm_page_size = getpagesize();
+
     /* Create the DRI data structure, and fill it in before calling the
        DRIScreenInit(). */
     if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
diff -ur xc/programs/Xserver/hw/xfree86/drivers/ati.ORIG/radeon_dri.c 
xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
--- xc/programs/Xserver/hw/xfree86/drivers/ati.ORIG/radeon_dri.c        2002-10-20 
02:48:27.000000000 +0900
+++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c     2002-10-20 
+03:04:18.000000000 +0900
@@ -56,15 +56,7 @@
 #include "sarea.h"
 #include "radeon_sarea.h"
 
-/* HACK - for now, put this here... */
-/* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
-#if defined(__alpha__)
-# define DRM_PAGE_SIZE 8192
-#elif defined(__ia64__)
-# define DRM_PAGE_SIZE getpagesize()
-#else
-# define DRM_PAGE_SIZE 4096
-#endif
+static size_t radeon_drm_page_size;


 static Bool RADEONDRICloseFullScreen(ScreenPtr pScreen);
@@ -775,11 +767,11 @@
 
                                /* Initialize the CP ring buffer data */
     info->ringStart       = info->agpOffset;
-    info->ringMapSize     = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+    info->ringMapSize     = info->ringSize*1024*1024 + radeon_drm_page_size;
     info->ringSizeLog2QW  = RADEONMinBits(info->ringSize*1024*1024/8)-1;
 
     info->ringReadOffset  = info->ringStart + info->ringMapSize;
-    info->ringReadMapSize = DRM_PAGE_SIZE;
+    info->ringReadMapSize = radeon_drm_page_size;
 
                                /* Reserve space for vertex/indirect buffers */
     info->bufStart        = info->ringReadOffset + info->ringReadMapSize;
@@ -901,11 +893,11 @@
 
                                /* Initialize the CCE ring buffer data */
     info->ringStart       = info->agpOffset;
-    info->ringMapSize     = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
+    info->ringMapSize     = info->ringSize*1024*1024 + radeon_drm_page_size;
     info->ringSizeLog2QW  = RADEONMinBits(info->ringSize*1024*1024/8)-1;
 
     info->ringReadOffset  = info->ringStart + info->ringMapSize;
-    info->ringReadMapSize = DRM_PAGE_SIZE;
+    info->ringReadMapSize = radeon_drm_page_size;
 
                                /* Reserve space for vertex/indirect buffers */
     info->bufStart        = info->ringReadOffset + info->ringReadMapSize;
@@ -1219,6 +1211,8 @@
        break;
     }
 
+    radeon_drm_page_size = getpagesize();
+
     /* Create the DRI data structure, and fill it in before calling the
      * DRIScreenInit().
      */

Reply via email to