Re: [Intel-gfx] [PATCH] drm/i915: ingore eDP bpc settings

2012-08-11 Thread Paul Menzel
Am Freitag, den 10.08.2012, 11:10 +0200 schrieb Daniel Vetter:

There is a typo in the commit summary: i*gn*ore.

 This has originally been introduced to not oversubscribe the dp links
 in
 
 commit 885a5fb5b120a5c7e0b3baad7b0feb5a89f76c18
 Author: Zhenyu Wang zhen...@linux.intel.com
 Date:   Tue Jan 12 05:38:31 2010 +0800
 
 drm/i915: fix pixel color depth setting on eDP
 
 Since then we've fixed up the dp link bandwidth calculation code for
 code

`for code` should be removed.

 and should now automatically fall back to 6bpc dithering. So this
 is unnecessary.
 
 Furthermore it seems to break the new MacbookPro with retina display,
 hence let's just rip this out.
 
 Reported-by: Benoit Gschwind gschw...@gnu-log.net
 Cc: Benoit Gschwind gschw...@gnu-log.net
 Cc: Francois Rigaut frig...@gmail.com
 Cc: Greg KH gre...@linuxfoundation.org
 Cc: sta...@vger.kernel.org
 Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch
 
 --
 
 Testing feedback highgly welcome, and thanks for Benoit for finding
 out that the bpc computations are busted.
 -Daniel
 ---
  drivers/gpu/drm/i915/intel_display.c |   11 ---
  1 file changed, 11 deletions(-)
 
 diff --git a/drivers/gpu/drm/i915/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index bddb290..ddd4db3 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -3755,17 +3755,6 @@ static bool intel_choose_pipe_bpp_dither(struct 
 drm_crtc *crtc,
   continue;
   }
  
 - if (intel_encoder-type == INTEL_OUTPUT_EDP) {
 - /* Use VBT settings if we have an eDP panel */
 - unsigned int edp_bpc = dev_priv-edp.bpp / 3;
 -
 - if (edp_bpc  display_bpc) {
 - DRM_DEBUG_KMS(clamping display bpc (was %d) to 
 eDP (%d)\n, display_bpc, edp_bpc);
 - display_bpc = edp_bpc;
 - }
 - continue;
 - }
 -
   /* Not one of the known troublemakers, check the EDID */
   list_for_each_entry(connector, dev-mode_config.connector_list,
   head) {

Acked-by: Paul Menzel paulepan...@users.sourceforge.net


Thanks,

Paul


signature.asc
Description: This is a digitally signed message part
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Netiquette: No HTML messages please. (was: [ANNOUNCE] glamor 0.5.0)

2012-08-11 Thread Paul Menzel
Dear Zhigang,


thank you for the announcement message and congratulations on the
release. But please do not send HTML messages to lists [1]!


Thanks,

Paul


[1] http://en.opensuse.org/openSUSE:Mailing_list_netiquette


signature.asc
Description: This is a digitally signed message part
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Macbook Air 2012

2012-08-11 Thread Daniel Wagner

Hi,

I installed on my shiny new Macbook Air 2012 Fedora 17. After adding

intremap=off

to the kernel arguments, I was able to install the system. The X server 
worked out of the box. This was with a 3.3.4 kernel.


Then I started to upgrade the installation and a newer kernel was 
installed 3.5. After the reboot the screen stayed black. Upgrading to 
Linus' 3.6-rc1 didn't help either.


After some research I have tried now Daniel's tree danvet branch 
drm-intel-next. Still no success. I also found 
https://bugs.freedesktop.org/show_bug.cgi?id=48652 which sounds awfully 
like what I am seeing as symptoms.


Unfortunately, is my graphic trouble debugging skills rather limited. Is 
there anything I could provide to resolve this issue?


cheers,
daniel

ps: Adding nomodeset to the drm-intel-next kernel resulted in a kernel 
panic:


http://www.monom.org/misc/mba/drm-intel-next_nomodeset-2012-08-11.jpg

Don't know if that is important. Just in case someone is interested in 
these kind of reports.

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Stolen pages, with a little surprise

2012-08-11 Thread Chris Wilson
I've reworked and incorporated dmabuf into the grand scheme of things,
unifying how we track pages for the various different types of object
(shmemfs, dmabuf, stolen) so the series is quite a bit more complicated
than it was before.

Please review, flame and generally suggest cleaner methods.
-Chris

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 06/29] drm/i915: Protect private gem objects from truncate (such as imported dmabuf)

2012-08-11 Thread Chris Wilson
If the object has no backing shmemfs filp, then we obviously cannot
perform a truncation operation upon it.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b16b5ff..2f4a113 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1385,6 +1385,11 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
 {
struct inode *inode;
 
+   i915_gem_object_free_mmap_offset(obj);
+
+   if (obj-base.filp == NULL)
+   return;
+
/* Our goal here is to return as much of the memory as
 * is possible back to the system as we are called from OOM.
 * To do this we must instruct the shmfs to drop all of its
@@ -1393,8 +1398,6 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
inode = obj-base.filp-f_path.dentry-d_inode;
shmem_truncate_range(inode, 0, (loff_t)-1);
 
-   i915_gem_object_free_mmap_offset(obj);
-
obj-madv = __I915_MADV_PURGED;
 }
 
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 13/29] drm/i915: Convert the dmabuf object to use the new i915_gem_object_ops

2012-08-11 Thread Chris Wilson
By providing a callback for when we need to bind the pages, and then
release them again later, we can shorten the amount of time we hold the
foreign pages mapped and pinned, and importantly the dmabuf objects then
behave as any other normal object with respect to the shrinker and
memory management.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|1 -
 drivers/gpu/drm/i915/i915_gem.c|   10 +++
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |   45 +---
 drivers/gpu/drm/i915/i915_gem_gtt.c|4 +--
 4 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d4d3b2a..74a3c6c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -993,7 +993,6 @@ struct drm_i915_gem_object {
int pages_pin_count;
 
/* prime dma-buf support */
-   struct sg_table *sg_table;
void *dma_buf_vmapping;
int vmapping_count;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 20e05c2..d0fcb61 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1450,7 +1450,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 {
const struct drm_i915_gem_object_ops *ops = obj-base.driver_private;
 
-   if (obj-sg_table || obj-pages == NULL)
+   if (obj-pages == NULL)
return 0;
 
if (obj-pages_pin_count)
@@ -1594,7 +1594,7 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
const struct drm_i915_gem_object_ops *ops = obj-base.driver_private;
int ret;
 
-   if (obj-sg_table || obj-pages)
+   if (obj-pages)
return 0;
 
BUG_ON(obj-pages_pin_count);
@@ -3680,9 +3680,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
trace_i915_gem_object_destroy(obj);
 
-   if (gem_obj-import_attach)
-   drm_prime_gem_destroy(gem_obj, obj-sg_table);
-
if (obj-phys_obj)
i915_gem_detach_phys_object(dev, obj);
 
@@ -3704,6 +3701,9 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
BUG_ON(obj-pages);
 
+   if (obj-base.import_attach)
+   drm_prime_gem_destroy(obj-base, NULL);
+
drm_gem_object_release(obj-base);
i915_gem_info_remove_obj(dev_priv, obj-base.size);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index b48c2a4..5e72e95 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -82,7 +82,8 @@ out:
 }
 
 static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
-   struct sg_table *sg, enum dma_data_direction dir)
+  struct sg_table *sg,
+  enum dma_data_direction dir)
 {
dma_unmap_sg(attachment-dev, sg-sgl, sg-nents, dir);
sg_free_table(sg);
@@ -212,11 +213,35 @@ struct dma_buf *i915_gem_prime_export(struct drm_device 
*dev,
return dma_buf_export(obj, i915_dmabuf_ops, obj-base.size, 0600);
 }
 
+static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+   struct sg_table *sg;
+
+   sg = dma_buf_map_attachment(obj-base.import_attach, DMA_BIDIRECTIONAL);
+   if (IS_ERR(sg))
+   return PTR_ERR(sg);
+
+   obj-pages = sg;
+   obj-has_dma_mapping = true;
+   return 0;
+}
+
+static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj)
+{
+   dma_buf_unmap_attachment(obj-base.import_attach,
+obj-pages, DMA_BIDIRECTIONAL);
+   obj-has_dma_mapping = false;
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
+   .get_pages = i915_gem_object_get_pages_dmabuf,
+   .put_pages = i915_gem_object_put_pages_dmabuf,
+};
+
 struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
 struct dma_buf *dma_buf)
 {
struct dma_buf_attachment *attach;
-   struct sg_table *sg;
struct drm_i915_gem_object *obj;
int ret;
 
@@ -235,32 +260,24 @@ struct drm_gem_object *i915_gem_prime_import(struct 
drm_device *dev,
if (IS_ERR(attach))
return ERR_CAST(attach);
 
-   sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
-   if (IS_ERR(sg)) {
-   ret = PTR_ERR(sg);
-   goto fail_detach;
-   }
 
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL) {
ret = -ENOMEM;
-   goto fail_unmap;
+   goto fail_detach;
}
 
ret = drm_gem_private_object_init(dev, obj-base, dma_buf-size);
if (ret) {
kfree(obj);
-   goto fail_unmap;
+   goto fail_detach;
}
 
-   

[Intel-gfx] [PATCH 15/29] drm/i915: Fix detection of stolen base for gen2

2012-08-11 Thread Chris Wilson
It was not until the G33 refresh, that a PCI config register was
introduced that explicitly said where the stolen memory was. Prior to
865G there was not even a register that said where the end of usable
low memory was and where the stolen memory began (or ended depending
upon chipset). Before then, one has to look at the BIOS memory maps to
find the Top of Memory. Alas that is not exported by arch/x86 and so we
have to resort to disabling stolen memory on gen2 for the time being.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |   69 ++--
 2 files changed, 31 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 74a3c6c..a25edcc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -704,6 +704,7 @@ typedef struct drm_i915_private {
unsigned long gtt_start;
unsigned long gtt_mappable_end;
unsigned long gtt_end;
+   unsigned long stolen_base; /* limited to low memory (32-bit) */
 
struct io_mapping *gtt_mapping;
phys_addr_t gtt_base_addr;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index ada2e90..a01ff74 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -43,56 +43,43 @@
  * for is a boon.
  */
 
-#define PTE_ADDRESS_MASK   0xf000
-#define PTE_ADDRESS_MASK_HIGH  0x00f0 /* i915+ */
-#define PTE_MAPPING_TYPE_UNCACHED  (0  1)
-#define PTE_MAPPING_TYPE_DCACHE(1  1) /* i830 only */
-#define PTE_MAPPING_TYPE_CACHED(3  1)
-#define PTE_MAPPING_TYPE_MASK  (3  1)
-#define PTE_VALID  (1  0)
-
-/**
- * i915_stolen_to_phys - take an offset into stolen memory and turn it into
- *   a physical one
- * @dev: drm device
- * @offset: address to translate
- *
- * Some chip functions require allocations from stolen space and need the
- * physical address of the memory in question.
- */
-static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset)
+static unsigned long i915_stolen_to_physical(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct pci_dev *pdev = dev_priv-bridge_dev;
u32 base;
 
-#if 0
/* On the machines I have tested the Graphics Base of Stolen Memory
-* is unreliable, so compute the base by subtracting the stolen memory
-* from the Top of Low Usable DRAM which is where the BIOS places
-* the graphics stolen memory.
+* is unreliable, so on those compute the base by subtracting the
+* stolen memory from the Top of Low Usable DRAM which is where the
+* BIOS places the graphics stolen memory.
+*
+* On gen2, the layout is slightly different with the Graphics Segment
+* immediately following Top of Memory (or Top of Usable DRAM). Note
+* it appears that TOUD is only reported by 865g, so we just use the
+* top of memory as determined by the e820 probe.
+*
+* XXX gen2 requires an unavailable symbol and 945gm fails with
+* its value of TOLUD.
 */
+   base = 0;
if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
-   /* top 32bits are reserved = 0 */
+   /* Read Graphics Base of Stolen Memory directly */
pci_read_config_dword(pdev, 0xA4, base);
-   } else {
-   /* XXX presume 8xx is the same as i915 */
-   pci_bus_read_config_dword(pdev-bus, 2, 0x5C, base);
-   }
-#else
-   if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
-   u16 val;
-   pci_read_config_word(pdev, 0xb0, val);
-   base = val  4  20;
-   } else {
+#if 0
+   } else if (IS_GEN3(dev)) {
u8 val;
+   /* Stolen is immediately below Top of Low Usable DRAM */
pci_read_config_byte(pdev, 0x9c, val);
base = val  3  27;
-   }
-   base -= dev_priv-mm.gtt-stolen_size;
+   base -= dev_priv-mm.gtt-stolen_size;
+   } else {
+   /* Stolen is immediately above Top of Memory */
+   base = max_low_pfn_mapped  PAGE_SHIFT;
 #endif
+   }
 
