From 1f9a5307acfe2ef0d104f7036d2d93504dc7673f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 26 Jun 2008 09:35:14 -0700 Subject: [intel-gem] typo fix in DRM_ERROR --- linux-core/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 8fd2b8a6..446c9ba9 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -2394,7 +2394,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, int ret; if (dev_priv->mm.wedged) { - DRM_ERROR("Renabling wedged hardware, good luck\n"); + DRM_ERROR("Reenabling wedged hardware, good luck\n"); dev_priv->mm.wedged = 0; } -- cgit v1.2.3 From a0474be4e78d678eb615b37aad355effb955ee19 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 11 Jul 2008 14:47:33 -0700 Subject: intel-gem: Add two new ioctls for managing tiling on objects. Various chips have exciting interactions between the CPU and the GPU's different ways of accessing interleaved memory, so we need some kernel assistance in determining how it works. Only fully tested on GM965 so far. --- linux-core/i915_gem.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 446c9ba9..236203a5 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -2702,3 +2702,18 @@ i915_gem_lastclose(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); } + +void i915_gem_load(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + INIT_LIST_HEAD(&dev_priv->mm.active_list); + INIT_LIST_HEAD(&dev_priv->mm.flushing_list); + INIT_LIST_HEAD(&dev_priv->mm.inactive_list); + INIT_LIST_HEAD(&dev_priv->mm.request_list); + INIT_DELAYED_WORK(&dev_priv->mm.retire_work, + i915_gem_retire_work_handler); + dev_priv->mm.next_gem_seqno = 1; + + i915_gem_detect_bit_6_swizzle(dev); +} -- cgit v1.2.3 From 4d83a751b421ec3f3e0c572070c3bc295b9adbcc Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 18 Jul 2008 12:42:43 -0700 Subject: drm-gem: Fix build On some distros missing prototypes cause kernel builds to fail. These are hack to make the code build. --- linux-core/i915_gem.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 236203a5..fff2074e 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -30,6 +30,7 @@ #include "drm_compat.h" #include "i915_drm.h" #include "i915_drv.h" +#include #define WATCH_COHERENCY 0 #define WATCH_BUF 0 -- cgit v1.2.3 From 67d15215660407b07265c37d60ea5cac8930cef9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 1 Jul 2008 12:31:37 -0700 Subject: intel-gem: Set up HWS when it needs a vaddr during GEM init. This requires an updated 2D driver to not try to set it up as well. --- linux-core/i915_gem.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index fff2074e..b4c478f5 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -2311,6 +2311,56 @@ i915_gem_idle(struct drm_device *dev) return 0; } +static int +i915_gem_init_hws(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + int ret; + + /* If we need a physical address for the status page, it's already + * initialized at driver load time. + */ + if (!I915_NEED_GFX_HWS(dev)) + return 0; + + obj = drm_gem_object_alloc(dev, 4096); + if (obj == NULL) { + DRM_ERROR("Failed to allocate status page\n"); + return -ENOMEM; + } + obj_priv = obj->driver_private; + + ret = i915_gem_object_pin(obj, 4096); + if (ret != 0) { + drm_gem_object_unreference(obj); + return ret; + } + + dev_priv->status_gfx_addr = obj_priv->gtt_offset; + dev_priv->hws_map.offset = dev->agp->base + obj_priv->gtt_offset; + dev_priv->hws_map.size = 4096; + dev_priv->hws_map.type = 0; + dev_priv->hws_map.flags = 0; + dev_priv->hws_map.mtrr = 0; + + drm_core_ioremap(&dev_priv->hws_map, dev); + if (dev_priv->hws_map.handle == NULL) { + DRM_ERROR("Failed to map status page.\n"); + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + drm_gem_object_unreference(obj); + return -EINVAL; + } + dev_priv->hws_obj = obj; + dev_priv->hw_status_page = dev_priv->hws_map.handle; + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); + DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); + + return 0; +} + static int i915_gem_init_ringbuffer(struct drm_device *dev) { @@ -2319,6 +2369,10 @@ i915_gem_init_ringbuffer(struct drm_device *dev) struct drm_i915_gem_object *obj_priv; int ret; + ret = i915_gem_init_hws(dev); + if (ret != 0) + return ret; + obj = drm_gem_object_alloc(dev, 128 * 1024); if (obj == NULL) { DRM_ERROR("Failed to allocate ringbuffer\n"); @@ -2383,8 +2437,18 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) i915_gem_object_unpin(dev_priv->ring.ring_obj); drm_gem_object_unreference(dev_priv->ring.ring_obj); - + dev_priv->ring.ring_obj = NULL; memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + + if (dev_priv->hws_obj != NULL) { + i915_gem_object_unpin(dev_priv->hws_obj); + drm_gem_object_unreference(dev_priv->hws_obj); + dev_priv->hws_obj = NULL; + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + + /* Write high address into HWS_PGA when disabling. */ + I915_WRITE(HWS_PGA, 0x1ffff000); + } } int -- cgit v1.2.3 From a5d8f35f0fa651fbe8ca2897875ba188ca7dcda5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 Jul 2008 14:33:55 -0700 Subject: intel-gem: Move /proc debugging to a separate file. --- linux-core/i915_gem.c | 257 -------------------------------------------------- 1 file changed, 257 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index b4c478f5..c5c68af9 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -2492,263 +2492,6 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, return 0; } -static int i915_gem_active_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Active:\n"); - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, - list) - { - struct drm_gem_object *obj = obj_priv->obj; - if (obj->name) { - DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", - obj, obj->name, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } else { - DRM_PROC_PRINT(" %p: %08x %08x %d\n", - obj, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_flushing_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Flushing:\n"); - list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, - list) - { - struct drm_gem_object *obj = obj_priv->obj; - if (obj->name) { - DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", - obj, obj->name, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } else { - DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_inactive_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Inactive:\n"); - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, - list) - { - struct drm_gem_object *obj = obj_priv->obj; - if (obj->name) { - DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n", - obj, obj->name, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } else { - DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj, - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - } - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_request_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_request *gem_request; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Request:\n"); - list_for_each_entry(gem_request, &dev_priv->mm.request_list, - list) - { - DRM_PROC_PRINT (" %d @ %d %08x\n", - gem_request->seqno, - (int) (jiffies - gem_request->emitted_jiffies), - gem_request->flush_domains); - } - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static int i915_gem_seqno_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev)); - DRM_PROC_PRINT("Waiter sequence: %d\n", dev_priv->mm.waiting_gem_seqno); - DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - - -static int i915_interrupt_info(char *buf, char **start, off_t offset, - int request, int *eof, void *data) -{ - struct drm_minor *minor = (struct drm_minor *) data; - struct drm_device *dev = minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int len = 0; - - if (offset > DRM_PROC_LIMIT) { - *eof = 1; - return 0; - } - - *start = &buf[offset]; - *eof = 0; - DRM_PROC_PRINT("Interrupt enable: %08x\n", - I915_READ(I915REG_INT_ENABLE_R)); - DRM_PROC_PRINT("Interrupt identity: %08x\n", - I915_READ(I915REG_INT_IDENTITY_R)); - DRM_PROC_PRINT("Interrupt mask: %08x\n", - I915_READ(I915REG_INT_MASK_R)); - DRM_PROC_PRINT("Pipe A stat: %08x\n", - I915_READ(I915REG_PIPEASTAT)); - DRM_PROC_PRINT("Pipe B stat: %08x\n", - I915_READ(I915REG_PIPEBSTAT)); - DRM_PROC_PRINT("Interrupts received: %d\n", - atomic_read(&dev_priv->irq_received)); - DRM_PROC_PRINT("Current sequence: %d\n", - i915_get_gem_seqno(dev)); - DRM_PROC_PRINT("Waiter sequence: %d\n", - dev_priv->mm.waiting_gem_seqno); - DRM_PROC_PRINT("IRQ sequence: %d\n", - dev_priv->mm.irq_gem_seqno); - if (len > request + offset) - return request; - *eof = 1; - return len - offset; -} - -static struct drm_proc_list { - const char *name; /**< file name */ - int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ -} i915_gem_proc_list[] = { - {"i915_gem_active", i915_gem_active_info}, - {"i915_gem_flushing", i915_gem_flushing_info}, - {"i915_gem_inactive", i915_gem_inactive_info}, - {"i915_gem_request", i915_gem_request_info}, - {"i915_gem_seqno", i915_gem_seqno_info}, - {"i915_gem_interrupt", i915_interrupt_info}, -}; - -#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list) - -int i915_gem_proc_init(struct drm_minor *minor) -{ - struct proc_dir_entry *ent; - int i, j; - - for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) { - ent = create_proc_entry(i915_gem_proc_list[i].name, - S_IFREG | S_IRUGO, minor->dev_root); - if (!ent) { - DRM_ERROR("Cannot create /proc/dri/.../%s\n", - i915_gem_proc_list[i].name); - for (j = 0; j < i; j++) - remove_proc_entry(i915_gem_proc_list[i].name, - minor->dev_root); - return -1; - } - ent->read_proc = i915_gem_proc_list[i].f; - ent->data = minor; - } - return 0; -} - -void i915_gem_proc_cleanup(struct drm_minor *minor) -{ - int i; - - if (!minor->dev_root) - return; - - for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) - remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root); -} - void i915_gem_lastclose(struct drm_device *dev) { -- cgit v1.2.3 From bddb952578d58c4dcfafe969c045a39d27666b56 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 23 Jul 2008 08:36:54 -0700 Subject: intel-gem: Don't do the GTT-pwrite shortcut on tiled buffers. These will be covered by the fence, while pread/pwrite are supposed to be CPU-perspective writes, with manual detiling done by the client. --- linux-core/i915_gem.c | 110 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 25 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index c5c68af9..ca2dd19c 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -165,18 +165,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, #include "drm_compat.h" -/** - * Writes data to the object referenced by handle. - * - * On error, the contents of the buffer that were to be modified are undefined. - */ -int -i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) +static int +i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file_priv) { - struct drm_i915_gem_pwrite *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj_priv = obj->driver_private; ssize_t remain; loff_t offset; char __user *user_data; @@ -186,18 +180,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, unsigned long pfn; unsigned long unwritten; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EINVAL; - - /** Bounds check destination. - * - * XXX: This could use review for overflow issues... - */ - if (args->offset > obj->size || args->size > obj->size || - args->offset + args->size > obj->size) - return -EFAULT; - user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; if (!access_ok(VERIFY_READ, user_data, remain)) @@ -207,7 +189,6 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); ret = i915_gem_object_pin(obj, 0); if (ret) { - drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); return ret; } @@ -283,13 +264,92 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, fail: i915_gem_object_unpin (obj); - drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); + return ret; +} + +int +i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file_priv) +{ + int ret; + loff_t offset; + ssize_t written; + + mutex_lock(&dev->struct_mutex); + + ret = i915_gem_set_domain(obj, file_priv, + I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); + if (ret) { + mutex_unlock(&dev->struct_mutex); + return ret; + } + + offset = args->offset; + + written = vfs_write(obj->filp, + (char __user *)(uintptr_t) args->data_ptr, + args->size, &offset); + if (written != args->size) { + mutex_unlock(&dev->struct_mutex); + if (written < 0) + return written; + else + return -EINVAL; + } + + mutex_unlock(&dev->struct_mutex); + + return 0; +} + +/** + * Writes data to the object referenced by handle. + * + * On error, the contents of the buffer that were to be modified are undefined. + */ +int +i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_pwrite *args = data; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + int ret = 0; + + obj = drm_gem_object_lookup(dev, file_priv, args->handle); + if (obj == NULL) + return -EINVAL; + obj_priv = obj->driver_private; + + /** Bounds check destination. + * + * XXX: This could use review for overflow issues... + */ + if (args->offset > obj->size || args->size > obj->size || + args->offset + args->size > obj->size) + return -EFAULT; + + /* We can only do the GTT pwrite on untiled buffers, as otherwise + * it would end up going through the fenced access, and we'll get + * different detiling behavior between reading and writing. + * pread/pwrite currently are reading and writing from the CPU + * perspective, requiring manual detiling by the client. + */ + if (obj_priv->tiling_mode == I915_TILING_NONE) + ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); + else + ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); + #if WATCH_PWRITE if (ret) DRM_INFO("pwrite failed %d\n", ret); #endif + + drm_gem_object_unreference(obj); + return ret; } -- cgit v1.2.3 From 439d7106832f2e9742deb900d96f1d3bc07162b1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 23 Jul 2008 10:07:16 -0700 Subject: intel-gem: Add a quick hack to reduce clflushing on pread. This increases overhead for the large-readpixels case due to the repeated page cache accessing, but greatly reduces overhead for the small-readpixels case. --- linux-core/i915_gem.c | 57 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index ca2dd19c..db068ce3 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -55,6 +55,9 @@ i915_gem_set_domain(struct drm_gem_object *obj, struct drm_file *file_priv, uint32_t read_domains, uint32_t write_domain); +static int i915_gem_object_get_page_list(struct drm_gem_object *obj); +static void i915_gem_object_free_page_list(struct drm_gem_object *obj); +static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static void i915_gem_clflush_object(struct drm_gem_object *obj); @@ -128,6 +131,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_pread *args = data; struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; ssize_t read; loff_t offset; int ret; @@ -135,15 +139,52 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; + obj_priv = obj->driver_private; - mutex_lock(&dev->struct_mutex); - ret = i915_gem_set_domain(obj, file_priv, - I915_GEM_DOMAIN_CPU, 0); - if (ret) { + /* Bounds check source. + * + * XXX: This could use review for overflow issues... + */ + if (args->offset > obj->size || args->size > obj->size || + args->offset + args->size > obj->size) { drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; + return -EFAULT; + } + + mutex_lock(&dev->struct_mutex); + + /* Do a partial equivalent of i915_gem_set_domain(CPU, 0), as + * we don't want to clflush whole objects to read a portion of them. + * + * The side effect of doing this is that repeated preads of the same + * contents would take extra clflush overhead, since we don't track + * flushedness on a page basis. + */ + if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { + ret = i915_gem_object_wait_rendering(obj); + if (ret) { + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); + return ret; + } } + if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { + int got_page_list = 0; + int first_page = args->offset / PAGE_SIZE; + int last_page = (args->offset + args->size) / PAGE_SIZE; + + if (obj_priv->page_list == NULL) { + i915_gem_object_get_page_list(obj); + got_page_list = 1; + } + + drm_ttm_cache_flush(&obj_priv->page_list[first_page], + last_page - first_page + 1); + + if (got_page_list) + i915_gem_object_free_page_list(obj); + } + offset = args->offset; read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr, @@ -329,8 +370,10 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * XXX: This could use review for overflow issues... */ if (args->offset > obj->size || args->size > obj->size || - args->offset + args->size > obj->size) + args->offset + args->size > obj->size) { + drm_gem_object_unreference(obj); return -EFAULT; + } /* We can only do the GTT pwrite on untiled buffers, as otherwise * it would end up going through the fenced access, and we'll get -- cgit v1.2.3 From 6d258ddf7715412e2fb6fae35ea28d49c57ee130 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 23 Jul 2008 11:49:25 -0700 Subject: intel-gem: Fix pread math and logic errors. Fixes an oops in fbotexture from walking off the end of the page list. --- linux-core/i915_gem.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index db068ce3..e4697427 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -169,20 +169,16 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, } } if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { - int got_page_list = 0; int first_page = args->offset / PAGE_SIZE; - int last_page = (args->offset + args->size) / PAGE_SIZE; + int last_page = (args->offset + args->size - 1) / PAGE_SIZE; - if (obj_priv->page_list == NULL) { - i915_gem_object_get_page_list(obj); - got_page_list = 1; - } + /* If we don't have the page list, the pages are unpinned + * and swappable, and thus should already be in the CPU domain. + */ + BUG_ON(obj_priv->page_list == NULL); drm_ttm_cache_flush(&obj_priv->page_list[first_page], last_page - first_page + 1); - - if (got_page_list) - i915_gem_object_free_page_list(obj); } offset = args->offset; -- cgit v1.2.3 From 04ae66db1c517264cddc786be962fdd393c9c8ac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 26 Jul 2008 19:51:58 -0700 Subject: intel-gem: Move debug-only functions to a separate file. --- linux-core/i915_gem.c | 185 +------------------------------------------------- 1 file changed, 1 insertion(+), 184 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index e4697427..4087854c 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -32,20 +32,6 @@ #include "i915_drv.h" #include -#define WATCH_COHERENCY 0 -#define WATCH_BUF 0 -#define WATCH_EXEC 0 -#define WATCH_LRU 0 -#define WATCH_RELOC 0 -#define WATCH_INACTIVE 0 -#define WATCH_PWRITE 0 - -#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE -static void -i915_gem_dump_object(struct drm_gem_object *obj, int len, - const char *where, uint32_t mark); -#endif - static int i915_gem_object_set_domain(struct drm_gem_object *obj, uint32_t read_domains, @@ -59,9 +45,6 @@ static int i915_gem_object_get_page_list(struct drm_gem_object *obj); static void i915_gem_object_free_page_list(struct drm_gem_object *obj); static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); -static void -i915_gem_clflush_object(struct drm_gem_object *obj); - int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -541,25 +524,6 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj) &dev_priv->mm.active_list); } -#if WATCH_INACTIVE -static void -i915_verify_inactive(struct drm_device *dev, char *file, int line) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { - obj = obj_priv->obj; - if (obj_priv->pin_count || obj_priv->active || (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) - DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n", - obj, - obj_priv->pin_count, obj_priv->active, obj->write_domain, file, line); - } -} -#else -#define i915_verify_inactive(dev,file,line) -#endif static void i915_gem_object_move_to_inactive(struct drm_gem_object *obj) @@ -1006,83 +970,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) return 0; } -#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE -static void -i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end, - uint32_t bias, uint32_t mark) -{ - uint32_t *mem = kmap_atomic(page, KM_USER0); - int i; - for (i = start; i < end; i += 4) - DRM_INFO("%08x: %08x%s\n", - (int) (bias + i), mem[i / 4], - (bias + i == mark) ? " ********" : ""); - kunmap_atomic(mem, KM_USER0); - /* give syslog time to catch up */ - msleep(1); -} - -static void -i915_gem_dump_object(struct drm_gem_object *obj, int len, - const char *where, uint32_t mark) -{ - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int page; - - DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); - for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) { - int page_len, chunk, chunk_len; - - page_len = len - page * PAGE_SIZE; - if (page_len > PAGE_SIZE) - page_len = PAGE_SIZE; - - for (chunk = 0; chunk < page_len; chunk += 128) { - chunk_len = page_len - chunk; - if (chunk_len > 128) - chunk_len = 128; - i915_gem_dump_page(obj_priv->page_list[page], - chunk, chunk + chunk_len, - obj_priv->gtt_offset + - page * PAGE_SIZE, - mark); - } - } -} -#endif - -#if WATCH_LRU -static void -i915_dump_lru(struct drm_device *dev, const char *where) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - - DRM_INFO("active list %s {\n", where); - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, - list) - { - DRM_INFO(" %p: %08x\n", obj_priv, - obj_priv->last_rendering_seqno); - } - DRM_INFO("}\n"); - DRM_INFO("flushing list %s {\n", where); - list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, - list) - { - DRM_INFO(" %p: %08x\n", obj_priv, - obj_priv->last_rendering_seqno); - } - DRM_INFO("}\n"); - DRM_INFO("inactive %s {\n", where); - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { - DRM_INFO(" %p: %08x\n", obj_priv, - obj_priv->last_rendering_seqno); - } - DRM_INFO("}\n"); -} -#endif - static int i915_gem_evict_something(struct drm_device *dev) { @@ -1308,7 +1195,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) return 0; } -static void +void i915_gem_clflush_object(struct drm_gem_object *obj) { struct drm_i915_gem_object *obj_priv = obj->driver_private; @@ -1540,76 +1427,6 @@ i915_gem_dev_set_domain(struct drm_device *dev) return flush_domains; } -#if WATCH_COHERENCY -static void -i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) -{ - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; - int page; - uint32_t *gtt_mapping; - uint32_t *backing_map = NULL; - int bad_count = 0; - - DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", - __func__, obj, obj_priv->gtt_offset, handle, - obj->size / 1024); - - gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset, - obj->size); - if (gtt_mapping == NULL) { - DRM_ERROR("failed to map GTT space\n"); - return; - } - - for (page = 0; page < obj->size / PAGE_SIZE; page++) { - int i; - - backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); - - if (backing_map == NULL) { - DRM_ERROR("failed to map backing page\n"); - goto out; - } - - for (i = 0; i < PAGE_SIZE / 4; i++) { - uint32_t cpuval = backing_map[i]; - uint32_t gttval = readl(gtt_mapping + - page * 1024 + i); - - if (cpuval != gttval) { - DRM_INFO("incoherent CPU vs GPU at 0x%08x: " - "0x%08x vs 0x%08x\n", - (int)(obj_priv->gtt_offset + - page * PAGE_SIZE + i * 4), - cpuval, gttval); - if (bad_count++ >= 8) { - DRM_INFO("...\n"); - goto out; - } - } - } - kunmap_atomic(backing_map, KM_USER0); - backing_map = NULL; - } - - out: - if (backing_map != NULL) - kunmap_atomic(backing_map, KM_USER0); - iounmap(gtt_mapping); - - /* give syslog time to catch up */ - msleep(1); - - /* Directly flush the object, since we just loaded values with the CPU - * from thebacking pages and we don't want to disturb the cache - * management that we're trying to observe. - */ - - i915_gem_clflush_object(obj); -} -#endif - /** * Pin an object to the GTT and evaluate the relocations landing in it. */ -- cgit v1.2.3 From f85fd1b42dc2d77266007c02144d4f4f524e4157 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 26 Jul 2008 19:28:14 -0700 Subject: intel-gem: Speed up tiled readpixels by tracking which pages have been flushed. This is around 3x or so speedup, since we would read wide rows at a time, and clflush each tile 8 times as a result. We'll want code related to this anyway when we do fault-based per-page clflushing for sw fallbacks. --- linux-core/i915_gem.c | 99 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 26 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 4087854c..eea2d488 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -36,6 +36,12 @@ static int i915_gem_object_set_domain(struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain); +static int +i915_gem_object_set_domain_range(struct drm_gem_object *obj, + uint64_t offset, + uint64_t size, + uint32_t read_domains, + uint32_t write_domain); int i915_gem_set_domain(struct drm_gem_object *obj, struct drm_file *file_priv, @@ -136,32 +142,11 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); - /* Do a partial equivalent of i915_gem_set_domain(CPU, 0), as - * we don't want to clflush whole objects to read a portion of them. - * - * The side effect of doing this is that repeated preads of the same - * contents would take extra clflush overhead, since we don't track - * flushedness on a page basis. - */ - if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { - ret = i915_gem_object_wait_rendering(obj); - if (ret) { - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } - } - if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { - int first_page = args->offset / PAGE_SIZE; - int last_page = (args->offset + args->size - 1) / PAGE_SIZE; - - /* If we don't have the page list, the pages are unpinned - * and swappable, and thus should already be in the CPU domain. - */ - BUG_ON(obj_priv->page_list == NULL); - - drm_ttm_cache_flush(&obj_priv->page_list[first_page], - last_page - first_page + 1); + ret = i915_gem_object_set_domain_range(obj, args->offset, args->size, + I915_GEM_DOMAIN_CPU, 0); + if (ret != 0) { + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); } offset = args->offset; @@ -1383,7 +1368,17 @@ i915_gem_object_set_domain(struct drm_gem_object *obj, if ((write_domain | flush_domains) != 0) obj->write_domain = write_domain; + + /* If we're invalidating the CPU domain, clear the per-page CPU + * domain list as well. + */ + if (obj_priv->page_cpu_valid != NULL && + (obj->read_domains & I915_GEM_DOMAIN_CPU) && + ((read_domains & I915_GEM_DOMAIN_CPU) == 0)) { + memset(obj_priv->page_cpu_valid, 0, obj->size / PAGE_SIZE); + } obj->read_domains = read_domains; + dev->invalidate_domains |= invalidate_domains; dev->flush_domains |= flush_domains; #if WATCH_BUF @@ -1395,6 +1390,57 @@ i915_gem_object_set_domain(struct drm_gem_object *obj, return 0; } +/** + * Set the read/write domain on a range of the object. + * + * Currently only implemented for CPU reads, otherwise drops to normal + * i915_gem_object_set_domain(). + */ +static int +i915_gem_object_set_domain_range(struct drm_gem_object *obj, + uint64_t offset, + uint64_t size, + uint32_t read_domains, + uint32_t write_domain) +{ + struct drm_i915_gem_object *obj_priv = obj->driver_private; + int ret, i; + + if (obj->read_domains & I915_GEM_DOMAIN_CPU) + return 0; + + if (read_domains != I915_GEM_DOMAIN_CPU || + write_domain != 0) + return i915_gem_object_set_domain(obj, + read_domains, write_domain); + + /* Wait on any GPU rendering to the object to be flushed. */ + if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) { + ret = i915_gem_object_wait_rendering(obj); + if (ret) + return ret; + } + + if (obj_priv->page_cpu_valid == NULL) { + obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, + DRM_MEM_DRIVER); + } + + /* Flush the cache on any pages that are still invalid from the CPU's + * perspective. + */ + for (i = offset / PAGE_SIZE; i < (offset + size - 1) / PAGE_SIZE; i++) { + if (obj_priv->page_cpu_valid[i]) + continue; + + drm_ttm_cache_flush(obj_priv->page_list + i, 1); + + obj_priv->page_cpu_valid[i] = 1; + } + + return 0; +} + /** * Once all of the objects have been set in the proper domain, * perform the necessary flush and invalidate operations. @@ -2097,6 +2143,7 @@ void i915_gem_free_object(struct drm_gem_object *obj) i915_gem_object_unbind(obj); + drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); } -- cgit v1.2.3 From 1bdf35fe19c1aa02b301375b3cae7ad29adacef8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 28 Jul 2008 11:24:00 -0700 Subject: intel-gem: Fix regression tests. Main fix is an oops that was triggered by the gtt pwrite path when we don't have the gtt initialized. Also, settle on -EBADF for "bad object handle", and -EINVAL for "reading/writing beyond object boundary". --- linux-core/i915_gem.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index eea2d488..4f207d6d 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -127,7 +127,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) - return -EINVAL; + return -EBADF; obj_priv = obj->driver_private; /* Bounds check source. @@ -137,7 +137,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, if (args->offset > obj->size || args->size > obj->size || args->offset + args->size > obj->size) { drm_gem_object_unreference(obj); - return -EFAULT; + return -EINVAL; } mutex_lock(&dev->struct_mutex); @@ -326,7 +326,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) - return -EINVAL; + return -EBADF; obj_priv = obj->driver_private; /** Bounds check destination. @@ -336,7 +336,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (args->offset > obj->size || args->size > obj->size || args->offset + args->size > obj->size) { drm_gem_object_unreference(obj); - return -EFAULT; + return -EINVAL; } /* We can only do the GTT pwrite on untiled buffers, as otherwise @@ -345,7 +345,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj_priv->tiling_mode == I915_TILING_NONE) + if (obj_priv->tiling_mode == I915_TILING_NONE && + dev->gtt_total != 0) ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); else ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); @@ -376,7 +377,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) - return -EINVAL; + return -EBADF; mutex_lock(&dev->struct_mutex); ret = i915_gem_set_domain(obj, file_priv, @@ -405,7 +406,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) { mutex_unlock(&dev->struct_mutex); - return -EINVAL; + return -EBADF; } #if WATCH_BUF @@ -446,7 +447,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) - return -EINVAL; + return -EBADF; offset = args->offset; @@ -1517,7 +1518,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, reloc.target_handle); if (target_obj == NULL) { i915_gem_object_unpin(obj); - return -EINVAL; + return -EBADF; } target_obj_priv = target_obj->driver_private; @@ -1818,7 +1819,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, if (object_list[i] == NULL) { DRM_ERROR("Invalid object handle %d at index %d\n", exec_list[i].handle, i); - ret = -EINVAL; + ret = -EBADF; goto err; } @@ -2029,7 +2030,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n", args->handle); mutex_unlock(&dev->struct_mutex); - return -EINVAL; + return -EBADF; } obj_priv = obj->driver_private; @@ -2069,7 +2070,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data, DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n", args->handle); mutex_unlock(&dev->struct_mutex); - return -EINVAL; + return -EBADF; } i915_gem_object_unpin(obj); @@ -2093,7 +2094,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n", args->handle); mutex_unlock(&dev->struct_mutex); - return -EINVAL; + return -EBADF; } obj_priv = obj->driver_private; -- cgit v1.2.3 From 487c42bd42d93304278abce03b36c935bdc83284 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 28 Jul 2008 11:45:22 -0700 Subject: intel-gem: Another checkpatch.pl pass. --- linux-core/i915_gem.c | 92 ++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 41 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 4f207d6d..593302ef 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -201,14 +201,13 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT); if (ret) goto fail; - + obj_priv = obj->driver_private; offset = obj_priv->gtt_offset + args->offset; obj_priv->dirty = 1; - + while (remain > 0) { - - /** Operation in this page + /* Operation in this page * * i = page number * o = offset within page @@ -221,7 +220,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, l = PAGE_SIZE - o; pfn = (dev->agp->base >> PAGE_SHIFT) + i; - + #ifdef DRM_KMAP_ATOMIC_PROT_PFN /* kmap_atomic can't map IO pages on non-HIGHMEM kernels */ @@ -231,7 +230,8 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", i, o, l, pfn, vaddr); #endif - unwritten = __copy_from_user_inatomic_nocache(vaddr + o, user_data, l); + unwritten = __copy_from_user_inatomic_nocache(vaddr + o, + user_data, l); kunmap_atomic(vaddr, KM_USER0); if (unwritten) @@ -239,7 +239,8 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, { vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); #if WATCH_PWRITE - DRM_INFO("pwrite slow i %d o %d l %d pfn %ld vaddr %p\n", + DRM_INFO("pwrite slow i %d o %d l %d " + "pfn %ld vaddr %p\n", i, o, l, pfn, vaddr); #endif if (vaddr == NULL) { @@ -268,7 +269,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, #endif fail: - i915_gem_object_unpin (obj); + i915_gem_object_unpin(obj); mutex_unlock(&dev->struct_mutex); return ret; @@ -329,11 +330,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, return -EBADF; obj_priv = obj->driver_private; - /** Bounds check destination. + /* Bounds check destination. * * XXX: This could use review for overflow issues... */ - if (args->offset > obj->size || args->size > obj->size || + if (args->offset > obj->size || args->size > obj->size || args->offset + args->size > obj->size) { drm_gem_object_unreference(obj); return -EINVAL; @@ -413,14 +414,13 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, DRM_INFO("%s: sw_finish %d (%p)\n", __func__, args->handle, obj); #endif - obj_priv = obj->driver_private; - - /** Pinned buffers may be scanout, so flush the cache - */ - if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) { - i915_gem_clflush_object(obj); - drm_agp_chipset_flush(dev); - } + obj_priv = obj->driver_private; + + /* Pinned buffers may be scanout, so flush the cache */ + if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) { + i915_gem_clflush_object(obj); + drm_agp_chipset_flush(dev); + } drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); return ret; @@ -577,7 +577,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains) list_add_tail(&request->list, &dev_priv->mm.request_list); if (was_empty) - schedule_delayed_work (&dev_priv->mm.retire_work, HZ); + schedule_delayed_work(&dev_priv->mm.retire_work, HZ); return seqno; } @@ -587,7 +587,6 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains) * Ensures that all commands in the ring are finished * before signalling the CPU */ - uint32_t i915_retire_commands(struct drm_device *dev) { @@ -704,7 +703,8 @@ i915_gem_retire_requests(struct drm_device *dev) list); retiring_seqno = request->seqno; - if (i915_seqno_passed(seqno, retiring_seqno) || dev_priv->mm.wedged) { + if (i915_seqno_passed(seqno, retiring_seqno) || + dev_priv->mm.wedged) { i915_gem_retire_request(dev, request); list_del(&request->list); @@ -727,7 +727,7 @@ i915_gem_retire_work_handler(struct work_struct *work) mutex_lock(&dev->struct_mutex); i915_gem_retire_requests(dev); if (!list_empty(&dev_priv->mm.request_list)) - schedule_delayed_work (&dev_priv->mm.retire_work, HZ); + schedule_delayed_work(&dev_priv->mm.retire_work, HZ); mutex_unlock(&dev->struct_mutex); } @@ -748,7 +748,8 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) i915_user_irq_on(dev_priv); ret = wait_event_interruptible(dev_priv->irq_queue, i915_seqno_passed(i915_get_gem_seqno(dev), - seqno) || dev_priv->mm.wedged); + seqno) || + dev_priv->mm.wedged); i915_user_irq_off(dev_priv); dev_priv->mm.waiting_gem_seqno = 0; } @@ -787,7 +788,8 @@ i915_gem_flush(struct drm_device *dev, if (flush_domains & I915_GEM_DOMAIN_CPU) drm_agp_chipset_flush(dev); - if ((invalidate_domains|flush_domains) & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) { + if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU | + I915_GEM_DOMAIN_GTT)) { /* * read/write caches: * @@ -914,7 +916,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) */ ret = i915_gem_object_wait_rendering(obj); if (ret) { - DRM_ERROR ("wait_rendering failed: %d\n", ret); + DRM_ERROR("wait_rendering failed: %d\n", ret); return ret; } @@ -944,7 +946,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) if (obj_priv->gtt_space) { atomic_dec(&dev->gtt_count); atomic_sub(obj->size, &dev->gtt_memory); - + drm_memrange_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; } @@ -1029,7 +1031,8 @@ i915_gem_evict_something(struct drm_device *dev) continue; } - DRM_ERROR("inactive empty %d request empty %d flushing empty %d\n", + DRM_ERROR("inactive empty %d request empty %d " + "flushing empty %d\n", list_empty(&dev_priv->mm.inactive_list), list_empty(&dev_priv->mm.request_list), list_empty(&dev_priv->mm.flushing_list)); @@ -1050,7 +1053,7 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj) struct inode *inode; struct page *page; int ret; - + if (obj_priv->page_list) return 0; @@ -1076,7 +1079,7 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj) page = NULL; } ret = shmem_getpage(inode, i, &page, SGP_DIRTY, NULL); - + if (ret) { DRM_ERROR("shmem_getpage failed: %d\n", ret); i915_gem_object_free_page_list(obj); @@ -1320,8 +1323,8 @@ i915_gem_object_set_domain(struct drm_gem_object *obj, #if WATCH_BUF DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", - __func__, obj, - obj->read_domains, read_domains, + __func__, obj, + obj->read_domains, read_domains, obj->write_domain, write_domain); #endif /* @@ -1359,7 +1362,8 @@ i915_gem_object_set_domain(struct drm_gem_object *obj, * flushed before the cpu cache is invalidated */ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) && - (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))) { + (flush_domains & ~(I915_GEM_DOMAIN_CPU | + I915_GEM_DOMAIN_GTT))) { ret = i915_gem_object_wait_rendering(obj); if (ret) return ret; @@ -1741,7 +1745,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) mutex_lock(&dev->struct_mutex); seqno = i915_file_priv->mm.last_gem_throttle_seqno; - i915_file_priv->mm.last_gem_throttle_seqno = i915_file_priv->mm.last_gem_seqno; + i915_file_priv->mm.last_gem_throttle_seqno = + i915_file_priv->mm.last_gem_seqno; if (seqno) ret = i915_wait_request(dev, seqno); mutex_unlock(&dev->struct_mutex); @@ -1798,7 +1803,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, mutex_unlock(&dev->struct_mutex); return -EIO; } - + if (dev_priv->mm.suspended) { DRM_ERROR("Execbuf while VT-switched.\n"); mutex_unlock(&dev->struct_mutex); @@ -1979,7 +1984,9 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) if (obj_priv->pin_count == 1) { atomic_inc(&dev->pin_count); atomic_add(obj->size, &dev->pin_memory); - if (!obj_priv->active && (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) == 0 && + if (!obj_priv->active && + (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | + I915_GEM_DOMAIN_GTT)) == 0 && !list_empty(&obj_priv->list)) list_del_init(&obj_priv->list); } @@ -2005,7 +2012,9 @@ i915_gem_object_unpin(struct drm_gem_object *obj) * the inactive list */ if (obj_priv->pin_count == 0) { - if (!obj_priv->active && (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) == 0) + if (!obj_priv->active && + (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | + I915_GEM_DOMAIN_GTT)) == 0) list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); atomic_dec(&dev->pin_count); @@ -2041,7 +2050,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, return ret; } - /** XXX - flush the CPU caches for pinned objects + /* XXX - flush the CPU caches for pinned objects * as the X server doesn't manage domains yet */ if (obj->write_domain & I915_GEM_DOMAIN_CPU) { @@ -2164,7 +2173,7 @@ i915_gem_set_domain(struct drm_gem_object *obj, if (ret) return ret; flush_domains = i915_gem_dev_set_domain(obj->dev); - + if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) (void) i915_add_request(dev, flush_domains); @@ -2225,7 +2234,8 @@ i915_gem_idle(struct drm_device *dev) */ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT), ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); - seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); + seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU | + I915_GEM_DOMAIN_GTT)); if (seqno == 0) { mutex_unlock(&dev->struct_mutex); @@ -2468,10 +2478,10 @@ i915_gem_lastclose(struct drm_device *dev) ret = i915_gem_idle(dev); if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); - + i915_gem_cleanup_ringbuffer(dev); } - + mutex_unlock(&dev->struct_mutex); } -- cgit v1.2.3 From 33c8e03787308c2b86a4f724ba7ce4dc43918b6a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 30 Jul 2008 11:22:48 -0700 Subject: Revert "Rename drm_mm.c and its fuctions to drm_memrange." This reverts commit 3ad8db2071d30c198403e605f2726fc5c3e46bfd. We ended up not needing that namespace, and I'd rather not have the churn for producing diffs. --- linux-core/i915_gem.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'linux-core/i915_gem.c') diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 4c167d29..70f11515 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -67,7 +67,7 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - drm_memrange_init(&dev_priv->mm.gtt_space, args->gtt_start, + drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start, args->gtt_end - args->gtt_start); dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start); @@ -947,7 +947,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) atomic_dec(&dev->gtt_count); atomic_sub(obj->size, &dev->gtt_memory); - drm_memrange_put_block(obj_priv->gtt_space); + drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; } @@ -1101,7 +1101,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = obj->driver_private; - struct drm_memrange_node *free_space; + struct drm_mm_node *free_space; int page_count, ret; if (alignment == 0) @@ -1112,13 +1112,11 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) } search_free: - free_space = drm_memrange_search_free(&dev_priv->mm.gtt_space, - obj->size, - alignment, 0); + free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, + obj->size, alignment, 0); if (free_space != NULL) { - obj_priv->gtt_space = - drm_memrange_get_block(free_space, obj->size, - alignment); + obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, + alignment); if (obj_priv->gtt_space != NULL) { obj_priv->gtt_space->private = obj; obj_priv->gtt_offset = obj_priv->gtt_space->start; @@ -1152,7 +1150,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) #endif ret = i915_gem_object_get_page_list(obj); if (ret) { - drm_memrange_put_block(obj_priv->gtt_space); + drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; return ret; } @@ -1167,7 +1165,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) obj_priv->gtt_offset); if (obj_priv->agp_mem == NULL) { i915_gem_object_free_page_list(obj); - drm_memrange_put_block(obj_priv->gtt_space); + drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; return -ENOMEM; } -- cgit v1.2.3