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(). */