-   return base + offset;
+   return base;
 }
 
 static void i915_warn_stolen(struct drm_device *dev)
@@ -117,7 +104,7 @@ static void i915_setup_compression(struct drm_device *dev, 
int size)
if (!compressed_fb)
goto err;
 
-   cfb_base = i915_stolen_to_phys(dev, compressed_fb-start);
+   cfb_base = dev_priv-mm.stolen_base + compressed_fb-start;
if (!cfb_base)
goto err_fb;
 
@@ -130,7 +117,7 @@ static void i915_setup_compression(struct 

[Intel-gfx] [PATCH 17/29] drm/i915: Avoid clearing preallocated regions from the GTT

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h |2 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c |   35 ---
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a25edcc..0ce410a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -896,6 +896,8 @@ enum i915_cache_level {
I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */
 };
 
+#define I915_GTT_RESERVED ((struct drm_mm_node *)0x1)
+
 struct drm_i915_gem_object_ops {
int (*get_pages)(struct drm_i915_gem_object *);
void (*put_pages)(struct drm_i915_gem_object *);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ea4fc20..528fd43 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -375,18 +375,47 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
  unsigned long end)
 {
drm_i915_private_t *dev_priv = dev-dev_private;
+   struct drm_mm_node *entry;
+   struct drm_i915_gem_object *obj;
 
-   /* Substract the guard page ... */
+   /* Subtract the guard page ... */
drm_mm_init(dev_priv-mm.gtt_space, start, end - start - PAGE_SIZE);
if (!HAS_LLC(dev))
dev_priv-mm.gtt_space.color_adjust = i915_gtt_color_adjust;
 
+   /* Mark any preallocated objects as occupied */
+   list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list) {
+   DRM_DEBUG_KMS(reserving preallocated space: %x + %zx\n,
+ obj-gtt_offset, obj-base.size);
+
+   BUG_ON(obj-gtt_space != I915_GTT_RESERVED);
+   obj-gtt_space = drm_mm_create_block(dev_priv-mm.gtt_space,
+obj-gtt_offset,
+obj-base.size,
+false);
+   obj-has_global_gtt_mapping = 1;
+   }
+
dev_priv-mm.gtt_start = start;
dev_priv-mm.gtt_mappable_end = mappable_end;
dev_priv-mm.gtt_end = end;
dev_priv-mm.gtt_total = end - start;
dev_priv-mm.mappable_gtt_total = min(end, mappable_end) - start;
 
-   /* ... but ensure that we clear the entire range. */
-   intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE);
+   /* Clear any non-preallocated blocks */
+   list_for_each_entry(entry, dev_priv-mm.gtt_space.hole_stack, 
hole_stack) {
+   unsigned long hole_start = entry-start + entry-size;
+   unsigned long hole_end = list_entry(entry-node_list.next,
+   struct drm_mm_node,
+   node_list)-start;
+
+   DRM_DEBUG_KMS(clearing unused GTT space: [%lx, %lx]\n,
+ hole_start, hole_end);
+
+   intel_gtt_clear_range(hole_start / PAGE_SIZE,
+ (hole_end-hole_start) / PAGE_SIZE);
+   }
+
+   /* And finally clear the reserved guard page */
+   intel_gtt_clear_range(end / PAGE_SIZE - 1, 1);
 }
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 22/29] drm/i915: Handle stolen objects in pwrite

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |  169 +--
 1 file changed, 111 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 552f95b..a2fb2aa 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -664,19 +664,17 @@ out:
  * needs_clflush_before is set and flushes out any written cachelines after
  * writing if needs_clflush is set. */
 static int
-shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
+shmem_pwrite_fast(char *vaddr, int shmem_page_offset, int page_length,
  char __user *user_data,
  bool page_do_bit17_swizzling,
  bool needs_clflush_before,
  bool needs_clflush_after)
 {
-   char *vaddr;
int ret;
 
if (unlikely(page_do_bit17_swizzling))
return -EINVAL;
 
-   vaddr = kmap_atomic(page);
if (needs_clflush_before)
drm_clflush_virt_range(vaddr + shmem_page_offset,
   page_length);
@@ -686,7 +684,6 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, 
int page_length,
if (needs_clflush_after)
drm_clflush_virt_range(vaddr + shmem_page_offset,
   page_length);
-   kunmap_atomic(vaddr);
 
return ret ? -EFAULT : 0;
 }
@@ -694,16 +691,14 @@ shmem_pwrite_fast(struct page *page, int 
shmem_page_offset, int page_length,
 /* Only difference to the fast-path function is that this can handle bit17
  * and uses non-atomic copy and kmap functions. */
 static int
-shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length,
+shmem_pwrite_slow(char *vaddr, int shmem_page_offset, int page_length,
  char __user *user_data,
  bool page_do_bit17_swizzling,
  bool needs_clflush_before,
  bool needs_clflush_after)
 {
-   char *vaddr;
int ret;
 
-   vaddr = kmap(page);
if (unlikely(needs_clflush_before || page_do_bit17_swizzling))
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
@@ -720,7 +715,6 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, 
int page_length,
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
 page_do_bit17_swizzling);
-   kunmap(page);
 
return ret ? -EFAULT : 0;
 }
