summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-04-17 10:04:55 -0700
committerZhenyu Wang <zhenyu.z.wang@intel.com>2008-04-21 15:06:47 +0800
commitf08aa4c291e4f5491372434e3ee08dfb15d5aa94 (patch)
treeb507c012a0a26e93a2235c5aa502f4e712eadeda
parent8187a5a16f8bd8f0ba5e7f5357f355928b3b8f07 (diff)
Add a kludge-around to fix cd/wt bits in fb ptes on linux.
Mmap from /sys/devices/pci* on linux forces the cache-disable and write-through bits, which turns our write-combining map into an uncached-map, seriously impacting performance. It turns out that a bug in mprotect allows us to fix this by disabling access to those pages and then immediately re-enabling them. (cherry picked from commit c3fb62df4e60b63295f94c99b3c5de70dbf94e1c)
-rw-r--r--configure.ac3
-rw-r--r--src/i830_driver.c10
2 files changed, 13 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 170d59b4..001e5e16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,6 +43,9 @@ AM_PROG_CC_C_O
AC_CHECK_PROG(gen4asm, [intel-gen4asm], yes, no)
AM_CONDITIONAL(HAVE_GEN4ASM, test x$gen4asm = xyes)
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_FUNCS(mprotect)
+
AH_TOP([#include "xorg-server.h"])
AC_ARG_WITH(xorg-module-dir,
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 41c0578a..f4046779 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -197,6 +197,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830_debug.h"
#include "i830_bios.h"
#include "i830_video.h"
+#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
+#include <sys/mman.h>
+#endif
#ifdef INTEL_XVMC
#define _INTEL_XVMC_SERVER_
@@ -685,6 +688,13 @@ I830MapMem(ScrnInfoPtr pScrn)
err = pci_device_map_range (device, pI830->LinearAddr, pI830->FbMapSize,
PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
(void **) &pI830->FbBase);
+ if (err)
+ return FALSE;
+ /* KLUDGE ALERT -- rewrite the PTEs to turn off the CD and WT bits */
+#if HAVE_MPROTECT
+ mprotect (pI830->FbBase, pI830->FbMapSize, PROT_NONE);
+ mprotect (pI830->FbBase, pI830->FbMapSize, PROT_READ|PROT_WRITE);
+#endif
#else
pI830->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
pI830->PciTag,