@@ -731,6 +725,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
  struct drm_i915_gem_pwrite *args,
  struct drm_file *file)
 {
+   struct drm_i915_private *dev_priv = dev-dev_private;
ssize_t remain;
loff_t offset;
char __user *user_data;
@@ -770,74 +765,132 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
if (ret)
return ret;
 
-   i915_gem_object_pin_pages(obj);
-
offset = args-offset;
obj-dirty = 1;
 
-   for_each_sg(obj-pages-sgl, sg, obj-pages-nents, i) {
-   struct page *page;
-   int partial_cacheline_write;
+   if (obj-stolen) {
+   while (remain  0) {
+   char *vaddr;
+   int partial_cacheline_write;
 
-   if (i  offset  PAGE_SHIFT)
-   continue;
+   /* Operation in this page
+*
+* shmem_page_offset = offset within page in shmem file
+* page_length = bytes to copy for this page
+*/
+   shmem_page_offset = offset_in_page(offset);
 
-   if (remain = 0)
-   break;
+   page_length = remain;
+   if ((shmem_page_offset + page_length)  PAGE_SIZE)
+   page_length = PAGE_SIZE - shmem_page_offset;
 
-   /* Operation in this page
-*
-* shmem_page_offset = offset within page in shmem file
-* page_length = bytes to copy for this page
-*/
-   shmem_page_offset = offset_in_page(offset);
+   /* If we don't overwrite a cacheline completely we need 
to be
+* careful to have up-to-date data by first clflushing. 
Don't
+* overcomplicate things and flush the entire patch. */
+   partial_cacheline_write = needs_clflush_before 
+   ((shmem_page_offset | page_length)
+ (boot_cpu_data.x86_clflush_size - 1));
 
-   page_length = remain;
-   if ((shmem_page_offset + 

[Intel-gfx] [PATCH 27/29] drm/i915: Allocate overlay registers from stolen memory

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/intel_overlay.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_overlay.c 
b/drivers/gpu/drm/i915/intel_overlay.c
index 7a98459..6982191 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1424,8 +1424,10 @@ void intel_setup_overlay(struct drm_device *dev)
 
overlay-dev = dev;
 
-   reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
-   if (!reg_bo)
+   reg_bo = i915_gem_object_create_stolen(dev, PAGE_SIZE);
+   if (reg_bo == NULL)
+   reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
+   if (reg_bo == NULL)
goto out_free;
overlay-reg_bo = reg_bo;
 
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 29/29] drm/i915: Introduce mapping of user pages into video memory (userptr) ioctl

2012-08-11 Thread Chris Wilson
By exporting the ability to map user address and inserting PTEs
representing their backing pages into the GTT, we can exploit UMA in order
to utilize normal application data as a texture source or even as a
render target (depending upon the capabilities of the chipset). This has
a number of uses, with zero-copy downloads to the GPU and efficient
readback making the intermixed streaming of CPU and GPU operations
fairly efficient. This ability has many widespread implications from
faster rendering of partial software fallbacks (xterm!) to faster
pipelining of texture data (such as pixel buffer objects in GL).

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/Makefile   |1 +
 drivers/gpu/drm/i915/i915_dma.c |1 +
 drivers/gpu/drm/i915/i915_drv.h |   14 +++
 drivers/gpu/drm/i915/i915_gem.c |6 +-
 drivers/gpu/drm/i915/i915_gem_userptr.c |  209 +++
 include/drm/i915_drm.h  |   15 +++
 6 files changed, 243 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_userptr.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0f2c549..754d665 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -14,6 +14,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o \
  i915_gem_gtt.o \
  i915_gem_stolen.o \
  i915_gem_tiling.o \
+ i915_gem_userptr.o \
  i915_sysfs.o \
  i915_trace_points.o \
  intel_display.o \
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 07f5b2e..62928fc 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1884,6 +1884,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, 
i915_gem_context_create_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, 
i915_gem_context_destroy_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED),
+   DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, 
DRM_MASTER|DRM_UNLOCKED),
 };
 
 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f0bf78f..50c635f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1045,6 +1045,18 @@ struct drm_i915_gem_object {
atomic_t pending_flip;
 };
 
+struct i915_gem_userptr_object {
+   struct drm_i915_gem_object gem;
+   uintptr_t user_ptr;
+   size_t user_size;
+   int read_only;
+};
+
+union drm_i915_gem_objects {
+   struct drm_i915_gem_object base;
+   struct i915_gem_userptr_object userptr;
+};
+
 inline static bool i915_gem_object_is_prime(struct drm_i915_gem_object *obj)
 {
return obj-base.import_attach != NULL;
@@ -1303,6 +1315,8 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void 
*data,
   struct drm_file *file_priv);
 int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv);
+int i915_gem_userptr_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file);
 int i915_gem_set_tiling(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 int i915_gem_get_tiling(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2d7adbb..1c8904a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2517,9 +2517,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
/* Avoid an unnecessary call to unbind on rebind. */
obj-map_and_fenceable = true;
 
+   obj-gtt_offset -= obj-gtt_space-start;
drm_mm_put_block(obj-gtt_space);
obj-gtt_space = NULL;
-   obj-gtt_offset = 0;
 
return 0;
 }
@@ -3035,7 +3035,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object 
*obj,
list_move_tail(obj-gtt_list, dev_priv-mm.bound_list);
list_add_tail(obj-mm_list, dev_priv-mm.inactive_list);
 
-   obj-gtt_offset = obj-gtt_space-start;
+   obj-gtt_offset += obj-gtt_space-start;
 
fenceable =
obj-gtt_space-size == fence_size 
@@ -4214,7 +4214,7 @@ i915_gem_load(struct drm_device *dev)
 
dev_priv-slab =
kmem_cache_create(i915_gem_object,
- sizeof(struct drm_i915_gem_object), 0,
+ sizeof(union drm_i915_gem_objects), 0,
  SLAB_HWCACHE_ALIGN,
  NULL);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c 
b/drivers/gpu/drm/i915/i915_gem_userptr.c
new file mode 100644
index 000..8604dad
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright 

[Intel-gfx] [PATCH 25/29] drm/i915: Allocate fbcon from stolen memory

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/intel_fb.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 97f6735..9de9cd9 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -84,7 +84,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
 
size = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);
-   obj = i915_gem_alloc_object(dev, size);
+   obj = i915_gem_object_create_stolen(dev, size);
+   if (obj == NULL)
+   obj = i915_gem_alloc_object(dev, size);
if (!obj) {
DRM_ERROR(failed to allocate framebuffer\n);
ret = -ENOMEM;
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 23/29] drm/i915: Handle stolen objects for pread

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |  175 ++-
 1 file changed, 116 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a2fb2aa..a29c259 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -324,24 +324,21 @@ __copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset,
  * Flushes invalid cachelines before reading the target if
  * needs_clflush is set. */
 static int
-shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length,
+shmem_pread_fast(char *vaddr, int shmem_page_offset, int page_length,
 char __user *user_data,
 bool page_do_bit17_swizzling, bool needs_clflush)
 {
-   char *vaddr;
int ret;
 
if (unlikely(page_do_bit17_swizzling))
return -EINVAL;
 
-   vaddr = kmap_atomic(page);
if (needs_clflush)
drm_clflush_virt_range(vaddr + shmem_page_offset,
   page_length);
ret = __copy_to_user_inatomic(user_data,
  vaddr + shmem_page_offset,
  page_length);
-   kunmap_atomic(vaddr);
 
return ret ? -EFAULT : 0;
 }
@@ -371,14 +368,12 @@ shmem_clflush_swizzled_range(char *addr, unsigned long 
length,
 /* Only difference to the fast-path function is that this can handle bit17
  * and uses non-atomic copy and kmap functions. */
 static int
-shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length,
+shmem_pread_slow(char *vaddr, int shmem_page_offset, int page_length,
 char __user *user_data,
 bool page_do_bit17_swizzling, bool needs_clflush)
 {
-   char *vaddr;
int ret;
 
-   vaddr = kmap(page);
if (needs_clflush)
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
@@ -392,7 +387,6 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, 
int page_length,
ret = __copy_to_user(user_data,
 vaddr + shmem_page_offset,
 page_length);
-   kunmap(page);
 
return ret ? - EFAULT : 0;
 }
@@ -403,6 +397,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
 struct drm_i915_gem_pread *args,
 struct drm_file *file)
 {
+   struct drm_i915_private *dev_priv = dev-dev_private;
char __user *user_data;
ssize_t remain;
loff_t offset;
@@ -433,76 +428,138 @@ i915_gem_shmem_pread(struct drm_device *dev,
}
}
 
-   ret = i915_gem_object_get_pages(obj);
-   if (ret)
-   return ret;
+   offset = args-offset;
 
-   i915_gem_object_pin_pages(obj);
+   if (obj-stolen) {
+   char *vaddr;
 
-   offset = args-offset;
+   vaddr = (char *)dev_priv-mm.stolen_base;
+   vaddr += obj-stolen-start + offset;
 
-   for_each_sg(obj-pages-sgl, sg, obj-pages-nents, i) {
-   struct page *page;
+   shmem_page_offset = offset_in_page(offset);
+   while (remain  0) {
+   /* Operation in this page
+*
+* shmem_page_offset = offset within page in shmem file
+* page_length = bytes to copy for this page
+*/
+   page_length = remain;
+   if ((shmem_page_offset + page_length)  PAGE_SIZE)
+   page_length = PAGE_SIZE - shmem_page_offset;
 
-   if (i  offset  PAGE_SHIFT)
-   continue;
+   page_do_bit17_swizzling = obj_do_bit17_swizzling 
+   ((uintptr_t)vaddr  (1  17)) != 0;
 
-   if (remain = 0)
-   break;
+   ret = shmem_pread_fast(vaddr, shmem_page_offset, 
page_length,
+  user_data, 
page_do_bit17_swizzling,
+  needs_clflush);
+   if (ret == 0)
+   goto next_stolen;
 
-   /* Operation in this page
-*
-* shmem_page_offset = offset within page in shmem file
-* page_length = bytes to copy for this page
-*/
-   shmem_page_offset = offset_in_page(offset);
-   page_length = remain;
-   if ((shmem_page_offset + page_length)  PAGE_SIZE)
-   page_length = PAGE_SIZE - shmem_page_offset;
+   hit_slowpath = 1;
+   mutex_unlock(dev-struct_mutex);
 
-   page = sg_page(sg);
-  

[Intel-gfx] [PATCH 26/29] drm/i915: Allocate ringbuffers from stolen memory

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/intel_ringbuffer.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 5fdd297..7e6f8f4 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1016,7 +1016,11 @@ static int intel_init_ring_buffer(struct drm_device *dev,
return ret;
}
 
-   obj = i915_gem_alloc_object(dev, ring-size);
+   obj = NULL;
+   if (!HAS_LLC(dev))
+   obj = i915_gem_object_create_stolen(dev, ring-size);
+   if (obj == NULL)
+   obj = i915_gem_alloc_object(dev, ring-size);
if (obj == NULL) {
DRM_ERROR(Failed to allocate ringbuffer\n);
ret = -ENOMEM;
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 28/29] drm/i915: Use a slab for object allocation

2012-08-11 Thread Chris Wilson
The primary purpose of this was to debug some use-after-free memory
corruption that was causing an OOPS inside drm/i915. As it turned out
the corruption was being caused elsewhere and i915.ko as a major user of
many objects was being hit hardest.

Indeed as we do frequent the generic kmalloc caches, dedicating one to
ourselves (or at least naming one for us depending upon the core) aids
debugging our own slab usage.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_dma.c|3 +++
 drivers/gpu/drm/i915/i915_drv.h|4 
 drivers/gpu/drm/i915/i915_gem.c|   28 +++-
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |5 ++---
 drivers/gpu/drm/i915/i915_gem_stolen.c |4 ++--
 5 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index df6490b..07f5b2e 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1759,6 +1759,9 @@ int i915_driver_unload(struct drm_device *dev)
 
destroy_workqueue(dev_priv-wq);
 
+   if (dev_priv-slab)
+   kmem_cache_destroy(dev_priv-slab);
+
pci_dev_put(dev_priv-bridge_dev);
kfree(dev-dev_private);
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 03cd1d6..f0bf78f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -390,6 +390,7 @@ struct intel_gmbus {
 
 typedef struct drm_i915_private {
struct drm_device *dev;
+   struct kmem_cache *slab;
 
const struct intel_device_info *info;
 
@@ -1311,12 +1312,15 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, 
void *data,
 int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 void i915_gem_load(struct drm_device *dev);
+void *i915_gem_object_alloc(struct drm_device *dev);
+void i915_gem_object_free(struct drm_i915_gem_object *obj);
 int i915_gem_init_object(struct drm_gem_object *obj);
 void i915_gem_object_init(struct drm_i915_gem_object *obj,
 const struct drm_i915_gem_object_ops *ops);
 struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
  size_t size);
 void i915_gem_free_object(struct drm_gem_object *obj);
+
 int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
 uint32_t alignment,
 bool map_and_fenceable,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index df73e02..2d7adbb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -193,6 +193,18 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void 
*data,
return 0;
 }
 
+void *i915_gem_object_alloc(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   return kmem_cache_alloc(dev_priv-slab, GFP_KERNEL | __GFP_ZERO);
+}
+
+void i915_gem_object_free(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = obj-base.dev-dev_private;
+   kmem_cache_free(dev_priv-slab, obj);
+}
+
 static int
 i915_gem_create(struct drm_file *file,
struct drm_device *dev,
@@ -216,7 +228,7 @@ i915_gem_create(struct drm_file *file,
if (ret) {
drm_gem_object_release(obj-base);
i915_gem_info_remove_obj(dev-dev_private, obj-base.size);
-   kfree(obj);
+   i915_gem_object_free(obj);
return ret;
}
 
@@ -3731,12 +3743,12 @@ struct drm_i915_gem_object 
*i915_gem_alloc_object(struct drm_device *dev,
struct address_space *mapping;
u32 mask;
 
-   obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+   obj = i915_gem_object_alloc(dev);
if (obj == NULL)
return NULL;
 
if (drm_gem_object_init(dev, obj-base, size) != 0) {
-   kfree(obj);
+   i915_gem_object_free(obj);
return NULL;
}
 
@@ -3819,7 +3831,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
i915_gem_info_remove_obj(dev_priv, obj-base.size);
 
kfree(obj-bit_17);
-   kfree(obj);
+   i915_gem_object_free(obj);
 }
 
 int
@@ -4197,8 +4209,14 @@ init_ring_lists(struct intel_ring_buffer *ring)
 void
 i915_gem_load(struct drm_device *dev)
 {
-   int i;
drm_i915_private_t *dev_priv = dev-dev_private;
+   int i;
+
+   dev_priv-slab =
+   kmem_cache_create(i915_gem_object,
+ sizeof(struct drm_i915_gem_object), 0,
+ SLAB_HWCACHE_ALIGN,
+ NULL);
 
INIT_LIST_HEAD(dev_priv-mm.active_list);
INIT_LIST_HEAD(dev_priv-mm.inactive_list);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 

[Intel-gfx] [PATCH 21/29] drm/i915: Support readback of stolen objects upon error

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_irq.c |8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2ec8ad7..f59eace 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -895,6 +895,14 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
 reloc_offset);
memcpy_fromio(d, s, PAGE_SIZE);
io_mapping_unmap_atomic(s);
+   } else if (src-stolen) {
+   unsigned long offset;
+
+   offset = dev_priv-mm.stolen_base;
+   offset += src-stolen-start;
+   offset += i  PAGE_SHIFT;
+
+   memcpy_fromio(d, (void *)offset, PAGE_SIZE);
} else {
struct page *page;
void *s;
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 20/29] drm/i915: Differentiate between prime and stolen objects

2012-08-11 Thread Chris Wilson
Stolen objects also share the property that they have no backing shmemfs
filp, but they can be used with pwrite/pread/gtt-mapping.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h |5 +
 drivers/gpu/drm/i915/i915_gem.c |4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d6cf758..02de587 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1044,6 +1044,11 @@ struct drm_i915_gem_object {
atomic_t pending_flip;
 };
 
+inline static bool i915_gem_object_is_prime(struct drm_i915_gem_object *obj)
+{
+   return obj-base.import_attach != NULL;
+}
+
 #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d0fcb61..552f95b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -553,7 +553,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
/* prime objects have no backing filp to GEM pread/pwrite
 * pages from.
 */
-   if (!obj-base.filp) {
+   if (i915_gem_object_is_prime(obj)) {
ret = -EINVAL;
goto out;
}
@@ -902,7 +902,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
/* prime objects have no backing filp to GEM pread/pwrite
 * pages from.
 */
-   if (!obj-base.filp) {
+   if (i915_gem_object_is_prime(obj)) {
ret = -EINVAL;
goto out;
}
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 24/29] drm/i915: Introduce i915_gem_object_create_stolen()

2012-08-11 Thread Chris Wilson
Allow for the creation of GEM objects backed by stolen memory. As these
are not backed by ordinary pages, we create a fake dma mapping and store
the address in the scatterlist rather than obj-pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|3 +
 drivers/gpu/drm/i915/i915_gem.c|1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |  122 
 3 files changed, 126 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 02de587..03cd1d6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1495,6 +1495,9 @@ int i915_gem_evict_everything(struct drm_device *dev);
 int i915_gem_init_stolen(struct drm_device *dev);
 int i915_gem_stolen_setup_compression(struct drm_device *dev);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size);
+void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj);
 
 /* i915_gem_tiling.c */
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a29c259..df73e02 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3808,6 +3808,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
obj-pages_pin_count = 0;
i915_gem_object_put_pages(obj);
i915_gem_object_free_mmap_offset(obj);
+   i915_gem_object_release_stolen(obj);
 
BUG_ON(obj-pages);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 00b1c1d..eca3af1 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -202,3 +202,125 @@ int i915_gem_init_stolen(struct drm_device *dev)
 
return 0;
 }
+
+static struct sg_table *
+i915_pages_create_for_stolen(struct drm_device *dev,
+u32 offset, u32 size)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct sg_table *st;
+   struct scatterlist *sg;
+
+   /* We hide that we have no struct page backing our stolen object
+* by wrapping the contiguous physical allocation with a fake
+* dma mapping in a single scatterlist.
+*/
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (st == NULL)
+   return NULL;
+
+   if (!sg_alloc_table(st, 1, GFP_KERNEL)) {
+   kfree(st);
+   return NULL;
+   }
+
+   sg = st-sgl;
+   sg-offset = offset;
+   sg-length = size;
+
+   sg_dma_address(sg) = dev_priv-mm.stolen_base + offset;
+   sg_dma_len(sg) = size;
+
+   return st;
+}
+
+static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
+{
+   BUG();
+   return -EINVAL;
+}
+
+static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj)
+{
+   /* Should only be called during free */
+   sg_free_table(obj-pages);
+   kfree(obj-pages);
+}
+
+static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
+   .get_pages = i915_gem_object_get_pages_stolen,
+   .put_pages = i915_gem_object_put_pages_stolen,
+};
+
+struct drm_i915_gem_object *
+_i915_gem_object_create_stolen(struct drm_device *dev,
+  struct drm_mm_node *stolen)
+{
+   struct drm_i915_gem_object *obj;
+
+   obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+   if (obj == NULL)
+   return NULL;
+
+   if (drm_gem_private_object_init(dev, obj-base, stolen-size))
+   goto cleanup;
+
+   i915_gem_object_init(obj, i915_gem_object_stolen_ops);
+
+   obj-pages = i915_pages_create_for_stolen(dev,
+ stolen-start, stolen-size);
+   if (obj-pages == NULL)
+   goto cleanup;
+
+   obj-has_dma_mapping = true;
+   obj-pages_pin_count = 1;
+   obj-stolen = stolen;
+
+   obj-base.write_domain = I915_GEM_DOMAIN_GTT;
+   obj-base.read_domains = I915_GEM_DOMAIN_GTT;
+   obj-cache_level = I915_CACHE_NONE;
+
+   return obj;
+
+cleanup:
+   kfree(obj);
+   return NULL;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct drm_i915_gem_object *obj;
+   struct drm_mm_node *stolen;
+
+   if (dev_priv-mm.stolen_base == 0)
+   return 0;
+
+   DRM_DEBUG_KMS(creating stolen object: size=%x\n, size);
+   if (size == 0)
+   return NULL;
+
+   stolen = drm_mm_search_free(dev_priv-mm.stolen, size, 4096, 0);
+   if (stolen)
+   stolen = drm_mm_get_block(stolen, size, 4096);
+   if (stolen == NULL)
+   return NULL;
+
+   obj = _i915_gem_object_create_stolen(dev, 

[Intel-gfx] [PATCH 18/29] drm/i915: Delay allocation of stolen space for FBC

2012-08-11 Thread Chris Wilson
As we may wish to wrap regions preallocated by the BIOS, we need to do
that before carving out contiguous chunks of stolen space for FBC.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |  114 +---
 drivers/gpu/drm/i915/intel_display.c   |3 +
 drivers/gpu/drm/i915/intel_pm.c|   13 ++--
 4 files changed, 70 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0ce410a..0fec169 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1486,6 +1486,7 @@ int i915_gem_evict_everything(struct drm_device *dev);
 
 /* i915_gem_stolen.c */
 int i915_gem_init_stolen(struct drm_device *dev);
+int i915_gem_stolen_setup_compression(struct drm_device *dev);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
 
 /* i915_gem_tiling.c */
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index a528e4a..00b1c1d 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -86,21 +86,13 @@ static unsigned long i915_stolen_to_physical(struct 
drm_device *dev)
return base;
 }
 
-static void i915_warn_stolen(struct drm_device *dev)
-{
-   DRM_INFO(not enough stolen space for compressed buffer, disabling\n);
-   DRM_INFO(hint: you may be able to increase stolen memory size in the 
BIOS to avoid this\n);
-}
-
-static void i915_setup_compression(struct drm_device *dev, int size)
+static int i915_setup_compression(struct drm_device *dev, int size)
 {
struct drm_i915_private *dev_priv = dev-dev_private;
struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
-   unsigned long cfb_base;
-   unsigned long ll_base = 0;
 
-   /* Just in case the BIOS is doing something questionable. */
-   intel_disable_fbc(dev);
+   DRM_DEBUG_KMS(reserving %d bytes of contiguous stolen space for FBC\n,
+ size);
 
compressed_fb = drm_mm_search_free(dev_priv-mm.stolen, size, 4096, 0);
if (compressed_fb)
@@ -108,11 +100,11 @@ static void i915_setup_compression(struct drm_device 
*dev, int size)
if (!compressed_fb)
goto err;
 
-   cfb_base = dev_priv-mm.stolen_base + compressed_fb-start;
-   if (!cfb_base)
-   goto err_fb;
-
-   if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) {
+   if (HAS_PCH_SPLIT(dev))
+   I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb-start);
+   else if (IS_GM45(dev)) {
+   I915_WRITE(DPFC_CB_BASE, compressed_fb-start);
+   } else {
compressed_llb = drm_mm_search_free(dev_priv-mm.stolen,
4096, 4096, 0);
if (compressed_llb)
@@ -121,56 +113,82 @@ static void i915_setup_compression(struct drm_device 
*dev, int size)
if (!compressed_llb)
goto err_fb;
 
-   ll_base = dev_priv-mm.stolen_base + compressed_llb-start;
-   if (!ll_base)
-   goto err_llb;
-   }
+   dev_priv-compressed_llb = compressed_llb;
 
-   dev_priv-cfb_size = size;
+   I915_WRITE(FBC_CFB_BASE,
+  dev_priv-mm.stolen_base + compressed_fb-start);
+   I915_WRITE(FBC_LL_BASE,
+  dev_priv-mm.stolen_base + compressed_llb-start);
+   }
 
dev_priv-compressed_fb = compressed_fb;
-   if (HAS_PCH_SPLIT(dev))
-   I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb-start);
-   else if (IS_GM45(dev)) {
-   I915_WRITE(DPFC_CB_BASE, compressed_fb-start);
-   } else {
-   I915_WRITE(FBC_CFB_BASE, cfb_base);
-   I915_WRITE(FBC_LL_BASE, ll_base);
-   dev_priv-compressed_llb = compressed_llb;
-   }
+   dev_priv-cfb_size = size;
 
-   DRM_DEBUG_KMS(FBC base 0x%08lx, ll base 0x%08lx, size %dM\n,
- (long)cfb_base, (long)ll_base, size  20);
-   return;
+   return size;
 
-err_llb:
-   drm_mm_put_block(compressed_llb);
 err_fb:
drm_mm_put_block(compressed_fb);
 err:
dev_priv-no_fbc_reason = FBC_STOLEN_TOO_SMALL;
-   i915_warn_stolen(dev);
+   DRM_INFO(not enough stolen space for compressed buffer (need %d 
bytes), disabling\n, size);
+   DRM_INFO(hint: you may be able to increase stolen memory size in the 
BIOS to avoid this\n);
+   return 0;
+}
+
+int i915_gem_stolen_setup_compression(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev-dev_private;
+   struct drm_mm_node *entry;
+   unsigned long size;
+
+   if (dev_priv-mm.stolen_base == 0)
+   return 0;
+
+   if (dev_priv-cfb_size)
+   return dev_priv-cfb_size;
+
+   /* Try to set up FBC with 

[Intel-gfx] [PATCH 16/29] drm/i915: Fix location of stolen memory register for SandyBridge+

2012-08-11 Thread Chris Wilson
A few of the earlier registers where enlarged and so the Base Data of
Stolem Memory Register (BDSM) was pushed to 0xb0.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem_stolen.c |9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/i915_gem_stolen.c
index a01ff74..a528e4a 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -63,7 +63,11 @@ static unsigned long i915_stolen_to_physical(struct 
drm_device *dev)
 * its value of TOLUD.
 */
base = 0;
-   if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
+   if (INTEL_INFO(dev)-gen = 6) {
+   /* Read Base Data of Stolen Memory Register (BDSM) directly */
+   pci_read_config_dword(pdev, 0xB0, base);
+   base = ~4095; /* lower bits used for locking register */
+   } else if (INTEL_INFO(dev)-gen  3 || IS_G33(dev)) {
/* Read Graphics Base of Stolen Memory directly */
pci_read_config_dword(pdev, 0xA4, base);
 #if 0
@@ -172,6 +176,9 @@ int i915_gem_init_stolen(struct drm_device *dev)
if (dev_priv-mm.stolen_base == 0)
return 0;
 
+   DRM_DEBUG_KMS(found %d bytes of stolen memory at %08lx\n,
+ dev_priv-mm.gtt-stolen_size, dev_priv-mm.stolen_base);
+
/* Basic memrange allocator for stolen space */
drm_mm_init(dev_priv-mm.stolen, 0, prealloc_size);
 
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 14/29] drm: Introduce drm_mm_create_block()

2012-08-11 Thread Chris Wilson
To be used later by i915 to preallocate exact blocks of space from the
range manager.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
Cc: Dave Airlie airl...@redhat.com
---
 drivers/gpu/drm/drm_mm.c |   49 ++
 include/drm/drm_mm.h |4 
 2 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 9bb82f7..5db8c20 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -161,6 +161,55 @@ static void drm_mm_insert_helper(struct drm_mm_node 
*hole_node,
}
 }
 
+struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
+   unsigned long start,
+   unsigned long size,
+   bool atomic)
+{
+   struct drm_mm_node *hole, *node;
+   unsigned long end = start + size;
+
+   list_for_each_entry(hole, mm-hole_stack, hole_stack) {
+   unsigned long hole_start;
+   unsigned long hole_end;
+
+   BUG_ON(!hole-hole_follows);
+   hole_start = drm_mm_hole_node_start(hole);
+   hole_end = drm_mm_hole_node_end(hole);
+
+   if (hole_start  start || hole_end  end)
+   continue;
+
+   node = drm_mm_kmalloc(mm, atomic);
+   if (unlikely(node == NULL))
+   return NULL;
+
+   node-start = start;
+   node-size = size;
+   node-mm = mm;
+   node-allocated = 1;
+
+   INIT_LIST_HEAD(node-hole_stack);
+   list_add(node-node_list, hole-node_list);
+
+   if (start == hole_start) {
+   hole-hole_follows = 0;
+   list_del_init(hole-hole_stack);
+   }
+
+   node-hole_follows = 0;
+   if (end != hole_end) {
+   list_add(node-hole_stack, mm-hole_stack);
+   node-hole_follows = 1;
+   }
+
+   return node;
+   }
+
+   return NULL;
+}
+EXPORT_SYMBOL(drm_mm_create_block);
+
 struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
 unsigned long size,
 unsigned alignment,
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 06d7f79..4020f96 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -102,6 +102,10 @@ static inline bool drm_mm_initialized(struct drm_mm *mm)
 /*
  * Basic range manager support (drm_mm.c)
  */
+extern struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
+  unsigned long start,
+  unsigned long size,
+  bool atomic);
 extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
unsigned long size,
unsigned alignment,
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 19/29] drm/i915: Allow objects to be created with no backing pages, but stolen space

2012-08-11 Thread Chris Wilson
In order to accommodate objects that are not backed by struct pages, but
instead point into a contiguous region of stolen space, we need to make
various changes to avoid dereferencing obj-pages or obj-base.filp.

First introduce a marker for the stolen object, that specifies its
offset into the stolen region and implies that it has no backing pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_debugfs.c |2 ++
 drivers/gpu/drm/i915/i915_drv.h |2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 229cf27..fd0ca3e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -125,6 +125,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object 
*obj)
if (obj-gtt_space != NULL)
seq_printf(m,  (gtt offset: %08x, size: %08x),
   obj-gtt_offset, (unsigned int)obj-gtt_space-size);
+   if (obj-stolen)
+   seq_printf(m,  (stolen: %08lx), obj-stolen-start);
if (obj-pin_mappable || obj-fault_mappable) {
char s[3], *t = s;
if (obj-pin_mappable)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0fec169..d6cf758 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -908,6 +908,8 @@ struct drm_i915_gem_object {
 
/** Current space allocated to this object in the GTT, if any. */
struct drm_mm_node *gtt_space;
+   /** Stolen memory for this object, instead of being backed by shmem. */
+   struct drm_mm_node *stolen;
struct list_head gtt_list;
 
/** This object's place on the active/inactive lists */
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 12/29] drm/i915: Replace the array of pages with a scatterlist

2012-08-11 Thread Chris Wilson
Rather than have multiple data structures for describing our page layout
in conjunction with the array of pages, we can migrate all users over to
a scatterlist.

One major advantage, other than unifying the page tracking structures,
this offers is that we replace the vmalloc'ed array (which can be up to
a megabyte in size) with a chain of individual pages which helps reduce
memory pressure.

The disadvantage is that we then do not have a simple array to iterate,
or to access randomly. The common case for this is in the relocation
processing, which will typically fit within a single scatterlist page
and so be almost the same cost as the simple array. For iterating over
the array, the extra function call could be optimised away, but in
reality is an insignificant cost of either binding the pages, or
performing the pwrite/pread.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/char/agp/intel-gtt.c   |   51 +---
 drivers/gpu/drm/drm_cache.c|   23 ++
 drivers/gpu/drm/i915/i915_drv.h|   18 +++--
 drivers/gpu/drm/i915/i915_gem.c|   79 --
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |  113 ++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |3 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c|  120 ++--
 drivers/gpu/drm/i915/i915_gem_tiling.c |   16 ++--
 drivers/gpu/drm/i915/i915_irq.c|   25 +++---
 drivers/gpu/drm/i915/intel_ringbuffer.c|9 ++-
 include/drm/drmP.h |1 +
 include/drm/intel-gtt.h|   10 +--
 12 files changed, 250 insertions(+), 218 deletions(-)

diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 9ed92ef..1d39864 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -84,40 +84,33 @@ static struct _intel_private {
 #define IS_IRONLAKEintel_private.driver-is_ironlake
 #define HAS_PGTBL_EN   intel_private.driver-has_pgtbl_enable
 
-int intel_gtt_map_memory(struct page **pages, unsigned int num_entries,
-struct scatterlist **sg_list, int *num_sg)
+static int intel_gtt_map_memory(struct page **pages,
+   unsigned int num_entries,
+   struct sg_table *st)
 {
-   struct sg_table st;
struct scatterlist *sg;
int i;
 
-   if (*sg_list)
-   return 0; /* already mapped (for e.g. resume */
-
DBG(try mapping %lu pages\n, (unsigned long)num_entries);
 
-   if (sg_alloc_table(st, num_entries, GFP_KERNEL))
+   if (sg_alloc_table(st, num_entries, GFP_KERNEL))
goto err;
 
-   *sg_list = sg = st.sgl;
-
-   for (i = 0 ; i  num_entries; i++, sg = sg_next(sg))
+   for_each_sg(st-sgl, sg, num_entries,i)
sg_set_page(sg, pages[i], PAGE_SIZE, 0);
 
-   *num_sg = pci_map_sg(intel_private.pcidev, *sg_list,
-num_entries, PCI_DMA_BIDIRECTIONAL);
-   if (unlikely(!*num_sg))
+   if (!pci_map_sg(intel_private.pcidev,
+   st-sgl, st-nents, PCI_DMA_BIDIRECTIONAL))
goto err;
 
return 0;
 
 err:
-   sg_free_table(st);
+   sg_free_table(st);
return -ENOMEM;
 }
-EXPORT_SYMBOL(intel_gtt_map_memory);
 
-void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
+static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
 {
struct sg_table st;
DBG(try unmapping %lu pages\n, (unsigned long)mem-page_count);
@@ -130,7 +123,6 @@ void intel_gtt_unmap_memory(struct scatterlist *sg_list, 
int num_sg)
 
sg_free_table(st);
 }
-EXPORT_SYMBOL(intel_gtt_unmap_memory);
 
 static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode)
 {
@@ -879,8 +871,7 @@ static bool i830_check_flags(unsigned int flags)
return false;
 }
 
-void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
-unsigned int sg_len,
+void intel_gtt_insert_sg_entries(struct sg_table *st,
 unsigned int pg_start,
 unsigned int flags)
 {
@@ -892,12 +883,11 @@ void intel_gtt_insert_sg_entries(struct scatterlist 
*sg_list,
 
/* sg may merge pages, but we have to separate
 * per-page addr for GTT */
-   for_each_sg(sg_list, sg, sg_len, i) {
+   for_each_sg(st-sgl, sg, st-nents, i) {
len = sg_dma_len(sg)  PAGE_SHIFT;
for (m = 0; m  len; m++) {
dma_addr_t addr = sg_dma_address(sg) + (m  
PAGE_SHIFT);
-   intel_private.driver-write_entry(addr,
- j, flags);
+   intel_private.driver-write_entry(addr, j, flags);
j++;
}
}
@@ -905,8 +895,10 @@ void 

[Intel-gfx] [PATCH 10/29] drm/i915: Pin backing pages for pwrite

2012-08-11 Thread Chris Wilson
By using the recently introduced pinning of pages, we can safely drop
the mutex in the knowledge that the pages are not going to disappear
beneath us, and so we can simplify the code for iterating over the pages.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |   37 +
 1 file changed, 13 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index c90e265..2e5cecc 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -690,7 +690,7 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, 
int page_length,
   page_length);
kunmap_atomic(vaddr);
 
-   return ret;
+   return ret ? -EFAULT : 0;
 }
 
 /* Only difference to the fast-path function is that this can handle bit17
@@ -724,7 +724,7 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, 
int page_length,
 page_do_bit17_swizzling);
kunmap(page);
 
-   return ret;
+   return ret ? -EFAULT : 0;
 }
 
 static int
@@ -733,7 +733,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
  struct drm_i915_gem_pwrite *args,
  struct drm_file *file)
 {
-   struct address_space *mapping = 
obj-base.filp-f_path.dentry-d_inode-i_mapping;
ssize_t remain;
loff_t offset;
char __user *user_data;
@@ -742,7 +741,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
int hit_slowpath = 0;
int needs_clflush_after = 0;
int needs_clflush_before = 0;
-   int release_page;
 
user_data = (char __user *) (uintptr_t) args-data_ptr;
remain = args-size;
@@ -768,6 +766,12 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
 obj-cache_level == I915_CACHE_NONE)
needs_clflush_before = 1;
 
+   ret = i915_gem_object_get_pages(obj);
+   if (ret)
+   return ret;
+
+   i915_gem_object_pin_pages(obj);
+
offset = args-offset;
obj-dirty = 1;
 
@@ -793,18 +797,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
((shmem_page_offset | page_length)
 (boot_cpu_data.x86_clflush_size - 1));
 
-   if (obj-pages) {
-   page = obj-pages[offset  PAGE_SHIFT];
-   release_page = 0;
-   } else {
-   page = shmem_read_mapping_page(mapping, offset  
PAGE_SHIFT);
-   if (IS_ERR(page)) {
-   ret = PTR_ERR(page);
-   goto out;
-   }
-   release_page = 1;
-   }
-
+   page = obj-pages[offset  PAGE_SHIFT];
page_do_bit17_swizzling = obj_do_bit17_swizzling 
(page_to_phys(page)  (1  17)) != 0;
 
@@ -816,26 +809,20 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
goto next_page;
 
hit_slowpath = 1;
-   page_cache_get(page);
mutex_unlock(dev-struct_mutex);
-
ret = shmem_pwrite_slow(page, shmem_page_offset, page_length,
user_data, page_do_bit17_swizzling,
partial_cacheline_write,
needs_clflush_after);
 
mutex_lock(dev-struct_mutex);
-   page_cache_release(page);
+
 next_page:
set_page_dirty(page);
mark_page_accessed(page);
-   if (release_page)
-   page_cache_release(page);
 
-   if (ret) {
-   ret = -EFAULT;
+   if (ret)
goto out;
-   }
 
remain -= page_length;
user_data += page_length;
@@ -843,6 +830,8 @@ next_page:
}
 
 out:
+   i915_gem_object_unpin_pages(obj);
+
if (hit_slowpath) {
/* Fixup: Kill any reinstated backing storage pages */
if (obj-madv == __I915_MADV_PURGED)
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 09/29] drm/i915: Pin backing pages whilst exporting through a dmabuf vmap

2012-08-11 Thread Chris Wilson
We need to refcount our pages in order to prevent reaping them at
inopportune times, such as when they currently vmapped or exported to
another driver. However, we also wish to keep the lazy deallocation of
our pages so we need to take a pin/unpinned approach rather than a
simple refcount.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|   12 
 drivers/gpu/drm/i915/i915_gem.c|   11 +--
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |9 +++--
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c42190b..0805040f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -989,6 +989,7 @@ struct drm_i915_gem_object {
unsigned int has_global_gtt_mapping:1;
 
struct page **pages;
+   int pages_pin_count;
 
/**
 * DMAR support
@@ -1322,6 +1323,17 @@ void i915_gem_release_mmap(struct drm_i915_gem_object 
*obj);
 void i915_gem_lastclose(struct drm_device *dev);
 
 int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
+static inline void i915_gem_object_pin_pages(struct drm_i915_gem_object *obj)
+{
+   BUG_ON(obj-pages == NULL);
+   obj-pages_pin_count++;
+}
+static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
+{
+   BUG_ON(obj-pages_pin_count == 0);
+   obj-pages_pin_count--;
+}
+
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
 struct intel_ring_buffer *to);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ed6a1ec..c90e265 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1455,6 +1455,9 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
if (obj-sg_table || obj-pages == NULL)
return 0;
 
+   if (obj-pages_pin_count)
+   return -EBUSY;
+
ops-put_pages(obj);
 
list_del(obj-gtt_list);
@@ -1586,6 +1589,8 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
if (obj-sg_table || obj-pages)
return 0;
 
+   BUG_ON(obj-pages_pin_count);
+
ret = ops-get_pages(obj);
if (ret)
return ret;
@@ -3685,6 +3690,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
dev_priv-mm.interruptible = was_interruptible;
}
 
+   obj-pages_pin_count = 0;
i915_gem_object_put_pages(obj);
i915_gem_object_free_mmap_offset(obj);
 
@@ -4344,9 +4350,10 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, 
struct shrink_control *sc)
 
cnt = 0;
list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list)
-   cnt += obj-base.size  PAGE_SHIFT;
+   if (obj-pages_pin_count == 0)
+   cnt += obj-base.size  PAGE_SHIFT;
list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list)
-   if (obj-pin_count == 0)
+   if (obj-pin_count == 0  obj-pages_pin_count == 0)
cnt += obj-base.size  PAGE_SHIFT;
 
mutex_unlock(dev-struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 1203460..4a6982e 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -50,6 +50,8 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
/* link the pages into an SG then map the sg */
sg = drm_prime_pages_to_sg(obj-pages, npages);
nents = dma_map_sg(attachment-dev, sg-sgl, sg-nents, dir);
+   i915_gem_object_pin_pages(obj);
+
 out:
mutex_unlock(dev-struct_mutex);
return sg;
@@ -72,6 +74,7 @@ static void i915_gem_dmabuf_release(struct dma_buf *dma_buf)
obj-base.export_dma_buf = NULL;
drm_gem_object_unreference_unlocked(obj-base);
}
+   i915_gem_object_unpin_pages(obj);
 }
 
 static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
@@ -102,6 +105,7 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
}
 
obj-vmapping_count = 1;
+   i915_gem_object_pin_pages(obj);
 out_unlock:
mutex_unlock(dev-struct_mutex);
return obj-dma_buf_vmapping;
@@ -117,10 +121,11 @@ static void i915_gem_dmabuf_vunmap(struct dma_buf 
*dma_buf, void *vaddr)
if (ret)
return;
 
-   --obj-vmapping_count;
-   if (obj-vmapping_count == 0) {
+   if (--obj-vmapping_count == 0) {
vunmap(obj-dma_buf_vmapping);
obj-dma_buf_vmapping = NULL;
+
+   i915_gem_object_unpin_pages(obj);
}
mutex_unlock(dev-struct_mutex);
 }
-- 
1.7.10.4

___
Intel-gfx mailing list

[Intel-gfx] [PATCH 05/29] drm/i915: Only pwrite through the GTT if there is space in the aperture

2012-08-11 Thread Chris Wilson
Avoid stalling and waiting for the GPU by checking to see if there is
sufficient inactive space in the aperture for us to bind the buffer
prior to writing through the GTT. If there is inadequate space we will
have to stall waiting for the GPU, and incur overheads moving objects
about. Instead, only incur the clflush overhead on the target object by
writing through shmem.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h|6 --
 drivers/gpu/drm/i915/i915_gem.c|   29 +++-
 drivers/gpu/drm/i915/i915_gem_context.c|4 ++--
 drivers/gpu/drm/i915/i915_gem_evict.c  |6 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |2 +-
 drivers/gpu/drm/i915/intel_overlay.c   |2 +-
 drivers/gpu/drm/i915/intel_pm.c|2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c|6 +++---
 8 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e252947..78eed86 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1307,7 +1307,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct 
drm_device *dev,
 void i915_gem_free_object(struct drm_gem_object *obj);
 int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
 uint32_t alignment,
-bool map_and_fenceable);
+bool map_and_fenceable,
+bool nonblocking);
 void i915_gem_object_unpin(struct drm_i915_gem_object *obj);
 int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj);
 void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
@@ -1454,7 +1455,8 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
 int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
  unsigned alignment,
  unsigned cache_level,
- bool mappable);
+ bool mappable,
+ bool nonblock);
 int i915_gem_evict_everything(struct drm_device *dev);
 
 /* i915_gem_stolen.c */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0e0fc1e..b16b5ff 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -41,7 +41,8 @@ static void i915_gem_object_flush_gtt_write_domain(struct 
drm_i915_gem_object *o
 static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object 
*obj);
 static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object 
*obj,
unsigned alignment,
-   bool map_and_fenceable);
+   bool map_and_fenceable,
+   bool nonblocking);
 static int i915_gem_phys_pwrite(struct drm_device *dev,
struct drm_i915_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -609,7 +610,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev,
char __user *user_data;
int page_offset, page_length, ret;
 
-   ret = i915_gem_object_pin(obj, 0, true);
+   ret = i915_gem_object_pin(obj, 0, true, true);
if (ret)
goto out;
 
@@ -925,10 +926,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
goto out;
}
 
-   if (obj-gtt_space 
-   obj-cache_level == I915_CACHE_NONE 
+   if (obj-cache_level == I915_CACHE_NONE 
obj-tiling_mode == I915_TILING_NONE 
-   obj-map_and_fenceable 
obj-base.write_domain != I915_GEM_DOMAIN_CPU) {
ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file);
/* Note that the gtt paths might fail with non-page-backed user
@@ -936,7 +935,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 * textures). Fallback to the shmem path in that case. */
}
 
-   if (ret == -EFAULT)
+   if (ret == -EFAULT || ret == -ENOSPC)
ret = i915_gem_shmem_pwrite(dev, obj, args, file);
 
 out:
@@ -1115,7 +1114,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct 
vm_fault *vmf)
goto unlock;
}
if (!obj-gtt_space) {
-   ret = i915_gem_object_bind_to_gtt(obj, 0, true);
+   ret = i915_gem_object_bind_to_gtt(obj, 0, true, false);
if (ret)
goto unlock;
 
@@ -2771,7 +2770,8 @@ static void i915_gem_verify_gtt(struct drm_device *dev)
 static int
 i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
unsigned alignment,
-   

[Intel-gfx] [PATCH 04/29] drm/i915: Try harder to allocate an mmap_offset

2012-08-11 Thread Chris Wilson
Given the persistence of an offset for the lifetime of an object, itis
easy to contemplate how the mmap space becomes badly fragmented to the
point that further allocations fail with ENOSPC. Our only recourse at
this point is to try to purge the objects to release some space and
reattempt the allocation.

References: https://bugs.freedesktop.org/show_bug.cgi?id=39552
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_gem.c |   50 ---
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3a7ac38..0e0fc1e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1276,6 +1276,42 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_device 
*dev,
return i915_gem_get_gtt_size(dev, size, tiling_mode);
 }
 
+static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *dev_priv = obj-base.dev-dev_private;
+   int ret;
+
+   if (obj-base.map_list.map)
+   return 0;
+
+   ret = drm_gem_create_mmap_offset(obj-base);
+   if (ret != -ENOSPC)
+   return ret;
+
+   /* Badly fragmented mmap space? The only way we can recover
+* space is by destroying unwanted objects. We can't randomly release
+* mmap_offsets as userspace expects them to be persistent for the
+* lifetime of the objects. The closest we can is to release the
+* offsets on purgeable objects by truncating it and marking it purged,
+* which prevents userspace from ever using that object again.
+*/
+   i915_gem_purge(dev_priv, obj-base.size  PAGE_SHIFT);
+   ret = drm_gem_create_mmap_offset(obj-base);
+   if (ret != -ENOSPC)
+   return ret;
+
+   i915_gem_shrink_all(dev_priv);
+   return drm_gem_create_mmap_offset(obj-base);
+}
+
+static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
+{
+   if (!obj-base.map_list.map)
+   return;
+
+   drm_gem_free_mmap_offset(obj-base);
+}
+
 int
 i915_gem_mmap_gtt(struct drm_file *file,
  struct drm_device *dev,
@@ -1307,11 +1343,9 @@ i915_gem_mmap_gtt(struct drm_file *file,
goto out;
}
 
-   if (!obj-base.map_list.map) {
-   ret = drm_gem_create_mmap_offset(obj-base);
-   if (ret)
-   goto out;
-   }
+   ret = i915_gem_object_create_mmap_offset(obj);
+   if (ret)
+   goto out;
 
*offset = (u64)obj-base.map_list.hash.key  PAGE_SHIFT;
 
@@ -1360,8 +1394,7 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
inode = obj-base.filp-f_path.dentry-d_inode;
shmem_truncate_range(inode, 0, (loff_t)-1);
 
-   if (obj-base.map_list.map)
-   drm_gem_free_mmap_offset(obj-base);
+   i915_gem_object_free_mmap_offset(obj);
 
obj-madv = __I915_MADV_PURGED;
 }
@@ -3614,8 +3647,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
}
 
i915_gem_object_put_pages_gtt(obj);
-   if (obj-base.map_list.map)
-   drm_gem_free_mmap_offset(obj-base);
+   i915_gem_object_free_mmap_offset(obj);
 
drm_gem_object_release(obj-base);
i915_gem_info_remove_obj(dev_priv, obj-base.size);
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 03/29] drm/i915: Show pin count in debugfs

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_debugfs.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 16e8701..229cf27 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -118,6 +118,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object 
*obj)
   obj-madv == I915_MADV_DONTNEED ?  purgeable : );
if (obj-base.name)
seq_printf(m,  (name: %d), obj-base.name);
+   if (obj-pin_count)
+   seq_printf(m,  (pinned x %d), obj-pin_count);
if (obj-fence_reg != I915_FENCE_REG_NONE)
seq_printf(m,  (fence: %d), obj-fence_reg);
if (obj-gtt_space != NULL)
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 02/29] drm/i915: Show (count, size) of purgeable objects in i915_gem_objects

2012-08-11 Thread Chris Wilson
Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_debugfs.c |   19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index a7eb093..16e8701 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -197,8 +197,8 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
struct drm_info_node *node = (struct drm_info_node *) m-private;
struct drm_device *dev = node-minor-dev;
struct drm_i915_private *dev_priv = dev-dev_private;
-   u32 count, mappable_count;
-   size_t size, mappable_size;
+   u32 count, mappable_count, purgeable_count;
+   size_t size, mappable_size, purgeable_size;
struct drm_i915_gem_object *obj;
int ret;
 
@@ -225,9 +225,12 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
seq_printf(m,   %u [%u] inactive objects, %zu [%zu] bytes\n,
   count, mappable_count, size, mappable_size);
 
-   size = count = 0;
-   list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list)
+   size = count = purgeable_size = purgeable_count = 0;
+   list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list) {
size += obj-base.size, ++count;
+   if (obj-madv == I915_MADV_DONTNEED)
+   purgeable_size += obj-base.size, ++purgeable_count;
+   }
seq_printf(m, %u unbound objects, %zu bytes\n, count, size);
 
size = count = mappable_size = mappable_count = 0;
@@ -237,10 +240,16 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
++count;
}
if (obj-pin_mappable) {
-   mappable_size += obj-gtt_space-size;
+   mappable_size += obj-gtt_space-size,
++mappable_count;
}
+   if (obj-madv == I915_MADV_DONTNEED) {
+   purgeable_size += obj-base.size;
+   ++purgeable_count;
+   }
}
+   seq_printf(m, %u purgeable objects, %zu bytes\n,
+  purgeable_count, purgeable_size);
seq_printf(m, %u pinned mappable objects, %zu bytes\n,
   mappable_count, mappable_size);
seq_printf(m, %u fault mappable objects, %zu bytes\n,
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 07/29] drm/i915: Extract general object init routine

2012-08-11 Thread Chris Wilson
As we wish to create specialised object constructions in the near
future that share the same basic GEM object struct, export the default
initializer.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h |1 +
 drivers/gpu/drm/i915/i915_gem.c |   30 ++
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 78eed86..bbc51ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1302,6 +1302,7 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file_priv);
 void i915_gem_load(struct drm_device *dev);
 int i915_gem_init_object(struct drm_gem_object *obj);
+void i915_gem_object_init(struct drm_i915_gem_object *obj);
 struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
  size_t size);
 void i915_gem_free_object(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2f4a113..9c8787e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3557,10 +3557,26 @@ unlock:
return ret;
 }
 
+void i915_gem_object_init(struct drm_i915_gem_object *obj)
+{
+   obj-base.driver_private = NULL;
+
+   INIT_LIST_HEAD(obj-mm_list);
+   INIT_LIST_HEAD(obj-gtt_list);
+   INIT_LIST_HEAD(obj-ring_list);
+   INIT_LIST_HEAD(obj-exec_list);
+
+   obj-fence_reg = I915_FENCE_REG_NONE;
+   obj-madv = I915_MADV_WILLNEED;
+   /* Avoid an unnecessary call to unbind on the first bind. */
+   obj-map_and_fenceable = true;
+
+   i915_gem_info_add_obj(obj-base.dev-dev_private, obj-base.size);
+}
+
 struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
  size_t size)
 {
-   struct drm_i915_private *dev_priv = dev-dev_private;
struct drm_i915_gem_object *obj;
struct address_space *mapping;
u32 mask;
@@ -3584,7 +3600,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct 
drm_device *dev,
mapping = obj-base.filp-f_path.dentry-d_inode-i_mapping;
mapping_set_gfp_mask(mapping, mask);
 
-   i915_gem_info_add_obj(dev_priv, size);
+   i915_gem_object_init(obj);
 
obj-base.write_domain = I915_GEM_DOMAIN_CPU;
obj-base.read_domains = I915_GEM_DOMAIN_CPU;
@@ -3606,16 +3622,6 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct 
drm_device *dev,
} else
obj-cache_level = I915_CACHE_NONE;
 
-   obj-base.driver_private = NULL;
-   obj-fence_reg = I915_FENCE_REG_NONE;
-   INIT_LIST_HEAD(obj-mm_list);
-   INIT_LIST_HEAD(obj-gtt_list);
-   INIT_LIST_HEAD(obj-ring_list);
-   INIT_LIST_HEAD(obj-exec_list);
-   obj-madv = I915_MADV_WILLNEED;
-   /* Avoid an unnecessary call to unbind on the first bind. */
-   obj-map_and_fenceable = true;
-
return obj;
 }
 
-- 
1.7.10.4

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 01/29] drm/i915: Track unbound pages

2012-08-11 Thread Chris Wilson
When dealing with a working set larger than the GATT, or even the
mappable aperture when touching through the GTT, we end up with evicting
objects only to rebind them at a new offset again later. Moving an
object into and out of the GTT requires clflushing the pages, thus
causing a double-clflush penalty for rebinding.

To avoid having to clflush on rebinding, we can track the pages as they
are evicted from the GTT and only relinquish those pages on memory
pressure.

As usual, if it were not for the handling of out-of-memory condition and
having to manually shrink our own bo caches, it would be a net reduction
of code. Alas.

Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_debugfs.c|   14 +-
 drivers/gpu/drm/i915/i915_drv.h|   13 +-
 drivers/gpu/drm/i915/i915_gem.c|  397 ++--
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |   20 +-
 drivers/gpu/drm/i915/i915_gem_evict.c  |   13 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |9 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c|2 +-
 drivers/gpu/drm/i915/i915_irq.c|4 +-
 drivers/gpu/drm/i915/i915_trace.h  |   10 +-
 9 files changed, 240 insertions(+), 242 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 0e8f14d..a7eb093 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -211,7 +211,7 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
   dev_priv-mm.object_memory);
 
size = count = mappable_size = mappable_count = 0;
-   count_objects(dev_priv-mm.gtt_list, gtt_list);
+   count_objects(dev_priv-mm.bound_list, gtt_list);
seq_printf(m, %u [%u] objects, %zu [%zu] bytes in gtt\n,
   count, mappable_count, size, mappable_size);
 
@@ -225,8 +225,13 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
seq_printf(m,   %u [%u] inactive objects, %zu [%zu] bytes\n,
   count, mappable_count, size, mappable_size);
 
+   size = count = 0;
+   list_for_each_entry(obj, dev_priv-mm.unbound_list, gtt_list)
+   size += obj-base.size, ++count;
+   seq_printf(m, %u unbound objects, %zu bytes\n, count, size);
+
size = count = mappable_size = mappable_count = 0;
-   list_for_each_entry(obj, dev_priv-mm.gtt_list, gtt_list) {
+   list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list) {
if (obj-fault_mappable) {
size += obj-gtt_space-size;
++count;
@@ -264,7 +269,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data)
return ret;
 
total_obj_size = total_gtt_size = count = 0;
-   list_for_each_entry(obj, dev_priv-mm.gtt_list, gtt_list) {
+   list_for_each_entry(obj, dev_priv-mm.bound_list, gtt_list) {
if (list == PINNED_LIST  obj-pin_count == 0)
continue;
 
@@ -526,7 +531,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, 
void *data)
for (i = 0; i  dev_priv-num_fence_regs; i++) {
struct drm_i915_gem_object *obj = dev_priv-fence_regs[i].obj;
 
-   seq_printf(m, Fenced object[%2d] = , i);
+   seq_printf(m, Fence %d, pin count = %d, object = ,
+  i, dev_priv-fence_regs[i].pin_count);
if (obj == NULL)
seq_printf(m, unused);
else
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 261fe21..e252947 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -692,7 +692,13 @@ typedef struct drm_i915_private {
struct drm_mm gtt_space;
/** List of all objects in gtt_space. Used to restore gtt
 * mappings on resume */
-   struct list_head gtt_list;
+   struct list_head bound_list;
+   /**
+* List of objects which are not bound to the GTT (thus
+* are idle and not used by the GPU) but still have
+* (presumably uncached) pages still attached.
+*/
+   struct list_head unbound_list;
 
/** Usable portion of the GTT for GEM */
unsigned long gtt_start;
@@ -1307,8 +1313,7 @@ int __must_check i915_gem_object_unbind(struct 
drm_i915_gem_object *obj);
 void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
 void i915_gem_lastclose(struct drm_device *dev);
 
-int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
- gfp_t gfpmask);
+int __must_check i915_gem_object_get_pages_gtt(struct drm_i915_gem_object 
*obj);
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
 

Re: [Intel-gfx] Macbook Air 2012

2012-08-11 Thread Paul Menzel
Dear Daniel,


Am Samstag, den 11.08.2012, 16:05 +0200 schrieb Daniel Wagner:

 I installed on my shiny new Macbook Air 2012 Fedora 17. After adding
 
 intremap=off
 
 to the kernel arguments, I was able to install the system. The X server 
 worked out of the box. This was with a 3.3.4 kernel.
 
 Then I started to upgrade the installation and a newer kernel was 
 installed 3.5. After the reboot the screen stayed black. Upgrading to 
 Linus' 3.6-rc1 didn't help either.
 
 After some research I have tried now Daniel's tree danvet branch 
 drm-intel-next. Still no success. I also found 
 https://bugs.freedesktop.org/show_bug.cgi?id=48652 which sounds awfully 
 like what I am seeing as symptoms.
 
 Unfortunately, is my graphic trouble debugging skills rather limited. Is 
 there anything I could provide to resolve this issue?

I think there is a fix already [1].

[…]


Thanks,

Paul


[1] http://lists.freedesktop.org/archives/intel-gfx/2012-August/019545.html


signature.asc
Description: This is a digitally signed message part
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] Fan constantly running with Intel Graphics card

2012-08-11 Thread Ben Widawsky
On Fri, 10 Aug 2012 14:28:35 + (UTC)
Patrick O'Byrne pobyr...@gmail.com wrote:

 Hi,
 
 I am having an issue with a new Dell E5520 laptop (Intel(R) Core(TM)
 i5-2520 CPU @ 2.5GHz) running Linux Mint 13 (Kernel: Linux
 3.2.0-23-generic (i686)). I am using the graphics driver that ships
 with the kernel:
 
 00:02.0 VGA compatible controller [0300]: Intel Corporation 2nd
 Generation Core Processor Family Integrated Graphics Controller
 [8086:0126] (rev 09)
 
 My problem is that the fan is constantly on even though I am not
 doing any intensive processing.  The laptop runs very nicely
 (quietly) when I boot into Windows 7.
 
 There was a recent post which suggests running the following commands:
 
 $ cat /sys/kernel/debug/dri/0/i915_cur_delayinfo | grep Lowest
 then echo that value into the max freq file, e.g.:
 $ echo 400  /sys/kernel/debug/dri/0/i915_max_freq
 
 
 I tried this (and restarted the machine) but still no joy, it seems
 that in my case GPU frequency is not to blame.  Any advice would be
 greatly appreciated.
 
 Regards
 Patrick
 
 
 

Can you please try sysfs_rc6_residency test in intel-gpu-tools? This
might be the same issue I am currently fighting.

-- 
Ben Widawsky, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Apply post-sync write for pipe control invalidates

2012-08-11 Thread Ben Widawsky
On Fri, 10 Aug 2012 10:18:10 +0100
Chris Wilson ch...@chris-wilson.co.uk wrote:

 When invalidating the TLBs it is documentated as requiring a post-sync
 write. Failure to do so seems to result in a GPU hang.
 
 Exposure to this hang on IVB seems to be a result of removing the
 extra stalls required for SNB pipecontrol workarounds:
 
 commit 6c6cf5aa9c583478b19e23149feaa92d01fb8c2d
 Author: Chris Wilson ch...@chris-wilson.co.uk
 Date:   Fri Jul 20 18:02:28 2012 +0100
 
 drm/i915: Only apply the SNB pipe control w/a to gen6
 
 Reported-by: yex.t...@intel.com
 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=53322
 Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk

This is the moral equivalent of my patch to make the simulator happy
on IVB. Daniel, I'll settle for either patch.
Therefore,
Acked-by: Ben Widawsky b...@bwidawsk.net

 ---
  drivers/gpu/drm/i915/intel_ringbuffer.c |   35
 ++- 1 file changed, 21 insertions(+), 14
 deletions(-)
 
 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c
 b/drivers/gpu/drm/i915/intel_ringbuffer.c index 13318a0..7608bc2
 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
 +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
 @@ -213,20 +213,27 @@ gen6_render_ring_flush(struct intel_ring_buffer
 *ring,
* number of bits based on the write domains has little
 performance
* impact.
*/
 - flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
 - flags |= PIPE_CONTROL_TLB_INVALIDATE;
 - flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
 - flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
 - flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
 - flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
 - flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
 - flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
 - /*
 -  * Ensure that any following seqno writes only happen when
 the render
 -  * cache is indeed flushed (but only if the caller actually
 wants that).
 -  */
 - if (flush_domains)
 + if (flush_domains) {
 + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
 + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
 + /*
 +  * Ensure that any following seqno writes only happen
 +  * when the render cache is indeed flushed.
 +  */
   flags |= PIPE_CONTROL_CS_STALL;
 + }
 + if (invalidate_domains) {
 + flags |= PIPE_CONTROL_TLB_INVALIDATE;
 + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
 + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
 + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
 + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
 + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
 + /*
 +  * TLB invalidate requires a post-sync write.
 +  */
 + flags |= PIPE_CONTROL_QW_WRITE;
 + }
  
   ret = intel_ring_begin(ring, 4);
   if (ret)
 @@ -234,7 +241,7 @@ gen6_render_ring_flush(struct intel_ring_buffer
 *ring, 
   intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4));
   intel_ring_emit(ring, flags);
 - intel_ring_emit(ring, 0);
 + intel_ring_emit(ring, (u32)ring-status_page.gfx_addr+2048);
   intel_ring_emit(ring, 0);
   intel_ring_advance(ring);
  



-- 
Ben Widawsky, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: ingore eDP bpc settings

2012-08-11 Thread Daniel Vetter
On Fri, Aug 10, 2012 at 12:24:29PM +0200, Benoit Gschwind wrote:
 
 Hello,
 
 I confirm this patch work apply to kernel 3.6-rc1

Ok, I've picked this up for -fixes, with the commit message a bit
improved. Let's see whether this blows up anywhere.
-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Apply post-sync write for pipe control invalidates

2012-08-11 Thread Daniel Vetter
On Sat, Aug 11, 2012 at 12:20:19PM -0700, Ben Widawsky wrote:
 On Fri, 10 Aug 2012 10:18:10 +0100
 Chris Wilson ch...@chris-wilson.co.uk wrote:
 
  When invalidating the TLBs it is documentated as requiring a post-sync
  write. Failure to do so seems to result in a GPU hang.
  
  Exposure to this hang on IVB seems to be a result of removing the
  extra stalls required for SNB pipecontrol workarounds:
  
  commit 6c6cf5aa9c583478b19e23149feaa92d01fb8c2d
  Author: Chris Wilson ch...@chris-wilson.co.uk
  Date:   Fri Jul 20 18:02:28 2012 +0100
  
  drm/i915: Only apply the SNB pipe control w/a to gen6
  
  Reported-by: yex.t...@intel.com
  Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=53322
  Signed-off-by: Chris Wilson ch...@chris-wilson.co.uk
 
 This is the moral equivalent of my patch to make the simulator happy
 on IVB. Daniel, I'll settle for either patch.
 Therefore,
 Acked-by: Ben Widawsky b...@bwidawsk.net

Ok, I'll wait until we have testing feedback from the bug report and then
either merge this to -fixes or -next.
-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: don't grab dev-struct_mutex for userspace forcewak

2012-08-11 Thread Daniel Vetter
On Fri, Aug 10, 2012 at 11:22:15PM +0100, Chris Wilson wrote:
 On Thu,  9 Aug 2012 22:33:58 +0200, Daniel Vetter daniel.vet...@ffwll.ch 
 wrote:
  Since forcewake is now protected by a spinlock, we don't need to grab
  dev-struct_mutex any more. This way we can also get rid of a stale
  comment, noticed by Ben Widawsky while reviewing some locking changes.
  
  Signed-off-by: Daniel Vetter daniel.vet...@ffwll.ch
 
 Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk
 (Although I still wish it were not so)
Queued for -next, thanks for the review.
-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] Macbook Air 2012

2012-08-11 Thread Daniel Vetter
On Sat, Aug 11, 2012 at 04:48:15PM +0200, Paul Menzel wrote:
 Dear Daniel,
 
 
 Am Samstag, den 11.08.2012, 16:05 +0200 schrieb Daniel Wagner:
 
  I installed on my shiny new Macbook Air 2012 Fedora 17. After adding
  
  intremap=off
  
  to the kernel arguments, I was able to install the system. The X server 
  worked out of the box. This was with a 3.3.4 kernel.
  
  Then I started to upgrade the installation and a newer kernel was 
  installed 3.5. After the reboot the screen stayed black. Upgrading to 
  Linus' 3.6-rc1 didn't help either.
  
  After some research I have tried now Daniel's tree danvet branch 
  drm-intel-next. Still no success. I also found 
  https://bugs.freedesktop.org/show_bug.cgi?id=48652 which sounds awfully 
  like what I am seeing as symptoms.
  
  Unfortunately, is my graphic trouble debugging skills rather limited. Is 
  there anything I could provide to resolve this issue?
 
 I think there is a fix already [1].

Nope, that's the fix for the new retina macbook pro. Daniel, if you can,
please test the latest patch attached to that bug report and reply on the
bug report with the result.

Thanks, Daniel

-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx