[PATCH 2/2] drm: add an fb creation ioctl that takes a pixel format

2011-11-09 Thread InKi Dae
Hello, all.

I am trying to implement multi planer using your plane patch and I
think it's good but I am still warried about that drm_mode_fb_cmd2
structure has only one handle. I know this handle is sent to
framebuffer module to create new framebuffer. and the framebuffer
would cover entire a image. as you know, the image could be consisted
of one more planes. so I think now drm_mode_fb_cmd2 structure doesn't
support multi planer because it has only one handle. with update_plane
callback, a buffer of the framebuffer would be set to a hardware
overlay. how we could set two planes or three planes to the hardware
overlay? but there might be my missing point so please give me any
comments. in addition, have you been looked into gem flink and open
functions for memory sharing between processes? gem object basically
has one buffer so we can't modify it because of compatibility. so I
think it's right way that gem object manages only one buffer. for such
a reason, maybe drm_mode_fb_cmd2 structure should include one more
handles and plane count. each handle has a gem object to one plane and
plane count means how many planes are requested and when update_plane
callback is called by setplane(), we could set them of the specific
framebuffer to a hardware overlay.

another one, and also I have tried to implement the way sharing the
memory between v4l2 based drivers and drm based drivers through
application and this works fine. this feature had been introduced by
v4l2 framework as user ptr. my way also is similar to it. the
difference is that application could get new gem handle from specific
gem framework of kernel side if user application requests user ptr
import with the user space address(mmaped memory). the new gem handle
means a gem object to the memory mapped to the user space address.
this way makes different applications to be possible to share the
memory between v4l2 based driver and drm based driver. and also this
feature is considered for IOMMU so it would support non continuous
memory also. I will introduce this feature soon.

Thank you,
Inki Dae.

2011/11/9 Jesse Barnes :
> To properly support the various plane formats supported by different
> hardware, the kernel must know the pixel format of a framebuffer object.
> So add a new ioctl taking a format argument corresponding to a fourcc
> name from videodev2.h. ?Implement the fb creation hooks in terms of the
> new mode_fb_cmd2 using helpers where the old bpp/depth values are
> needed.
>
> Acked-by: Alan Cox 
> Reviewed-by: Rob Clark 
> Signed-off-by: Jesse Barnes 
> ---
> ?drivers/gpu/drm/drm_crtc.c ? ? ? ? ? ? ? ?| ?108 +++-
> ?drivers/gpu/drm/drm_crtc_helper.c ? ? ? ? | ? 50 -
> ?drivers/gpu/drm/drm_drv.c ? ? ? ? ? ? ? ? | ? ?1 +
> ?drivers/gpu/drm/i915/intel_display.c ? ? ?| ? 36 +-
> ?drivers/gpu/drm/i915/intel_drv.h ? ? ? ? ?| ? ?2 +-
> ?drivers/gpu/drm/i915/intel_fb.c ? ? ? ? ? | ? 11 ++--
> ?drivers/gpu/drm/nouveau/nouveau_display.c | ? ?4 +-
> ?drivers/gpu/drm/nouveau/nouveau_fb.h ? ? ?| ? ?2 +-
> ?drivers/gpu/drm/nouveau/nouveau_fbcon.c ? | ? 13 ++--
> ?drivers/gpu/drm/radeon/radeon_display.c ? | ? ?4 +-
> ?drivers/gpu/drm/radeon/radeon_fb.c ? ? ? ?| ? 18 +++--
> ?drivers/gpu/drm/radeon/radeon_mode.h ? ? ?| ? ?2 +-
> ?drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ? ? ? | ? 22 --
> ?drivers/gpu/drm/vmwgfx/vmwgfx_kms.h ? ? ? | ? ?1 +
> ?drivers/staging/gma500/framebuffer.c ? ? ?| ? ?2 +-
> ?include/drm/drm.h ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
> ?include/drm/drm_crtc.h ? ? ? ? ? ? ? ? ? ?| ? ?7 ++-
> ?include/drm/drm_crtc_helper.h ? ? ? ? ? ? | ? ?4 +-
> ?include/drm/drm_mode.h ? ? ? ? ? ? ? ? ? ?| ? 28 +++-
> ?include/linux/videodev2.h ? ? ? ? ? ? ? ? | ? ?1 +
> ?20 files changed, 256 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 804ef12..39cccb4 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1910,6 +1910,42 @@ out:
> ? ? ? ?return ret;
> ?}
>
> +/* Original addfb only supported RGB formats, so figure out which one */
> +uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
> +{
> + ? ? ? uint32_t fmt;
> +
> + ? ? ? switch (bpp) {
> + ? ? ? case 8:
> + ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_RGB332;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 16:
> + ? ? ? ? ? ? ? if (depth == 15)
> + ? ? ? ? ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_RGB555;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_RGB565;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 24:
> + ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_RGB24;
> + ? ? ? ? ? ? ? break;
> + ? ? ? case 32:
> + ? ? ? ? ? ? ? if (depth == 24)
> + ? ? ? ? ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_RGB24;
> + ? ? ? ? ? ? ? else if (depth == 30)
> + ? ? ? ? ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_INTC_RGB30;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? fmt = V4L2_PIX_FMT_RGB32;
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? DRM_ERROR("bad bpp, assuming RGB24 pixel format\n");
> + 

[PATCH] drm: serialize access to list of debugfs files

2011-11-09 Thread Marcin Slusarz
Nouveau, when configured with debugfs, creates debugfs files for every
channel, so structure holding list of files needs to be protected from
simultaneous changes by multiple threads.

Without this patch it's possible to hit kernel oops in
drm_debugfs_remove_files just by running a couple of xterms with
looped glxinfo.

Signed-off-by: Marcin Slusarz 
Reviewed-by: Daniel Vetter 
---
Updated changelog.
---
 drivers/gpu/drm/drm_debugfs.c   |   12 +---
 drivers/gpu/drm/i915/i915_debugfs.c |5 -
 include/drm/drmP.h  |4 +++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index d067c12..1c7a1c0 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, 
int count,
tmp->minor = minor;
tmp->dent = ent;
tmp->info_ent = [i];
-   list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+
+   mutex_lock(>debugfs_lock);
+   list_add(>list, >debugfs_list);
+   mutex_unlock(>debugfs_lock);
}
return 0;

@@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
char name[64];
int ret;

-   INIT_LIST_HEAD(>debugfs_nodes.list);
+   INIT_LIST_HEAD(>debugfs_list);
+   mutex_init(>debugfs_lock);
sprintf(name, "%d", minor_id);
minor->debugfs_root = debugfs_create_dir(name, root);
if (!minor->debugfs_root) {
@@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, 
int count,
struct drm_info_node *tmp;
int i;

+   mutex_lock(>debugfs_lock);
for (i = 0; i < count; i++) {
-   list_for_each_safe(pos, q, >debugfs_nodes.list) {
+   list_for_each_safe(pos, q, >debugfs_list) {
tmp = list_entry(pos, struct drm_info_node, list);
if (tmp->info_ent == [i]) {
debugfs_remove(tmp->dent);
@@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, 
int count,
}
}
}
+   mutex_unlock(>debugfs_lock);
return 0;
 }
 EXPORT_SYMBOL(drm_debugfs_remove_files);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index d14b44e..4f40f1c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1506,7 +1506,10 @@ drm_add_fake_info_node(struct drm_minor *minor,
node->minor = minor;
node->dent = ent;
node->info_ent = (void *) key;
-   list_add(>list, >debugfs_nodes.list);
+
+   mutex_lock(>debugfs_lock);
+   list_add(>list, >debugfs_list);
+   mutex_unlock(>debugfs_lock);

return 0;
 }
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index cf39949..1f9e951 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -990,7 +990,9 @@ struct drm_minor {
struct proc_dir_entry *proc_root;  /**< proc directory entry */
struct drm_info_node proc_nodes;
struct dentry *debugfs_root;
-   struct drm_info_node debugfs_nodes;
+
+   struct list_head debugfs_list;
+   struct mutex debugfs_lock; /* Protects debugfs_list. */

struct drm_master *master; /* currently active master for this node */
struct list_head master_list;
-- 
1.7.7.2



ttm: merge ttm_backend & ttm_tt, introduce ttm dma allocator

2011-11-09 Thread Thomas Hellstrom
On 11/09/2011 09:22 PM, j.glisse at gmail.com wrote:
> So i did an overhaul of ttm_memory, i believe the simplification i did
> make sense. See patch 5 for a longer explanation.
>
>
> Thomas with the ttm_memory change the allocation of pages won't happen
> if the accounting report that we are going over the limit and bo shrinker
> failed to free any memory to make room.
>
> The handling of dma32 zone is done as post pass of ttm memory accounting.
>

OK. I'll take a deeper look into this.

> Regarding the pagefault comment i removed, it doesn't make sense anymore
> because now we populate the whole page table in one shot. So there is
> no more prefaulting few pages but a full prefaulting. Thought i can
> add a comment stating that if you like.
>

It's important that we distinguish between populating, which populates 
pages,
and faulting, which add ptes pointing to those pages.

Previously populating happened as a side effect of faulting, but now 
that populating is done
in a single step, faulting (adding ptes) is still not. Usually a fault() 
handler adds a single pte,
but TTM is different and tries to prefault more, but it is important 
that we only error on the first
pte, so that's why the comment should stay.

> For the ttm_tt_dma struct to hold page allocator specific informations
> i think it can be done as an followup patch but if you prefer to have
> that in this patchset let me know i will respin with such changes.
>
>

I'm fine with having it as a separate patchset as long as it gets done :).


> I am in the process of retesting this whole serie and especialy the
> while memory accounting.
>
> Cheers,
> Jerome
>

/Thomas



Linux 3.2-rc1

2011-11-09 Thread Wu Fengguang
On Wed, Nov 09, 2011 at 03:40:19PM +0800, Takashi Iwai wrote:
> At Tue, 8 Nov 2011 12:23:30 -0800,
> Linus Torvalds wrote:
> > 
> > Hmm, I don't know what caused this to trigger, but I'm adding both the
> > i915 people and the HDA people to the cc, and they can fight to the
> > death about this in the HDMI Thunderdome.
> 
> It must be the new addition of ELD-passing code.

Yes, it's my fault.

> Fengguang, can the drm or i915 driver check whether ELD is changed or
> not?  Writing ELD at each time even when unchanged confuses the audio
> side, as if the monitor is hotplugged.

It's sure possible to mask out the extra events.
I'll work out a patch tomorrow.

> > Guys: One.. Two.. Three.. FIGHT!
> 
> Round two!

Three to fight!

Thanks,
Fengguang

> > On Tue, Nov 8, 2011 at 6:55 AM, Nick Bowler  
> > wrote:
> > >
> > > Mode switches are very noisy on an Intel G45 in 3.2-rc1:
> > >
> > > ?HDMI hot plug event: Codec=3 Pin=3 Presence_Detect=1 ELD_Valid=1
> > > ?HDMI status: Codec=3 Pin=3 Presence_Detect=1 ELD_Valid=1
> > > ?HDMI: detected monitor W2253 at connection type HDMI
> > > ?HDMI: available speakers: FL/FR
> > > ?HDMI: supports coding type LPCM: channels = 2, rates = 32000 44100 
> > > 48000, bits = 16 20 24
> > >
> > > These lines get printed every single switch; previously only a single
> > > line was printed once at boot (the "HDMI status" line).
> > >
> > > Cheers,
> > > --
> > > Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
> > >
> > 


[PATCH 1/5] drm: add plane support

2011-11-09 Thread Joonyoung Shim
IVER_MODESET))
> +   return -EINVAL;
> +
> +   mutex_lock(>mode_config.mutex);
> +
> +   /*
> +* First, find the plane, crtc, and fb objects.  If not available,
> +* we don't bother to call the driver.
> +*/
> +   obj = drm_mode_object_find(dev, plane_req->plane_id,
> +  DRM_MODE_OBJECT_PLANE);
> +   if (!obj) {
> +   DRM_DEBUG_KMS("Unknown plane ID %d\n",
> + plane_req->plane_id);
> +   ret = -ENOENT;
> +   goto out;
> +   }
> +   plane = obj_to_plane(obj);
> +
> +   /* No fb means shut it down */
> +   if (!plane_req->fb_id) {
> +   plane->funcs->disable_plane(plane);
> +   goto out;
> +   }
> +
> +   obj = drm_mode_object_find(dev, plane_req->crtc_id,
> +  DRM_MODE_OBJECT_CRTC);
> +   if (!obj) {
> +   DRM_DEBUG_KMS("Unknown crtc ID %d\n",
> + plane_req->crtc_id);
> +   ret = -ENOENT;
> +   goto out;
> +   }
> +   crtc = obj_to_crtc(obj);
> +
> +   obj = drm_mode_object_find(dev, plane_req->fb_id,
> +  DRM_MODE_OBJECT_FB);
> +   if (!obj) {
> +   DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
> + plane_req->fb_id);
> +   ret = -ENOENT;
> +   goto out;
> +   }
> +   fb = obj_to_fb(obj);
> +
> +   ret = plane->funcs->update_plane(plane, crtc, fb,
> +plane_req->crtc_x,
plane_req->crtc_y,
> +plane_req->crtc_w,
plane_req->crtc_h,
> +plane_req->src_x,
plane_req->src_y,
> +plane_req->src_w,
plane_req->src_h);
> +   if (!ret) {
> +   plane->crtc = crtc;
> +   plane->fb = fb;
> +   }
> +
> +out:
> +   mutex_unlock(>mode_config.mutex);
> +
> +   return ret;
> +}
> +
> +/**
>  * drm_mode_setcrtc - set CRTC configuration
>  * @inode: inode from the ioctl
>  * @filp: file * from the ioctl
> @@ -1688,11 +1939,13 @@ int drm_mode_addfb(struct drm_device *dev,
>return -EINVAL;
>
>if ((config->min_width > r->width) || (r->width >
config->max_width)) {
> -   DRM_ERROR("mode new framebuffer width not within
limits\n");
> +   DRM_ERROR("bad framebuffer width %d, should be >= %d &&
<= %d\n",
> + r->width, config->min_width, config->max_width);
>return -EINVAL;
> index 8020798..e20867e 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -44,6 +44,7 @@ struct drm_framebuffer;
>  #define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
>  #define DRM_MODE_OBJECT_+extern int drm_pl

-- 
- Joonyoung Shim
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/2009/f1f1ea33/attachment-0001.htm>


[Bug 42678] Dual Screen Monitor Gnome-shell 3 hard lock ups - ATI open source Radeon

2011-11-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=42678

--- Comment #13 from Filip  2011-11-09 10:56:34 PST ---
So, after I ran the following on my system:

sudo sh /usr/share/ati/fglrx-uninstall.sh
sudo apt-get remove --purge fglrx fglrx_* fglrx-amdcccle* fglrx-dev*

sudo apt-get remove --purge xserver-xorg-video-ati xserver-xorg-video-radeon
sudo apt-get install xserver-xorg-video-ati
sudo apt-get install --reinstall libgl1-mesa-glx:amd64 libgl1-mesa-glx:i386
libgl1-mesa-dri xserver-xorg-core
sudo mv /etc/X11/xorg.conf /etc/X11/xorg.conf.backup
sudo rm -rf /etc/ati

I still get the occasional hard freeze (the frequency was reduced to 2 - 4
times a day, which is a lot better than it was before). 

Is it possible that the old fglrx driver touched some other libraries which I
need to install? if yes, which one would those be?

As a next step, I will try the option per Xorg config

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 14/14] drm/ttm: isolate dma data from ttm_tt

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

Move dma data to a superset ttm_dma_tt structure which herit
from ttm_tt. This allow driver that don't use dma functionalities
to not have to waste memory for it.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c |   18 +
 drivers/gpu/drm/nouveau/nouveau_sgdma.c  |   22 +++
 drivers/gpu/drm/radeon/radeon_ttm.c  |   43 +++---
 drivers/gpu/drm/ttm/ttm_page_alloc.c |   10 +++---
 drivers/gpu/drm/ttm/ttm_page_alloc_dma.c |   38 +++-
 drivers/gpu/drm/ttm/ttm_tt.c |   58 -
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c   |2 +
 include/drm/ttm/ttm_bo_driver.h  |   31 +++-
 include/drm/ttm/ttm_page_alloc.h |   12 ++
 9 files changed, 155 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 36234a7..df3f19c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1052,6 +1052,7 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
 static int
 nouveau_ttm_tt_populate(struct ttm_tt *ttm)
 {
+   struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct drm_nouveau_private *dev_priv;
struct drm_device *dev;
unsigned i;
@@ -1065,7 +1066,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)

 #ifdef CONFIG_SWIOTLB
if ((dma_get_mask(dev->dev) <= DMA_BIT_MASK(32)) && swiotlb_nr_tbl()) {
-   return ttm_dma_populate(ttm, dev->dev);
+   return ttm_dma_populate((void *)ttm, dev->dev);
}
 #endif

@@ -1075,14 +1076,14 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
}

for (i = 0; i < ttm->num_pages; i++) {
-   ttm->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i],
+   ttm_dma->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i],
   0, PAGE_SIZE,
   PCI_DMA_BIDIRECTIONAL);
-   if (pci_dma_mapping_error(dev->pdev, ttm->dma_address[i])) {
+   if (pci_dma_mapping_error(dev->pdev, ttm_dma->dma_address[i])) {
while (--i) {
-   pci_unmap_page(dev->pdev, ttm->dma_address[i],
+   pci_unmap_page(dev->pdev, 
ttm_dma->dma_address[i],
   PAGE_SIZE, 
PCI_DMA_BIDIRECTIONAL);
-   ttm->dma_address[i] = 0;
+   ttm_dma->dma_address[i] = 0;
}
ttm_page_alloc_ttm_tt_unpopulate(ttm);
return -EFAULT;
@@ -1094,6 +1095,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
 static void
 nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
 {
+   struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct drm_nouveau_private *dev_priv;
struct drm_device *dev;
unsigned i;
@@ -1103,14 +1105,14 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)

 #ifdef CONFIG_SWIOTLB
if ((dma_get_mask(dev->dev) <= DMA_BIT_MASK(32)) && swiotlb_nr_tbl()) {
-   ttm_dma_unpopulate(ttm, dev->dev);
+   ttm_dma_unpopulate((void *)ttm, dev->dev);
return;
}
 #endif

for (i = 0; i < ttm->num_pages; i++) {
-   if (ttm->dma_address[i]) {
-   pci_unmap_page(dev->pdev, ttm->dma_address[i],
+   if (ttm_dma->dma_address[i]) {
+   pci_unmap_page(dev->pdev, ttm_dma->dma_address[i],
   PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index ee1eb7c..47f245e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -8,7 +8,10 @@
 #define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)

 struct nouveau_sgdma_be {
-   struct ttm_tt ttm;
+   /* this has to be the first field so populate/unpopulated in
+* nouve_bo.c works properly, otherwise have to move them here
+*/
+   struct ttm_dma_tt ttm;
struct drm_device *dev;
u64 offset;
 };
@@ -20,6 +23,7 @@ nouveau_sgdma_destroy(struct ttm_tt *ttm)

if (ttm) {
NV_DEBUG(nvbe->dev, "\n");
+   ttm_dma_tt_fini(>ttm);
kfree(nvbe);
}
 }
@@ -38,7 +42,7 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
nvbe->offset = mem->start << PAGE_SHIFT;
pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2;
for (i = 0; i < ttm->num_pages; i++) {
-   dma_addr_t dma_offset = ttm->dma_address[i];
+   dma_addr_t dma_offset = nvbe->ttm.dma_address[i];
uint32_t offset_l = lower_32_bits(dma_offset);

   

Isolate dma information from ttm_tt

2011-11-09 Thread j.gli...@gmail.com
This apply on top of the ttm_tt & backend merge patchset.

Cheers,
Jerome



r600 hdmi sound issue

2011-11-09 Thread Greg Dietsche
2011/11/9 Rafa? Mi?ecki :
> 2011/11/9 Greg Dietsche :
>> Hi,
>> I have a ASUS M4A89GTD motherboard and when I play back music in Rhythmbox,
>> there is no sound (hdmi connection). Also, the playback speed is in a sort
>> of fast forward (for example, after a few seconds of real time, rhythmbox
>> shows something like 30 seconds into the song). This seems to be a kernel
>> regression. I know that it started with 3.0, is present in 3.1, and is not
>> working in 3.2-rc1, so it is still a problem.
>>
>> I bisected and found my self here: fe6f0bd03d697835e76dd18d232ba476c65b8282.
>> However due to some graphical issues, I'm not actually able to test that
>> commit. I tried reverting that commit, but the problem wasn't fixed.
>>
>> I'd like to see this problem fixed and can compile and test patches as
>> necessary. Please let me know if you need more information - I'm happy to
>> provide it :)
>
> fe6f0bd03d697835e76dd18d232ba476c65b8282 is not likely. I suspect you
> just experience results of so-called-fix:
>
> 805c22168da76a65c978017d0fe0d59cd048e995
>
> drm/radeon/kms: disable hdmi audio by default
>
> I'm trying to get in contact with ppl affected by issues when enabling
> audio. Hopefully we can fix audio support and enable it by default
> again.
>
> For now, please load radeon module with "audio=1", or simply boot with
> radeon.audio=1
>
> --
> Rafa?
>

Thanks Rafa? that fixed it for me. (Wish I'd noticed that commit
earler). Anyway, if you need any testers at some point for this
driver, just let me know. I'd be happy to try them out.

Greg


[Bug 28426] hardware cursor corruption with radeon+kms

2011-11-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=28426

--- Comment #11 from J?rg Billeter  2011-11-09 08:51:09 PST ---
My Linux 3.1 system has been running for over 6 days now without issues. Seems
like it may finally be fixed for good :) Thanks!

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


ttm: merge ttm_backend & ttm_tt, introduce ttm dma allocator

2011-11-09 Thread Jerome Glisse
On Wed, Nov 09, 2011 at 09:25:20PM +0100, Thomas Hellstrom wrote:
> On 11/09/2011 09:22 PM, j.glisse at gmail.com wrote:
> >So i did an overhaul of ttm_memory, i believe the simplification i did
> >make sense. See patch 5 for a longer explanation.
> >
> >Thomas with the ttm_memory change the allocation of pages won't happen
> >if the accounting report that we are going over the limit and bo shrinker
> >failed to free any memory to make room.
> >
> >The handling of dma32 zone is done as post pass of ttm memory accounting.
> 
> OK. I'll take a deeper look into this.
> 
> >Regarding the pagefault comment i removed, it doesn't make sense anymore
> >because now we populate the whole page table in one shot. So there is
> >no more prefaulting few pages but a full prefaulting. Thought i can
> >add a comment stating that if you like.
> It's important that we distinguish between populating, which
> populates pages,
> and faulting, which add ptes pointing to those pages.
> 
> Previously populating happened as a side effect of faulting, but now
> that populating is done
> in a single step, faulting (adding ptes) is still not. Usually a
> fault() handler adds a single pte,
> but TTM is different and tries to prefault more, but it is important
> that we only error on the first
> pte, so that's why the comment should stay.
> 

Well yes it only fill numprefault pte, but no error can happen in the
prefault loop except for vm_insert_mixed failure, it's why i kept the
report error only if it fails on the first page. I actually did a full
pte populate at one point while working on that, dunno if that would
make sense.

> >For the ttm_tt_dma struct to hold page allocator specific informations
> >i think it can be done as an followup patch but if you prefer to have
> >that in this patchset let me know i will respin with such changes.
> >
> 
> I'm fine with having it as a separate patchset as long as it gets done :).
> 

I will spin a patch for that on top of the patchset.

Cheers,
Jerome


[PATCH 01/12] drm/ttm: remove userspace backed ttm object support

2011-11-09 Thread Jerome Glisse
On Tue, Nov 08, 2011 at 08:22:48AM +0100, Thomas Hellstrom wrote:
> On 11/08/2011 12:40 AM, j.glisse at gmail.com wrote:
> >From: Jerome Glisse
> >
> >This was never use in none of the driver, properly using userspace
> >page for bo would need more code (vma interaction mostly). Removing
> >this dead code in preparation of ttm_tt&  backend merge.
> >
> 
> Jerome,
> I actually have using user-space TTMs in the pipe for vmwgfx, and it
> doesn't need more code
> (it was used by the psb driver). There are extra requirements,
> though: It only supports cached memory and user-space CPU-access
> needs to be done using existing VMAs.
> 
> Anyway, I'll try to figure out a way to do this in the context of
> the unified tt / tt_backends.
> 

Issue, and i might be wrong here, is that you need to mark the user
vma as reserved and you need to split the vma to covert only the
portion you want. linux kernel a no helper for that. omap people
use mlock on the range they want to use to make sure that page
associated to the vma are lock and that the vma is split to only
cover the range. I don't think it's safe/enough as userspace can
unlock the vma in our back and things might fall apart at that
point.

My idea was to use mlock to split the vma and then set the reserved
flags on the vma. This will forbid userspace to munlock. When memory
is no longer needed you have to go back to locked flag and then
munlock. Also we might want to do things with page of the vma, for
instance if the object move to vram we might want to free those
pages, but here i fear i need to take a closer look at linux mm
to see what we can do safely on those page to not break any of
the kernel assumptions on those pages.

Anyway, from my inspection this whole things is fragile in regards
of other mm activities that might happen.

Cheers,
Jerome


[PATCH v2] radeon: Make sure CS mutex is held across GPU reset.

2011-11-09 Thread Jerome Glisse
On Tue, Nov 08, 2011 at 06:50:19PM +0100, Michel D?nzer wrote:
> From: Michel D?nzer 
> 
> This was only the case if the GPU reset was triggered from the CS ioctl,
> otherwise other processes could happily enter the CS ioctl and wreak havoc
> during the GPU reset.
> 
> This is a little complicated because the GPU reset can be triggered from the
> CS ioctl, in which case we're already holding the mutex, or from other call
> paths, in which case we need to lock the mutex. AFAICT the mutex API doesn't
> allow recursive locking or finding out the mutex owner, so we need to handle
> this with helper functions which allow recursive locking from the same
> process.
> 
> Signed-off-by: Michel D?nzer 

Beside not so important comment below

Reviewed-by: Jerome Glisse 
> ---
> 
> v2: Use generic radeon_mutex_(un)lock helpers which allow recursive locking
> from the same process. Eliminates int vs. bool return type issue in v1, and
> maybe these helpers can be used similarly for more locks in the future.
> 
>  drivers/gpu/drm/radeon/radeon.h|   45 
> +++-
>  drivers/gpu/drm/radeon/radeon_cs.c |   14 +-
>  drivers/gpu/drm/radeon/radeon_device.c |   16 ---
>  3 files changed, 63 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index c1e056b..671d5a5 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -1151,6 +1151,48 @@ struct r700_vram_scratch {
>   volatile uint32_t   *ptr;
>  };
>  
> +
> +/*
> + * Mutex which allows recursive locking from the same process.
> + */
> +struct radeon_mutex {
> + struct mutexmutex;
> + struct task_struct  *owner;
> + int level;
> +};
> +
> +static inline void radeon_mutex_init(struct radeon_mutex *mutex)
> +{
> + mutex_init(>mutex);
> + mutex->owner = NULL;
> + mutex->level = 0;
> +}
> +
> +static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
> +{
> + if (mutex_trylock(>mutex)) {
> + /* The mutex was unlocked before, so it's ours now */
> + mutex->owner = current;
> + } else if (mutex->owner != current) {
> + /* Another process locked the mutex, take it */
> + mutex_lock(>mutex);
> + mutex->owner = current;
> + }
> + /* Otherwise the mutex was already locked by this process */
> +
> + mutex->level++;
> +}
> +
> +static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
> +{
> + if (--mutex->level > 0)
> + return;
> +
> + mutex->owner = NULL;
> + mutex_unlock(>mutex);
> +}
> +
> +
>  /*
>   * Core structure, functions and helpers.
>   */
> @@ -1206,7 +1248,7 @@ struct radeon_device {
>   struct radeon_gem   gem;
>   struct radeon_pmpm;
>   uint32_tbios_scratch[RADEON_BIOS_NUM_SCRATCH];
> - struct mutexcs_mutex;
> + struct radeon_mutex cs_mutex;
>   struct radeon_wbwb;
>   struct radeon_dummy_pagedummy_page;
>   boolgpu_lockup;
> @@ -1245,6 +1287,7 @@ struct radeon_device {
>   struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS];
>  };
>  
> +
Adding empty line ?
>  int radeon_device_init(struct radeon_device *rdev,
>  struct drm_device *ddev,
>  struct pci_dev *pdev,
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
> b/drivers/gpu/drm/radeon/radeon_cs.c
> index fae00c0..ccaa243 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -222,7 +222,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
> struct drm_file *filp)
>   struct radeon_cs_chunk *ib_chunk;
>   int r;
>  
> - mutex_lock(>cs_mutex);
> + radeon_mutex_lock(>cs_mutex);
>   /* initialize parser */
>   memset(, 0, sizeof(struct radeon_cs_parser));
>   parser.filp = filp;
> @@ -233,14 +233,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
> struct drm_file *filp)
>   if (r) {
>   DRM_ERROR("Failed to initialize parser !\n");
>   radeon_cs_parser_fini(, r);
> - mutex_unlock(>cs_mutex);
> + radeon_mutex_unlock(>cs_mutex);
>   return r;
>   }
>   r =  radeon_ib_get(rdev, );
>   if (r) {
>   DRM_ERROR("Failed to get ib !\n");
>   radeon_cs_parser_fini(, r);
> - mutex_unlock(>cs_mutex);
> + radeon_mutex_unlock(>cs_mutex);
>   return r;
>   }
>   r = radeon_cs_parser_relocs();
> @@ -248,7 +248,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
> struct drm_file *filp)
>   if (r != -ERESTARTSYS)
>   DRM_ERROR("Failed to parse relocation %d!\n", r);
>   radeon_cs_parser_fini(, r);

[PATCH 13/13] drm/nouveau: enable the TTM DMA pool on 32-bit DMA only device V2

2011-11-09 Thread j.gli...@gmail.com
From: Konrad Rzeszutek Wilk 

If the card is capable of more than 32-bit, then use the default
TTM page pool code which allocates from anywhere in the memory.

Note: If the 'ttm.no_dma' parameter is set, the override is ignored
and the default TTM pool is used.

V2 use pci_set_consistent_dma_mask

CC: Ben Skeggs 
CC: Francisco Jerez 
CC: Dave Airlie 
Signed-off-by: Konrad Rzeszutek Wilk 
Reviewed-by: Jerome Glisse 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  |   73 -
 drivers/gpu/drm/nouveau/nouveau_debugfs.c |1 +
 drivers/gpu/drm/nouveau/nouveau_mem.c |6 ++
 drivers/gpu/drm/nouveau/nouveau_sgdma.c   |   60 +---
 4 files changed, 79 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7e5ca3f..36234a7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1049,10 +1049,79 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
nouveau_fence_unref(_fence);
 }

+static int
+nouveau_ttm_tt_populate(struct ttm_tt *ttm)
+{
+   struct drm_nouveau_private *dev_priv;
+   struct drm_device *dev;
+   unsigned i;
+   int r;
+
+   if (ttm->state != tt_unpopulated)
+   return 0;
+
+   dev_priv = nouveau_bdev(ttm->bdev);
+   dev = dev_priv->dev;
+
+#ifdef CONFIG_SWIOTLB
+   if ((dma_get_mask(dev->dev) <= DMA_BIT_MASK(32)) && swiotlb_nr_tbl()) {
+   return ttm_dma_populate(ttm, dev->dev);
+   }
+#endif
+
+   r = ttm_page_alloc_ttm_tt_populate(ttm);
+   if (r) {
+   return r;
+   }
+
+   for (i = 0; i < ttm->num_pages; i++) {
+   ttm->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i],
+  0, PAGE_SIZE,
+  PCI_DMA_BIDIRECTIONAL);
+   if (pci_dma_mapping_error(dev->pdev, ttm->dma_address[i])) {
+   while (--i) {
+   pci_unmap_page(dev->pdev, ttm->dma_address[i],
+  PAGE_SIZE, 
PCI_DMA_BIDIRECTIONAL);
+   ttm->dma_address[i] = 0;
+   }
+   ttm_page_alloc_ttm_tt_unpopulate(ttm);
+   return -EFAULT;
+   }
+   }
+   return 0;
+}
+
+static void
+nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+   struct drm_nouveau_private *dev_priv;
+   struct drm_device *dev;
+   unsigned i;
+
+   dev_priv = nouveau_bdev(ttm->bdev);
+   dev = dev_priv->dev;
+
+#ifdef CONFIG_SWIOTLB
+   if ((dma_get_mask(dev->dev) <= DMA_BIT_MASK(32)) && swiotlb_nr_tbl()) {
+   ttm_dma_unpopulate(ttm, dev->dev);
+   return;
+   }
+#endif
+
+   for (i = 0; i < ttm->num_pages; i++) {
+   if (ttm->dma_address[i]) {
+   pci_unmap_page(dev->pdev, ttm->dma_address[i],
+  PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+   }
+   }
+
+   ttm_page_alloc_ttm_tt_unpopulate(ttm);
+}
+
 struct ttm_bo_driver nouveau_bo_driver = {
.ttm_tt_create = _ttm_tt_create,
-   .ttm_tt_populate = _page_alloc_ttm_tt_populate,
-   .ttm_tt_unpopulate = _page_alloc_ttm_tt_unpopulate,
+   .ttm_tt_populate = _ttm_tt_populate,
+   .ttm_tt_unpopulate = _ttm_tt_unpopulate,
.invalidate_caches = nouveau_bo_invalidate_caches,
.init_mem_type = nouveau_bo_init_mem_type,
.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c 
b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index 8e15923..f52c2db 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -178,6 +178,7 @@ static struct drm_info_list nouveau_debugfs_list[] = {
{ "memory", nouveau_debugfs_memory_info, 0, NULL },
{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
{ "ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL },
+   { "ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL },
 };
 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)

diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 36bec48..37fcaa2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -407,6 +407,12 @@ nouveau_mem_vram_init(struct drm_device *dev)
ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
if (ret)
return ret;
+   ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits));
+   if (ret) {
+   /* Reset to default value. */
+   pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32));
+   }
+

ret = nouveau_ttm_global_init(dev_priv);
if 

[PATCH 12/13] drm/radeon/kms: Enable the TTM DMA pool if swiotlb is on V2

2011-11-09 Thread j.gli...@gmail.com
From: Konrad Rzeszutek Wilk 

With the exception that we do not handle the AGP case. We only
deal with PCIe cards such as ATI ES1000 or HD3200 that have been
detected to only do DMA up to 32-bits.

V2 force dma32 if we fail to set bigger dma mask

CC: Dave Airlie 
CC: Alex Deucher 
Signed-off-by: Konrad Rzeszutek Wilk 
Reviewed-by: Jerome Glisse 
---
 drivers/gpu/drm/radeon/radeon.h|1 -
 drivers/gpu/drm/radeon/radeon_device.c |6 ++
 drivers/gpu/drm/radeon/radeon_gart.c   |   29 +---
 drivers/gpu/drm/radeon/radeon_ttm.c|   83 +--
 4 files changed, 84 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e3170c7..63257ba 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -332,7 +332,6 @@ struct radeon_gart {
union radeon_gart_table table;
struct page **pages;
dma_addr_t  *pages_addr;
-   bool*ttm_alloced;
boolready;
 };

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index c33bc91..7c31321 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -765,8 +765,14 @@ int radeon_device_init(struct radeon_device *rdev,
r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
if (r) {
rdev->need_dma32 = true;
+   dma_bits = 32;
printk(KERN_WARNING "radeon: No suitable DMA available.\n");
}
+   r = pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
+   if (r) {
+   pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(32));
+   printk(KERN_WARNING "radeon: No coherent DMA available.\n");
+   }

/* Registers mapping */
/* TODO: block userspace mapping of io register */
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index fdc3a9a..18f496c 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -149,9 +149,6 @@ void radeon_gart_unbind(struct radeon_device *rdev, 
unsigned offset,
p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
for (i = 0; i < pages; i++, p++) {
if (rdev->gart.pages[p]) {
-   if (!rdev->gart.ttm_alloced[p])
-   pci_unmap_page(rdev->pdev, 
rdev->gart.pages_addr[p],
-   PAGE_SIZE, 
PCI_DMA_BIDIRECTIONAL);
rdev->gart.pages[p] = NULL;
rdev->gart.pages_addr[p] = rdev->dummy_page.addr;
page_base = rdev->gart.pages_addr[p];
@@ -181,23 +178,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned 
offset,
p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);

for (i = 0; i < pages; i++, p++) {
-   /* we reverted the patch using dma_addr in TTM for now but this
-* code stops building on alpha so just comment it out for now 
*/
-   if (0) { /*dma_addr[i] != DMA_ERROR_CODE) */
-   rdev->gart.ttm_alloced[p] = true;
-   rdev->gart.pages_addr[p] = dma_addr[i];
-   } else {
-   /* we need to support large memory configurations */
-   /* assume that unbind have already been call on the 
range */
-   rdev->gart.pages_addr[p] = pci_map_page(rdev->pdev, 
pagelist[i],
-   0, PAGE_SIZE,
-   PCI_DMA_BIDIRECTIONAL);
-   if (pci_dma_mapping_error(rdev->pdev, 
rdev->gart.pages_addr[p])) {
-   /* FIXME: failed to map page (return -ENOMEM?) 
*/
-   radeon_gart_unbind(rdev, offset, pages);
-   return -ENOMEM;
-   }
-   }
+   rdev->gart.pages_addr[p] = dma_addr[i];
rdev->gart.pages[p] = pagelist[i];
page_base = rdev->gart.pages_addr[p];
for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
@@ -259,12 +240,6 @@ int radeon_gart_init(struct radeon_device *rdev)
radeon_gart_fini(rdev);
return -ENOMEM;
}
-   rdev->gart.ttm_alloced = kzalloc(sizeof(bool) *
-rdev->gart.num_cpu_pages, GFP_KERNEL);
-   if (rdev->gart.ttm_alloced == NULL) {
-   radeon_gart_fini(rdev);
-   return -ENOMEM;
-   }
/* set GART entry to point to the dummy page by default */
for (i = 0; i < rdev->gart.num_cpu_pages; i++) {
rdev->gart.pages_addr[i] = 

[PATCH 11/13] swiotlb: Expose swiotlb_nr_tlb function to modules

2011-11-09 Thread j.gli...@gmail.com
From: Konrad Rzeszutek Wilk 

As a mechanism to detect whether SWIOTLB is enabled or not.
We also fix the spelling - it was swioltb instead of
swiotlb.

CC: FUJITA Tomonori 
[v1: Ripped out swiotlb_enabled]
Signed-off-by: Konrad Rzeszutek Wilk 
---
 drivers/xen/swiotlb-xen.c |2 +-
 include/linux/swiotlb.h   |2 +-
 lib/swiotlb.c |5 +++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index c984768..c50fb0b 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -152,7 +152,7 @@ void __init xen_swiotlb_init(int verbose)
char *m = NULL;
unsigned int repeat = 3;

-   nr_tbl = swioltb_nr_tbl();
+   nr_tbl = swiotlb_nr_tbl();
if (nr_tbl)
xen_io_tlb_nslabs = nr_tbl;
else {
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 445702c..e872526 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -24,7 +24,7 @@ extern int swiotlb_force;

 extern void swiotlb_init(int verbose);
 extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int 
verbose);
-extern unsigned long swioltb_nr_tbl(void);
+extern unsigned long swiotlb_nr_tbl(void);

 /*
  * Enumeration for sync targets
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 99093b3..058935e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -110,11 +110,11 @@ setup_io_tlb_npages(char *str)
 __setup("swiotlb=", setup_io_tlb_npages);
 /* make io_tlb_overflow tunable too? */

-unsigned long swioltb_nr_tbl(void)
+unsigned long swiotlb_nr_tbl(void)
 {
return io_tlb_nslabs;
 }
-
+EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
 /* Note that this doesn't work with highmem page */
 static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
  volatile void *address)
@@ -321,6 +321,7 @@ void __init swiotlb_free(void)
free_bootmem_late(__pa(io_tlb_start),
  PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
}
+   io_tlb_nslabs = 0;
 }

 static int is_swiotlb_buffer(phys_addr_t paddr)
-- 
1.7.7.1



[PATCH 10/13] ttm: Provide DMA aware TTM page pool code. V5

2011-11-09 Thread j.gli...@gmail.com
From: Konrad Rzeszutek Wilk 

In TTM world the pages for the graphic drivers are kept in three different
pools: write combined, uncached, and cached (write-back). When the pages
are used by the graphic driver the graphic adapter via its built in MMU
(or AGP) programs these pages in. The programming requires the virtual address
(from the graphic adapter perspective) and the physical address (either System 
RAM
or the memory on the card) which is obtained using the pci_map_* calls (which 
does the
virtual to physical - or bus address translation). During the graphic 
application's
"life" those pages can be shuffled around, swapped out to disk, moved from the
VRAM to System RAM or vice-versa. This all works with the existing TTM pool code
- except when we want to use the software IOTLB (SWIOTLB) code to "map" the 
physical
addresses to the graphic adapter MMU. We end up programming the bounce buffer's
physical address instead of the TTM pool memory's and get a non-worky driver.
There are two solutions:
1) using the DMA API to allocate pages that are screened by the DMA API, or
2) using the pci_sync_* calls to copy the pages from the bounce-buffer and back.

This patch fixes the issue by allocating pages using the DMA API. The second
is a viable option - but it has performance drawbacks and potential correctness
issues - think of the write cache page being bounced (SWIOTLB->TTM), the
WC is set on the TTM page and the copy from SWIOTLB not making it to the TTM
page until the page has been recycled in the pool (and used by another 
application).

The bounce buffer does not get activated often - only in cases where we have
a 32-bit capable card and we want to use a page that is allocated above the
4GB limit. The bounce buffer offers the solution of copying the contents
of that 4GB page to an location below 4GB and then back when the operation has 
been
completed (or vice-versa). This is done by using the 'pci_sync_*' calls.
Note: If you look carefully enough in the existing TTM page pool code you will
notice the GFP_DMA32 flag is used  - which should guarantee that the provided 
page
is under 4GB. It certainly is the case, except this gets ignored in two cases:
 - If user specifies 'swiotlb=force' which bounces _every_ page.
 - If user is using a Xen's PV Linux guest (which uses the SWIOTLB and the
   underlaying PFN's aren't necessarily under 4GB).

To not have this extra copying done the other option is to allocate the pages
using the DMA API so that there is not need to map the page and perform the
expensive 'pci_sync_*' calls.

This DMA API capable TTM pool requires for this the 'struct device' to
properly call the DMA API. It also has to track the virtual and bus address of
the page being handed out in case it ends up being swapped out or de-allocated -
to make sure it is de-allocated using the proper's 'struct device'.

Implementation wise the code keeps two lists: one that is attached to the
'struct device' (via the dev->dma_pools list) and a global one to be used when
the 'struct device' is unavailable (think shrinker code). The global list can
iterate over all of the 'struct device' and its associated dma_pool. The list
in dev->dma_pools can only iterate the device's dma_pool.
/[struct 
device_pool]\
/---| dev   
 |
   /+---| dma_pool  
 |
 /-+--\/
\/
 |struct device| /-->[struct dma_pool for WC][struct dma_pool for uncached]<-/--| dma_pool  
 |
 \-+--/ /   
\/
\--/
[Two pools associated with the device (WC and UC), and the parallel list
containing the 'struct dev' and 'struct dma_pool' entries]

The maximum amount of dma pools a device can have is six: write-combined,
uncached, and cached; then there are the DMA32 variants which are:
write-combined dma32, uncached dma32, and cached dma32.

Currently this code only gets activated when any variant of the SWIOTLB IOMMU
code is running (Intel without VT-d, AMD without GART, IBM Calgary and Xen PV
with PCI devices).

Tested-by: Michel D?nzer 
[v1: Using swiotlb_nr_tbl instead of swiotlb_enabled]
[v2: Major overhaul - added 'inuse_list' to seperate used from inuse and reorder
the order of lists to get better performance.]
[v3: Added comments/and some logic based on review, Added Jerome tag]
[v4: rebase on top of ttm_tt & ttm_backend merge]
[v5: rebase on top of ttm memory accounting overhaul]
Reviewed-by: Jerome Glisse 
Signed-off-by: Konrad Rzeszutek Wilk 
---
 drivers/gpu/drm/ttm/Makefile |4 +
 drivers/gpu/drm/ttm/ttm_memory.c |2 +
 drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 1235 ++
 

[PATCH 09/13] drm/ttm: introduce callback for ttm_tt populate & unpopulate V2

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

Move the page allocation and freeing to driver callback and
provide ttm code helper function for those.

Most intrusive change, is the fact that we now only fully
populate an object this simplify some of code designed around
the page fault design.

V2 Rebase on top of memory accounting overhaul

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c   |3 +
 drivers/gpu/drm/radeon/radeon_ttm.c|2 +
 drivers/gpu/drm/ttm/ttm_bo_util.c  |   31 ++-
 drivers/gpu/drm/ttm/ttm_bo_vm.c|   13 +++--
 drivers/gpu/drm/ttm/ttm_page_alloc.c   |   45 +
 drivers/gpu/drm/ttm/ttm_tt.c   |   86 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c |3 +
 include/drm/ttm/ttm_bo_driver.h|   41 +---
 include/drm/ttm/ttm_page_alloc.h   |   18 +++
 9 files changed, 123 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index b060fa4..7e5ca3f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -28,6 +28,7 @@
  */

 #include "drmP.h"
+#include "ttm/ttm_page_alloc.h"

 #include "nouveau_drm.h"
 #include "nouveau_drv.h"
@@ -1050,6 +1051,8 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)

 struct ttm_bo_driver nouveau_bo_driver = {
.ttm_tt_create = _ttm_tt_create,
+   .ttm_tt_populate = _page_alloc_ttm_tt_populate,
+   .ttm_tt_unpopulate = _page_alloc_ttm_tt_unpopulate,
.invalidate_caches = nouveau_bo_invalidate_caches,
.init_mem_type = nouveau_bo_init_mem_type,
.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index 53ff62b..490afce 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -584,6 +584,8 @@ struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device 
*bdev,

 static struct ttm_bo_driver radeon_bo_driver = {
.ttm_tt_create = _ttm_tt_create,
+   .ttm_tt_populate = _page_alloc_ttm_tt_populate,
+   .ttm_tt_unpopulate = _page_alloc_ttm_tt_unpopulate,
.invalidate_caches = _invalidate_caches,
.init_mem_type = _init_mem_type,
.evict_flags = _evict_flags,
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c 
b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 082fcae..60f204d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -244,7 +244,7 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void 
*src,
unsigned long page,
pgprot_t prot)
 {
-   struct page *d = ttm_tt_get_page(ttm, page);
+   struct page *d = ttm->pages[page];
void *dst;

if (!d)
@@ -281,7 +281,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void 
*dst,
unsigned long page,
pgprot_t prot)
 {
-   struct page *s = ttm_tt_get_page(ttm, page);
+   struct page *s = ttm->pages[page];
void *src;

if (!s)
@@ -342,6 +342,12 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
if (old_iomap == NULL && ttm == NULL)
goto out2;

+   if (ttm->state == tt_unpopulated) {
+   ret = ttm->bdev->driver->ttm_tt_populate(ttm);
+   if (ret)
+   goto out1;
+   }
+
add = 0;
dir = 1;

@@ -502,10 +508,16 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
 {
struct ttm_mem_reg *mem = >mem; pgprot_t prot;
struct ttm_tt *ttm = bo->ttm;
-   struct page *d;
-   int i;
+   int ret;

BUG_ON(!ttm);
+
+   if (ttm->state == tt_unpopulated) {
+   ret = ttm->bdev->driver->ttm_tt_populate(ttm);
+   if (ret)
+   return ret;
+   }
+
if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) {
/*
 * We're mapping a single page, and the desired
@@ -513,18 +525,9 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
 */

map->bo_kmap_type = ttm_bo_map_kmap;
-   map->page = ttm_tt_get_page(ttm, start_page);
+   map->page = ttm->pages[start_page];
map->virtual = kmap(map->page);
} else {
-   /*
-* Populate the part we're mapping;
-*/
-   for (i = start_page; i < start_page + num_pages; ++i) {
-   d = ttm_tt_get_page(ttm, i);
-   if (!d)
-   return -ENOMEM;
-   }
-
/*
 * We need to use vmap to get the desired page protection
 * or to make the buffer object look contiguous.
diff --git 

[PATCH 08/13] drm/ttm: merge ttm_backend and ttm_tt V2

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

ttm_backend will exist only and only with a ttm_tt, and ttm_tt
will be of interesting use only when bind to a backend. Thus to
avoid code & data duplication btw the two merge them.

V2 Rebase on top of memory accountign overhaul

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c|   14 ++-
 drivers/gpu/drm/nouveau/nouveau_drv.h   |5 +-
 drivers/gpu/drm/nouveau/nouveau_sgdma.c |  188 --
 drivers/gpu/drm/radeon/radeon_ttm.c |  222 ---
 drivers/gpu/drm/ttm/ttm_agp_backend.c   |   88 +
 drivers/gpu/drm/ttm/ttm_bo.c|9 +-
 drivers/gpu/drm/ttm/ttm_tt.c|   60 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c  |   66 +++--
 include/drm/ttm/ttm_bo_driver.h |  104 ++-
 9 files changed, 295 insertions(+), 461 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7226f41..b060fa4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -343,8 +343,10 @@ nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, 
u32 val)
*mem = val;
 }

-static struct ttm_backend *
-nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
+static struct ttm_tt *
+nouveau_ttm_tt_create(struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ struct page *dummy_read_page)
 {
struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
struct drm_device *dev = dev_priv->dev;
@@ -352,11 +354,13 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device 
*bdev)
switch (dev_priv->gart_info.type) {
 #if __OS_HAS_AGP
case NOUVEAU_GART_AGP:
-   return ttm_agp_backend_init(bdev, dev->agp->bridge);
+   return ttm_agp_tt_create(bdev, dev->agp->bridge,
+size, page_flags, dummy_read_page);
 #endif
case NOUVEAU_GART_PDMA:
case NOUVEAU_GART_HW:
-   return nouveau_sgdma_init_ttm(dev);
+   return nouveau_sgdma_create_ttm(bdev, size, page_flags,
+   dummy_read_page);
default:
NV_ERROR(dev, "Unknown GART type %d\n",
 dev_priv->gart_info.type);
@@ -1045,7 +1049,7 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
 }

 struct ttm_bo_driver nouveau_bo_driver = {
-   .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
+   .ttm_tt_create = _ttm_tt_create,
.invalidate_caches = nouveau_bo_invalidate_caches,
.init_mem_type = nouveau_bo_init_mem_type,
.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 29837da..0c53e39 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1000,7 +1000,10 @@ extern int nouveau_sgdma_init(struct drm_device *);
 extern void nouveau_sgdma_takedown(struct drm_device *);
 extern uint32_t nouveau_sgdma_get_physical(struct drm_device *,
   uint32_t offset);
-extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+extern struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
+  unsigned long size,
+  uint32_t page_flags,
+  struct page *dummy_read_page);

 /* nouveau_debugfs.c */
 #if defined(CONFIG_DRM_NOUVEAU_DEBUG)
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index b75258a..bc2ab90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -8,44 +8,23 @@
 #define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)

 struct nouveau_sgdma_be {
-   struct ttm_backend backend;
+   struct ttm_tt ttm;
struct drm_device *dev;
-
-   dma_addr_t *pages;
-   unsigned nr_pages;
-   bool unmap_pages;
-
u64 offset;
-   bool bound;
 };

 static int
-nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
-  struct page **pages, struct page *dummy_read_page,
-  dma_addr_t *dma_addrs)
+nouveau_sgdma_dma_map(struct ttm_tt *ttm)
 {
-   struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+   struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
struct drm_device *dev = nvbe->dev;
int i;

-   NV_DEBUG(nvbe->dev, "num_pages = %ld\n", num_pages);
-
-   nvbe->pages = dma_addrs;
-   nvbe->nr_pages = num_pages;
-   nvbe->unmap_pages = true;
-
-   /* this code path isn't called and is incorrect anyways */
-

[PATCH 07/13] drm/ttm: test for dma_address array allocation failure

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/ttm/ttm_tt.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 303bbba..2dab08b 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -293,7 +293,7 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, 
unsigned long size,
ttm->dummy_read_page = dummy_read_page;

ttm_tt_alloc_page_directory(ttm);
-   if (!ttm->pages) {
+   if (!ttm->pages || !ttm->dma_address) {
ttm_tt_destroy(ttm);
printk(KERN_ERR TTM_PFX "Failed allocating page table\n");
return NULL;
-- 
1.7.7.1



[PATCH 06/13] drm/ttm: convert page allocation to use page ptr array instead of list V4

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

Use the ttm_tt page ptr array for page allocation, move the list to
array unwinding into the page allocation functions.

V2 split the fix to use ttm put page as a separate fix
properly fill pages array when TTM_PAGE_FLAG_ZERO_ALLOC is not
set
V3 Added back page_count()==1 check when freeing page
V4 Rebase on top of memory accounting overhaul

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/ttm/ttm_memory.c |   47 +++--
 drivers/gpu/drm/ttm/ttm_page_alloc.c |   90 --
 drivers/gpu/drm/ttm/ttm_tt.c |   68 --
 include/drm/ttm/ttm_memory.h |   13 +++--
 include/drm/ttm/ttm_page_alloc.h |   17 +++---
 5 files changed, 120 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index b550baf..98f6899 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -326,32 +326,45 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob,
 }
 EXPORT_SYMBOL(ttm_mem_global_alloc);

-int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
- struct page *page,
- bool no_wait)
+int ttm_mem_global_alloc_pages(struct ttm_mem_global *glob,
+  unsigned npages,
+  bool no_wait)
 {
-
-   if (ttm_mem_global_alloc(glob, PAGE_SIZE, no_wait))
+   if (ttm_mem_global_alloc(glob, PAGE_SIZE * npages, no_wait))
return -ENOMEM;
+   ttm_check_swapping(glob);
+   return 0;
+}
+
+void ttm_mem_global_account_pages(struct ttm_mem_global *glob,
+ struct page **pages,
+ unsigned npages)
+{
+   unsigned i;

/* check if page is dma32 */
-   if (page_to_pfn(page) > 0x0010UL) {
-   spin_lock(>lock);
-   glob->used_mem -= PAGE_SIZE;
-   glob->used_dma32_mem += PAGE_SIZE;
-   spin_unlock(>lock);
+   spin_lock(>lock);
+   for (i = 0; i < npages; i++) {
+   if (page_to_pfn(pages[i]) > 0x0010UL) {
+   glob->used_mem -= PAGE_SIZE;
+   glob->used_dma32_mem += PAGE_SIZE;
+   }
}
-   ttm_check_swapping(glob);
-   return 0;
+   spin_unlock(>lock);
 }

-void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page)
+void ttm_mem_global_free_pages(struct ttm_mem_global *glob,
+  struct page **pages, unsigned npages)
 {
+   unsigned i;
+
spin_lock(>lock);
-   if (page_to_pfn(page) > 0x0010UL) {
-   glob->used_dma32_mem -= PAGE_SIZE;
-   } else {
-   glob->used_mem -= PAGE_SIZE;
+   for (i = 0; i < npages; i++) {
+   if (page_to_pfn(pages[i]) > 0x0010UL) {
+   glob->used_dma32_mem -= PAGE_SIZE;
+   } else {
+   glob->used_mem -= PAGE_SIZE;
+   }
}
spin_unlock(>lock);
 }
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c 
b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 727e93d..c4f18b9 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -619,8 +619,10 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool 
*pool,
  * @return count of pages still required to fulfill the request.
  */
 static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool,
-   struct list_head *pages, int ttm_flags,
-   enum ttm_caching_state cstate, unsigned count)
+   struct list_head *pages,
+   int ttm_flags,
+   enum ttm_caching_state cstate,
+   unsigned count)
 {
unsigned long irq_flags;
struct list_head *p;
@@ -664,13 +666,14 @@ out:
  * On success pages list will hold count number of correctly
  * cached pages.
  */
-int ttm_get_pages(struct list_head *pages, int flags,
- enum ttm_caching_state cstate, unsigned count,
- dma_addr_t *dma_address)
+int ttm_get_pages(struct page **pages, unsigned npages, int flags,
+ enum ttm_caching_state cstate, dma_addr_t *dma_address)
 {
struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
struct page *p = NULL;
+   struct list_head plist;
gfp_t gfp_flags = GFP_USER;
+   unsigned count = 0;
int r;

/* set zero flag for page allocation if required */
@@ -684,94 +687,107 @@ int ttm_get_pages(struct list_head *pages, int flags,
else
gfp_flags |= GFP_HIGHUSER;

-   for (r = 0; r < count; ++r) {
-   p = alloc_page(gfp_flags);
-   if (!p) {
-
+   for 

[PATCH 05/13] drm/ttm: overhaul memory accounting

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

This is an overhaul of the ttm memory accounting. This tries to keep
the same global behavior while removing the whole zone concept. It
keeps a distrinction for dma32 so that we make sure that ttm don't
starve the dma32 zone.

There is 3 threshold for memory allocation :
- max_mem is the maximum memory the whole ttm infrastructure is
  going to allow allocation for (exception of system process see
  below)
- emer_mem is the maximum memory allowed for system process, this
  limit is > to max_mem
- swap_limit is the threshold at which point ttm will start to
  try to swap object because ttm is getting close the max_mem
  limit
- swap_dma32_limit is the threshold at which point ttm will start
  swap object to try to reduce the pressure on the dma32 zone. Note
  that we don't specificly target object to swap to it might very
  well free more memory from highmem rather than from dma32

Accounting is done through used_mem & used_dma32_mem, which sum give
the total amount of memory actually accounted by ttm.

Idea is that allocation will fail if (used_mem + used_dma32_mem) >
max_mem and if swapping fail to make enough room.

The used_dma32_mem can be updated as a later stage, allowing to
perform accounting test before allocating a whole batch of pages.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/ttm/ttm_bo.c |2 +-
 drivers/gpu/drm/ttm/ttm_memory.c |  517 +-
 drivers/gpu/drm/ttm/ttm_object.c |3 +-
 drivers/gpu/drm/ttm/ttm_tt.c |2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c|8 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |8 +-
 include/drm/ttm/ttm_memory.h |   23 +-
 7 files changed, 168 insertions(+), 395 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4bde335..92712798 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1252,7 +1252,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev,

size_t acc_size =
ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-   ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+   ret = ttm_mem_global_alloc(mem_glob, acc_size, false);
if (unlikely(ret != 0))
return ret;

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index e70ddd8..b550baf 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -35,21 +35,10 @@
 #include 
 #include 

-#define TTM_MEMORY_ALLOC_RETRIES 4
-
-struct ttm_mem_zone {
-   struct kobject kobj;
-   struct ttm_mem_global *glob;
-   const char *name;
-   uint64_t zone_mem;
-   uint64_t emer_mem;
-   uint64_t max_mem;
-   uint64_t swap_limit;
-   uint64_t used_mem;
-};
+#define TTM_MEMORY_RETRIES 4

 static struct attribute ttm_mem_sys = {
-   .name = "zone_memory",
+   .name = "memory",
.mode = S_IRUGO
 };
 static struct attribute ttm_mem_emer = {
@@ -64,140 +53,141 @@ static struct attribute ttm_mem_swap = {
.name = "swap_limit",
.mode = S_IRUGO | S_IWUSR
 };
+static struct attribute ttm_mem_dma32_swap = {
+   .name = "swap_dma32_limit",
+   .mode = S_IRUGO | S_IWUSR
+};
 static struct attribute ttm_mem_used = {
.name = "used_memory",
.mode = S_IRUGO
 };
+static struct attribute ttm_mem_dma32_used = {
+   .name = "used_dma32_memory",
+   .mode = S_IRUGO
+};

-static void ttm_mem_zone_kobj_release(struct kobject *kobj)
-{
-   struct ttm_mem_zone *zone =
-   container_of(kobj, struct ttm_mem_zone, kobj);
-
-   printk(KERN_INFO TTM_PFX
-  "Zone %7s: Used memory at exit: %llu kiB.\n",
-  zone->name, (unsigned long long) zone->used_mem >> 10);
-   kfree(zone);
-}
-
-static ssize_t ttm_mem_zone_show(struct kobject *kobj,
-struct attribute *attr,
-char *buffer)
+static ssize_t ttm_mem_global_show(struct kobject *kobj,
+  struct attribute *attr,
+  char *buffer)
 {
-   struct ttm_mem_zone *zone =
-   container_of(kobj, struct ttm_mem_zone, kobj);
-   uint64_t val = 0;
+   struct ttm_mem_global *glob =
+   container_of(kobj, struct ttm_mem_global, kobj);
+   unsigned long val = 0;

-   spin_lock(>glob->lock);
+   spin_lock(>lock);
if (attr == _mem_sys)
-   val = zone->zone_mem;
+   val = glob->mem;
else if (attr == _mem_emer)
-   val = zone->emer_mem;
+   val = glob->emer_mem;
else if (attr == _mem_max)
-   val = zone->max_mem;
+   val = glob->max_mem;
else if (attr == _mem_swap)
-   val = zone->swap_limit;
+   val = glob->swap_limit;
else if (attr == _mem_used)
- 

[PATCH 04/13] drm/ttm: use ttm put pages function to properly restore cache attribute

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

On failure we need to make sure the page we free has wb cache
attribute. Do this pas call the proper ttm page helper function.

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/ttm/ttm_tt.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 8b7a6d0..3fb4c6d 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -89,7 +89,10 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, 
int index)
}
return p;
 out_err:
-   put_page(p);
+   INIT_LIST_HEAD();
+   list_add(>lru, );
+   ttm_put_pages(, 1, ttm->page_flags,
+ ttm->caching_state, >dma_address[index]);
return NULL;
 }

-- 
1.7.7.1



[PATCH 03/13] drm/ttm: remove unused backend flags field

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

This field is not use by any of the driver just drop it.

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/radeon/radeon_ttm.c |1 -
 include/drm/ttm/ttm_bo_driver.h |2 --
 2 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index 0b5468b..97c76ae 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -787,7 +787,6 @@ struct ttm_backend *radeon_ttm_backend_create(struct 
radeon_device *rdev)
return NULL;
}
gtt->backend.bdev = >mman.bdev;
-   gtt->backend.flags = 0;
gtt->backend.func = _backend_func;
gtt->rdev = rdev;
gtt->pages = NULL;
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 9da182b..6d17140 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -106,7 +106,6 @@ struct ttm_backend_func {
  * struct ttm_backend
  *
  * @bdev: Pointer to a struct ttm_bo_device.
- * @flags: For driver use.
  * @func: Pointer to a struct ttm_backend_func that describes
  * the backend methods.
  *
@@ -114,7 +113,6 @@ struct ttm_backend_func {

 struct ttm_backend {
struct ttm_bo_device *bdev;
-   uint32_t flags;
struct ttm_backend_func *func;
 };

-- 
1.7.7.1



[PATCH 02/13] drm/ttm: remove split btw highmen and lowmem page

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

Split btw highmem and lowmem page was rendered useless by the
pool code. Remove it. Note further cleanup would change the
ttm page allocation helper to actualy take an array instead
of relying on list this could drasticly reduce the number of
function call in the common case of allocation whole buffer.

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/ttm/ttm_tt.c|   11 ++-
 include/drm/ttm/ttm_bo_driver.h |7 ---
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 82a1161..8b7a6d0 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -69,7 +69,7 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int 
index)
struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
int ret;

-   while (NULL == (p = ttm->pages[index])) {
+   if (NULL == (p = ttm->pages[index])) {

INIT_LIST_HEAD();

@@ -85,10 +85,7 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, 
int index)
if (unlikely(ret != 0))
goto out_err;

-   if (PageHighMem(p))
-   ttm->pages[--ttm->first_himem_page] = p;
-   else
-   ttm->pages[++ttm->last_lomem_page] = p;
+   ttm->pages[index] = p;
}
return p;
 out_err:
@@ -270,8 +267,6 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
ttm_put_pages(, count, ttm->page_flags, ttm->caching_state,
  ttm->dma_address);
ttm->state = tt_unpopulated;
-   ttm->first_himem_page = ttm->num_pages;
-   ttm->last_lomem_page = -1;
 }

 void ttm_tt_destroy(struct ttm_tt *ttm)
@@ -315,8 +310,6 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, 
unsigned long size,

ttm->glob = bdev->glob;
ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-   ttm->first_himem_page = ttm->num_pages;
-   ttm->last_lomem_page = -1;
ttm->caching_state = tt_cached;
ttm->page_flags = page_flags;

diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 37527d6..9da182b 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -136,11 +136,6 @@ enum ttm_caching_state {
  * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL
  * pointer.
  * @pages: Array of pages backing the data.
- * @first_himem_page: Himem pages are put last in the page array, which
- * enables us to run caching attribute changes on only the first part
- * of the page array containing lomem pages. This is the index of the
- * first himem page.
- * @last_lomem_page: Index of the last lomem page in the page array.
  * @num_pages: Number of pages in the page array.
  * @bdev: Pointer to the current struct ttm_bo_device.
  * @be: Pointer to the ttm backend.
@@ -157,8 +152,6 @@ enum ttm_caching_state {
 struct ttm_tt {
struct page *dummy_read_page;
struct page **pages;
-   long first_himem_page;
-   long last_lomem_page;
uint32_t page_flags;
unsigned long num_pages;
struct ttm_bo_global *glob;
-- 
1.7.7.1



[PATCH 01/13] drm/ttm: remove userspace backed ttm object support

2011-11-09 Thread j.gli...@gmail.com
From: Jerome Glisse 

This was never use in none of the driver, properly using userspace
page for bo would need more code (vma interaction mostly). Removing
this dead code in preparation of ttm_tt & backend merge.

Signed-off-by: Jerome Glisse 
Reviewed-by: Konrad Rzeszutek Wilk 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/ttm/ttm_bo.c|   22 
 drivers/gpu/drm/ttm/ttm_tt.c|  105 +--
 include/drm/ttm/ttm_bo_api.h|5 --
 include/drm/ttm/ttm_bo_driver.h |   24 -
 4 files changed, 1 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 617b646..4bde335 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -342,22 +342,6 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, 
bool zero_alloc)
if (unlikely(bo->ttm == NULL))
ret = -ENOMEM;
break;
-   case ttm_bo_type_user:
-   bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
-   page_flags | TTM_PAGE_FLAG_USER,
-   glob->dummy_read_page);
-   if (unlikely(bo->ttm == NULL)) {
-   ret = -ENOMEM;
-   break;
-   }
-
-   ret = ttm_tt_set_user(bo->ttm, current,
- bo->buffer_start, bo->num_pages);
-   if (unlikely(ret != 0)) {
-   ttm_tt_destroy(bo->ttm);
-   bo->ttm = NULL;
-   }
-   break;
default:
printk(KERN_ERR TTM_PFX "Illegal buffer object type\n");
ret = -EINVAL;
@@ -907,16 +891,12 @@ static uint32_t ttm_bo_select_caching(struct 
ttm_mem_type_manager *man,
 }

 static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
-bool disallow_fixed,
 uint32_t mem_type,
 uint32_t proposed_placement,
 uint32_t *masked_placement)
 {
uint32_t cur_flags = ttm_bo_type_flags(mem_type);

-   if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && disallow_fixed)
-   return false;
-
if ((cur_flags & proposed_placement & TTM_PL_MASK_MEM) == 0)
return false;

@@ -961,7 +941,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
man = >man[mem_type];

type_ok = ttm_bo_mt_compatible(man,
-   bo->type == ttm_bo_type_user,
mem_type,
placement->placement[i],
_flags);
@@ -1009,7 +988,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
if (!man->has_type)
continue;
if (!ttm_bo_mt_compatible(man,
-   bo->type == ttm_bo_type_user,
mem_type,
placement->busy_placement[i],
_flags))
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 58c271e..82a1161 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -62,43 +62,6 @@ static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
ttm->dma_address = NULL;
 }

-static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
-{
-   int write;
-   int dirty;
-   struct page *page;
-   int i;
-   struct ttm_backend *be = ttm->be;
-
-   BUG_ON(!(ttm->page_flags & TTM_PAGE_FLAG_USER));
-   write = ((ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0);
-   dirty = ((ttm->page_flags & TTM_PAGE_FLAG_USER_DIRTY) != 0);
-
-   if (be)
-   be->func->clear(be);
-
-   for (i = 0; i < ttm->num_pages; ++i) {
-   page = ttm->pages[i];
-   if (page == NULL)
-   continue;
-
-   if (page == ttm->dummy_read_page) {
-   BUG_ON(write);
-   continue;
-   }
-
-   if (write && dirty && !PageReserved(page))
-   set_page_dirty_lock(page);
-
-   ttm->pages[i] = NULL;
-   ttm_mem_global_free(ttm->glob->mem_glob, PAGE_SIZE);
-   put_page(page);
-   }
-   ttm->state = tt_unpopulated;
-   ttm->first_himem_page = ttm->num_pages;
-   ttm->last_lomem_page = -1;
-}
-
 static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
 {
struct page *p;
@@ -325,10 +288,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
}

if (likely(ttm->pages != NULL)) {
-   if (ttm->page_flags & 

ttm: merge ttm_backend & ttm_tt, introduce ttm dma allocator

2011-11-09 Thread j.gli...@gmail.com
So i did an overhaul of ttm_memory, i believe the simplification i did
make sense. See patch 5 for a longer explanation.

Thomas with the ttm_memory change the allocation of pages won't happen
if the accounting report that we are going over the limit and bo shrinker
failed to free any memory to make room.

The handling of dma32 zone is done as post pass of ttm memory accounting.

Regarding the pagefault comment i removed, it doesn't make sense anymore
because now we populate the whole page table in one shot. So there is
no more prefaulting few pages but a full prefaulting. Thought i can
add a comment stating that if you like.

For the ttm_tt_dma struct to hold page allocator specific informations
i think it can be done as an followup patch but if you prefer to have
that in this patchset let me know i will respin with such changes.

I am in the process of retesting this whole serie and especialy the
while memory accounting.

Cheers,
Jerome


[Bug 27314] displayport link training fails on certain panels (channel equalization fails)

2011-11-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=27314

--- Comment #59 from Alex Deucher  2011-11-09 06:44:37 PST 
---
(In reply to comment #57)
> Created attachment 53309 [details]
> xorg log with the ati driver in fedora16
> 
> I have just installed fedora 16 on an "imac11,1", and I still have the same
> problem. I have attached the xorg log, let me know if there is anything else I
> could do to help.
> 
> I checked that the patch pointed by Comment 55 is include in the linux 3.1
> shipping with fedora.
> 
> I am going to try the current linus tree and let you know if that helps.

Why are you using UMS?  All of the relevant fixes have been in KMS.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 3/3] vmwgfx: Only allow 64x64 cursors

2011-11-09 Thread Thomas Hellstrom
From: Jakob Bornecrantz 

Snooping code expects this to be the case.

Signed-off-by: Jakob Bornecrantz 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 40c7e61..880e285 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct 
drm_file *file_priv,
struct vmw_dma_buffer *dmabuf = NULL;
int ret;

+   /* A lot of the code assumes this */
+   if (handle && (width != 64 || height != 64))
+   return -EINVAL;
+
if (handle) {
ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
 handle, );
-- 
1.7.4.4



[PATCH 2/3] vmwgfx: Initialize clip rect loop correctly in surface dirty

2011-11-09 Thread Thomas Hellstrom
From: Jakob Bornecrantz 

Signed-off-by: Jakob Bornecrantz 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index f3ab1fe..40c7e61 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -410,8 +410,9 @@ static int do_surface_dirty_sou(struct vmw_private 
*dev_priv,
top = clips->y1;
bottom = clips->y2;

-   clips_ptr = clips;
-   for (i = 1; i < num_clips; i++, clips_ptr += inc) {
+   /* skip the first clip rect */
+   for (i = 1, clips_ptr = clips + inc;
+i < num_clips; i++, clips_ptr += inc) {
left = min_t(int, left, (int)clips_ptr->x1);
right = max_t(int, right, (int)clips_ptr->x2);
top = min_t(int, top, (int)clips_ptr->y1);
-- 
1.7.4.4



[PATCH 1/3] vmwgfx: Close screen object system

2011-11-09 Thread Thomas Hellstrom
From: Jakob Bornecrantz 

Signed-off-by: Jakob Bornecrantz 
Reviewed-by: Thomas Hellstrom 
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 03daefa..f3ab1fe 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1323,7 +1323,10 @@ int vmw_kms_close(struct vmw_private *dev_priv)
 * drm_encoder_cleanup which takes the lock we deadlock.
 */
drm_mode_config_cleanup(dev_priv->dev);
-   vmw_kms_close_legacy_display_system(dev_priv);
+   if (dev_priv->sou_priv)
+   vmw_kms_close_screen_object_display(dev_priv);
+   else
+   vmw_kms_close_legacy_display_system(dev_priv);
return 0;
 }

-- 
1.7.4.4



[PATCH -fixes 0/3] vmwgfx fixes

2011-11-09 Thread Thomas Hellstrom
A couple of bugfixes for vmwgfx kms.



r600 hdmi sound issue

2011-11-09 Thread Rafał Miłecki
2011/11/9 Greg Dietsche :
> Hi,
> I have a ASUS M4A89GTD motherboard and when I play back music in Rhythmbox,
> there is no sound (hdmi connection). Also, the playback speed is in a sort
> of fast forward (for example, after a few seconds of real time, rhythmbox
> shows something like 30 seconds into the song). This seems to be a kernel
> regression. I know that it started with 3.0, is present in 3.1, and is not
> working in 3.2-rc1, so it is still a problem.
>
> I bisected and found my self here: fe6f0bd03d697835e76dd18d232ba476c65b8282.
> However due to some graphical issues, I'm not actually able to test that
> commit. I tried reverting that commit, but the problem wasn't fixed.
>
> I'd like to see this problem fixed and can compile and test patches as
> necessary. Please let me know if you need more information - I'm happy to
> provide it :)

fe6f0bd03d697835e76dd18d232ba476c65b8282 is not likely. I suspect you
just experience results of so-called-fix:

805c22168da76a65c978017d0fe0d59cd048e995

drm/radeon/kms: disable hdmi audio by default

I'm trying to get in contact with ppl affected by issues when enabling
audio. Hopefully we can fix audio support and enable it by default
again.

For now, please load radeon module with "audio=1", or simply boot with
radeon.audio=1

-- 
Rafa?


Linux 3.2-rc1

2011-11-09 Thread Takashi Iwai
At Tue, 8 Nov 2011 12:23:30 -0800,
Linus Torvalds wrote:
> 
> Hmm, I don't know what caused this to trigger, but I'm adding both the
> i915 people and the HDA people to the cc, and they can fight to the
> death about this in the HDMI Thunderdome.

It must be the new addition of ELD-passing code.

Fengguang, can the drm or i915 driver check whether ELD is changed or
not?  Writing ELD at each time even when unchanged confuses the audio
side, as if the monitor is hotplugged.

> 
> Guys: One.. Two.. Three.. FIGHT!

Round two!


Takashi

>  Linus
> 
> On Tue, Nov 8, 2011 at 6:55 AM, Nick Bowler  
> wrote:
> >
> > Mode switches are very noisy on an Intel G45 in 3.2-rc1:
> >
> > ?HDMI hot plug event: Codec=3 Pin=3 Presence_Detect=1 ELD_Valid=1
> > ?HDMI status: Codec=3 Pin=3 Presence_Detect=1 ELD_Valid=1
> > ?HDMI: detected monitor W2253 at connection type HDMI
> > ?HDMI: available speakers: FL/FR
> > ?HDMI: supports coding type LPCM: channels = 2, rates = 32000 44100 48000, 
> > bits = 16 20 24
> >
> > These lines get printed every single switch; previously only a single
> > line was printed once at boot (the "HDMI status" line).
> >
> > Cheers,
> > --
> > Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
> >
> 


[PATCH] drm/ttm: overhaul memory accounting V2

2011-11-09 Thread Jerome Glisse
This is an overhaul of the ttm memory accounting. This tries to keep
the same global behavior while removing the whole zone concept. It
keeps a distrinction for dma32 so that we make sure that ttm don't
starve the dma32 zone.

There is 3 threshold for memory allocation :
- max_mem is the maximum memory the whole ttm infrastructure is
  going to allow allocation for (exception of system process see
  below)
- emer_mem is the maximum memory allowed for system process, this
  limit is > to max_mem
- swap_limit is the threshold at which point ttm will start to
  try to swap object because ttm is getting close the max_mem
  limit
- swap_dma32_limit is the threshold at which point ttm will start
  swap object to try to reduce the pressure on the dma32 zone. Note
  that we don't specificly target object to swap to it might very
  well free more memory from highmem rather than from dma32

Accounting is done through used_mem & used_dma32_mem, which sum give
the total amount of memory actually accounted by ttm.

Idea is that allocation will fail if (used_mem + used_dma32_mem) >
max_mem and if swapping fail to make enough room.

The used_dma32_mem can be updated as a later stage, allowing to
perform accounting test before allocating a whole batch of pages.

V2 Move accouting before page allocation instead of leaving that
to a later patch. Always account first against dma32 zone and
only as a post pass rebalance accouting to highmem if pages
allow it.

Signed-off-by: Jerome Glisse 
---
 drivers/gpu/drm/ttm/ttm_bo.c |9 +-
 drivers/gpu/drm/ttm/ttm_memory.c |  554 ++
 drivers/gpu/drm/ttm/ttm_object.c |   10 +-
 drivers/gpu/drm/ttm/ttm_tt.c |   14 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c|   30 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |   51 ++--
 include/drm/ttm/ttm_memory.h |   27 +-
 7 files changed, 263 insertions(+), 432 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4bde335..b3674ba 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1248,13 +1248,16 @@ int ttm_bo_create(struct ttm_bo_device *bdev,
 {
struct ttm_buffer_object *bo;
struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+   unsigned long available;
int ret;

size_t acc_size =
ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-   ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
-   if (unlikely(ret != 0))
-   return ret;
+   available = ttm_mem_global_alloc(mem_glob, acc_size, false);
+   if (available != acc_size) {
+   ttm_mem_global_free(mem_glob, available);
+   return -ENOMEM;
+   }

bo = kzalloc(sizeof(*bo), GFP_KERNEL);

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index e70ddd8..2aa08a7 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -35,21 +35,10 @@
 #include 
 #include 

-#define TTM_MEMORY_ALLOC_RETRIES 4
-
-struct ttm_mem_zone {
-   struct kobject kobj;
-   struct ttm_mem_global *glob;
-   const char *name;
-   uint64_t zone_mem;
-   uint64_t emer_mem;
-   uint64_t max_mem;
-   uint64_t swap_limit;
-   uint64_t used_mem;
-};
+#define TTM_MEMORY_RETRIES 4

 static struct attribute ttm_mem_sys = {
-   .name = "zone_memory",
+   .name = "memory",
.mode = S_IRUGO
 };
 static struct attribute ttm_mem_emer = {
@@ -60,144 +49,156 @@ static struct attribute ttm_mem_max = {
.name = "available_memory",
.mode = S_IRUGO | S_IWUSR
 };
+static struct attribute ttm_mem_dma32_max = {
+   .name = "available_dma32_memory",
+   .mode = S_IRUGO | S_IWUSR
+};
 static struct attribute ttm_mem_swap = {
.name = "swap_limit",
.mode = S_IRUGO | S_IWUSR
 };
+static struct attribute ttm_mem_dma32_swap = {
+   .name = "swap_dma32_limit",
+   .mode = S_IRUGO | S_IWUSR
+};
 static struct attribute ttm_mem_used = {
.name = "used_memory",
.mode = S_IRUGO
 };
+static struct attribute ttm_mem_dma32_used = {
+   .name = "used_dma32_memory",
+   .mode = S_IRUGO
+};

-static void ttm_mem_zone_kobj_release(struct kobject *kobj)
-{
-   struct ttm_mem_zone *zone =
-   container_of(kobj, struct ttm_mem_zone, kobj);
-
-   printk(KERN_INFO TTM_PFX
-  "Zone %7s: Used memory at exit: %llu kiB.\n",
-  zone->name, (unsigned long long) zone->used_mem >> 10);
-   kfree(zone);
-}
-
-static ssize_t ttm_mem_zone_show(struct kobject *kobj,
-struct attribute *attr,
-char *buffer)
+static ssize_t ttm_mem_global_show(struct kobject *kobj,
+  struct attribute *attr,
+  char *buffer)
 {
-   struct ttm_mem_zone *zone =
-  

[PATCH 2/2] drm: add an fb creation ioctl that takes a pixel format

2011-11-09 Thread Rob Clark
On Wed, Nov 9, 2011 at 7:25 AM, InKi Dae  wrote:
> Hello, all.
>
> I am trying to implement multi planer using your plane patch and I
> think it's good but I am still warried about that drm_mode_fb_cmd2
> structure has only one handle. I know this handle is sent to
> framebuffer module to create new framebuffer. and the framebuffer
> would cover entire a image. as you know, the image could be consisted
> of one more planes. so I think now drm_mode_fb_cmd2 structure doesn't
> support multi planer because it has only one handle. with update_plane
> callback, a buffer of the framebuffer would be set to a hardware
> overlay. how we could set two planes or three planes to the hardware
> overlay? but there might be my missing point so please give me any
> comments. in addition, have you been looked into gem flink and open
> functions for memory sharing between processes? gem object basically
> has one buffer so we can't modify it because of compatibility. so I
> think it's right way that gem object manages only one buffer. for such
> a reason, maybe drm_mode_fb_cmd2 structure should include one more
> handles and plane count. each handle has a gem object to one plane and
> plane count means how many planes are requested and when update_plane
> callback is called by setplane(), we could set them of the specific
> framebuffer to a hardware overlay.

The current plan is to add a 3rd ioctl, for adding multi-planar fb..
I guess it is a good thing that I'm not the only one who wants this
:-)

> another one, and also I have tried to implement the way sharing the
> memory between v4l2 based drivers and drm based drivers through
> application and this works fine. this feature had been introduced by
> v4l2 framework as user ptr. my way also is similar to it. the
> difference is that application could get new gem handle from specific
> gem framework of kernel side if user application requests user ptr
> import with the user space address(mmaped memory). the new gem handle
> means a gem object to the memory mapped to the user space address.
> this way makes different applications to be possible to share the
> memory between v4l2 based driver and drm based driver. and also this
> feature is considered for IOMMU so it would support non continuous
> memory also. I will introduce this feature soon.

btw, there was an RFC a little while back for "dmabuf" buffer sharing
mechanism..  the idea would be to export a (for example) GEM buffer to
a dmabuf handle which could be passed in to other devices, including
for example v4l2 (although without necessarily requiring a userspace
mapping)..

http://www.spinics.net/lists/dri-devel/msg15077.html

It sounds like you are looking for a similar thing..

BR,
-R

> Thank you,
> Inki Dae.
>
> 2011/11/9 Jesse Barnes :
>> To properly support the various plane formats supported by different
>> hardware, the kernel must know the pixel format of a framebuffer object.
>> So add a new ioctl taking a format argument corresponding to a fourcc
>> name from videodev2.h. ?Implement the fb creation hooks in terms of the
>> new mode_fb_cmd2 using helpers where the old bpp/depth values are
>> needed.
>>
>> Acked-by: Alan Cox 
>> Reviewed-by: Rob Clark 
>> Signed-off-by: Jesse Barnes 
>> ---
>> ?drivers/gpu/drm/drm_crtc.c ? ? ? ? ? ? ? ?| ?108 
>> +++-
>> ?drivers/gpu/drm/drm_crtc_helper.c ? ? ? ? | ? 50 -
>> ?drivers/gpu/drm/drm_drv.c ? ? ? ? ? ? ? ? | ? ?1 +
>> ?drivers/gpu/drm/i915/intel_display.c ? ? ?| ? 36 +-
>> ?drivers/gpu/drm/i915/intel_drv.h ? ? ? ? ?| ? ?2 +-
>> ?drivers/gpu/drm/i915/intel_fb.c ? ? ? ? ? | ? 11 ++--
>> ?drivers/gpu/drm/nouveau/nouveau_display.c | ? ?4 +-
>> ?drivers/gpu/drm/nouveau/nouveau_fb.h ? ? ?| ? ?2 +-
>> ?drivers/gpu/drm/nouveau/nouveau_fbcon.c ? | ? 13 ++--
>> ?drivers/gpu/drm/radeon/radeon_display.c ? | ? ?4 +-
>> ?drivers/gpu/drm/radeon/radeon_fb.c ? ? ? ?| ? 18 +++--
>> ?drivers/gpu/drm/radeon/radeon_mode.h ? ? ?| ? ?2 +-
>> ?drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ? ? ? | ? 22 --
>> ?drivers/gpu/drm/vmwgfx/vmwgfx_kms.h ? ? ? | ? ?1 +
>> ?drivers/staging/gma500/framebuffer.c ? ? ?| ? ?2 +-
>> ?include/drm/drm.h ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
>> ?include/drm/drm_crtc.h ? ? ? ? ? ? ? ? ? ?| ? ?7 ++-
>> ?include/drm/drm_crtc_helper.h ? ? ? ? ? ? | ? ?4 +-
>> ?include/drm/drm_mode.h ? ? ? ? ? ? ? ? ? ?| ? 28 +++-
>> ?include/linux/videodev2.h ? ? ? ? ? ? ? ? | ? ?1 +
>> ?20 files changed, 256 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>> index 804ef12..39cccb4 100644
>> --- a/drivers/gpu/drm/drm_crtc.c
>> +++ b/drivers/gpu/drm/drm_crtc.c
>> @@ -1910,6 +1910,42 @@ out:
>> ? ? ? ?return ret;
>> ?}
>>
>> +/* Original addfb only supported RGB formats, so figure out which one */
>> +uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
>> +{
>> + ? ? ? uint32_t fmt;
>> +
>> + ? ? ? switch (bpp) {
>> + ? ? ? case 8:
>> + ? ? ? ? ? ? ? fmt = 

[Bug 27314] displayport link training fails on certain panels (channel equalization fails)

2011-11-09 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=27314

--- Comment #57 from Rafael ?vila de Esp?ndola  
2011-11-08 17:43:24 PST ---
Created attachment 53309
  --> https://bugs.freedesktop.org/attachment.cgi?id=53309
xorg log with the ati driver in fedora16

I have just installed fedora 16 on an "imac11,1", and I still have the same
problem. I have attached the xorg log, let me know if there is anything else I
could do to help.

I checked that the patch pointed by Comment 55 is include in the linux 3.1
shipping with fedora.

I am going to try the current linus tree and let you know if that helps.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.


[PATCH 4/5] drm/i915: add destination color key support

2011-11-09 Thread Daniel Vetter
On Tue, Nov 08, 2011 at 05:36:11PM -0500, Alex Deucher wrote:
> On Tue, Nov 8, 2011 at 5:06 PM, Daniel Vetter  wrote:
> > On Mon, Nov 07, 2011 at 10:02:55AM -0800, Jesse Barnes wrote:
> >> Add new ioctls for getting and setting the current destination color
> >> key. ?This allows for simple overlay display control by matching a color
> >> key value in the primary plane before blending the overlay on top.
> >>
> >> Signed-off-by: Jesse Barnes 
> >
> > A few comments below and a snide-y one here: If the goal is simply to keep
> > the bubble intact, this is fine by me. If we want something that has the
> > chance to be useable by a generic driver I think we want a drm interface
> > for plane/crtc properties (you could wire up set_gamma on planes in the
> > same series ... ;-) Again, I don't really care ...
> 
> Even further off topic, the panel scaler support should ideally be a
> property of crtcs/planes rather than a connector property.  However,
> that would be a bit of pain to implement and keep backwards
> compatibility.

I think we could just internally route the output pannel-fitter prop to
the crtc one. After all if the hw has the fitter really on the crtc,
moving it also logically to the crtc won't make anything previously
possibel impossible ...
-Daniel
-- 
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48


Re: r600 hdmi sound issue

2011-11-09 Thread Rafał Miłecki
2011/11/9 Greg Dietsche g...@gregd.org:
 Hi,
 I have a ASUS M4A89GTD motherboard and when I play back music in Rhythmbox,
 there is no sound (hdmi connection). Also, the playback speed is in a sort
 of fast forward (for example, after a few seconds of real time, rhythmbox
 shows something like 30 seconds into the song). This seems to be a kernel
 regression. I know that it started with 3.0, is present in 3.1, and is not
 working in 3.2-rc1, so it is still a problem.

 I bisected and found my self here: fe6f0bd03d697835e76dd18d232ba476c65b8282.
 However due to some graphical issues, I'm not actually able to test that
 commit. I tried reverting that commit, but the problem wasn't fixed.

 I'd like to see this problem fixed and can compile and test patches as
 necessary. Please let me know if you need more information - I'm happy to
 provide it :)

fe6f0bd03d697835e76dd18d232ba476c65b8282 is not likely. I suspect you
just experience results of so-called-fix:

805c22168da76a65c978017d0fe0d59cd048e995

drm/radeon/kms: disable hdmi audio by default

I'm trying to get in contact with ppl affected by issues when enabling
audio. Hopefully we can fix audio support and enable it by default
again.

For now, please load radeon module with audio=1, or simply boot with
radeon.audio=1

-- 
Rafał
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH -fixes 0/3] vmwgfx fixes

2011-11-09 Thread Thomas Hellstrom
A couple of bugfixes for vmwgfx kms.

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/3] vmwgfx: Close screen object system

2011-11-09 Thread Thomas Hellstrom
From: Jakob Bornecrantz ja...@vmware.com

Signed-off-by: Jakob Bornecrantz ja...@vmware.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 03daefa..f3ab1fe 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1323,7 +1323,10 @@ int vmw_kms_close(struct vmw_private *dev_priv)
 * drm_encoder_cleanup which takes the lock we deadlock.
 */
drm_mode_config_cleanup(dev_priv-dev);
-   vmw_kms_close_legacy_display_system(dev_priv);
+   if (dev_priv-sou_priv)
+   vmw_kms_close_screen_object_display(dev_priv);
+   else
+   vmw_kms_close_legacy_display_system(dev_priv);
return 0;
 }
 
-- 
1.7.4.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/3] vmwgfx: Initialize clip rect loop correctly in surface dirty

2011-11-09 Thread Thomas Hellstrom
From: Jakob Bornecrantz ja...@vmware.com

Signed-off-by: Jakob Bornecrantz ja...@vmware.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index f3ab1fe..40c7e61 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -410,8 +410,9 @@ static int do_surface_dirty_sou(struct vmw_private 
*dev_priv,
top = clips-y1;
bottom = clips-y2;
 
-   clips_ptr = clips;
-   for (i = 1; i  num_clips; i++, clips_ptr += inc) {
+   /* skip the first clip rect */
+   for (i = 1, clips_ptr = clips + inc;
+i  num_clips; i++, clips_ptr += inc) {
left = min_t(int, left, (int)clips_ptr-x1);
right = max_t(int, right, (int)clips_ptr-x2);
top = min_t(int, top, (int)clips_ptr-y1);
-- 
1.7.4.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/3] vmwgfx: Only allow 64x64 cursors

2011-11-09 Thread Thomas Hellstrom
From: Jakob Bornecrantz ja...@vmware.com

Snooping code expects this to be the case.

Signed-off-by: Jakob Bornecrantz ja...@vmware.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 40c7e61..880e285 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct 
drm_file *file_priv,
struct vmw_dma_buffer *dmabuf = NULL;
int ret;
 
+   /* A lot of the code assumes this */
+   if (handle  (width != 64 || height != 64))
+   return -EINVAL;
+
if (handle) {
ret = vmw_user_surface_lookup_handle(dev_priv, tfile,
 handle, surface);
-- 
1.7.4.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/5] drm: add plane support

2011-11-09 Thread Joonyoung Shim
2011년 11월 9일 수요일에 Jesse Barnesjbar...@virtuousgeek.org님이 작성:
 Planes are a bit like half-CRTCs.  They have a location and fb, but
 don't drive outputs directly.  Add support for handling them to the core
 KMS code.

 Acked-by: Alan Cox a...@lxorguk.ukuu.org.uk
 Reviewed-by: Rob Clark rob.cl...@linaro.org
 Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch
 Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org

Reviewed-by: Joonyoung Shim jy0922.s...@samsung.com

Thanks.

 ---
  drivers/gpu/drm/drm_crtc.c |  257
+++-
  drivers/gpu/drm/drm_drv.c  |3 +
  include/drm/drm.h  |3 +
  include/drm/drm_crtc.h |   75 +-
  include/drm/drm_mode.h |   33 ++
  5 files changed, 368 insertions(+), 3 deletions(-)

 diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
 index fe738f0..804ef12 100644
 --- a/drivers/gpu/drm/drm_crtc.c
 +++ b/drivers/gpu/drm/drm_crtc.c
 @@ -321,6 +321,7 @@ void drm_framebuffer_cleanup(struct drm_framebuffer
*fb)
  {
struct drm_device *dev = fb-dev;
struct drm_crtc *crtc;
 +   struct drm_plane *plane;
struct drm_mode_set set;
int ret;

 @@ -337,6 +338,15 @@ void drm_framebuffer_cleanup(struct drm_framebuffer
*fb)
}
}

 +   list_for_each_entry(plane, dev-mode_config.plane_list, head) {
 +   if (plane-fb == fb) {
 +   /* should turn off the crtc */
 +   ret = plane-funcs-disable_plane(plane);
 +   if (ret)
 +   DRM_ERROR(failed to disable plane with
busy fb\n);
 +   }
 +   }
 +
drm_mode_object_put(dev, fb-base);
list_del(fb-head);
dev-mode_config.num_fb--;
 @@ -535,6 +545,50 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
  }
  EXPORT_SYMBOL(drm_encoder_cleanup);

 +int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
 +  unsigned long possible_crtcs,
 +  const struct drm_plane_funcs *funcs,
 +  uint32_t *formats, uint32_t format_count)
 +{
 +   mutex_lock(dev-mode_config.mutex);
 +
 +   plane-dev = dev;
 +   drm_mode_object_get(dev, plane-base, DRM_MODE_OBJECT_PLANE);
 +   plane-funcs = funcs;
 +   plane-format_types = kmalloc(sizeof(uint32_t) * format_count,
 + GFP_KERNEL);
 +   if (!plane-format_types) {
 +   DRM_DEBUG_KMS(out of memory when allocating plane\n);
 +   drm_mode_object_put(dev, plane-base);
 +   return -ENOMEM;
 +   }
 +
 +   memcpy(plane-format_types, formats, format_count);
 +   plane-format_count = format_count;
 +   plane-possible_crtcs = possible_crtcs;
 +
 +   list_add_tail(plane-head, dev-mode_config.plane_list);
 +   dev-mode_config.num_plane++;
 +
 +   mutex_unlock(dev-mode_config.mutex);
 +
 +   return 0;
 +}
 +EXPORT_SYMBOL(drm_plane_init);
 +
 +void drm_plane_cleanup(struct drm_plane *plane)
 +{
 +   struct drm_device *dev = plane-dev;
 +
 +   mutex_lock(dev-mode_config.mutex);
 +   kfree(plane-format_types);
 +   drm_mode_object_put(dev, plane-base);
 +   list_del(plane-head);
 +   dev-mode_config.num_plane--;
 +   mutex_unlock(dev-mode_config.mutex);
 +}
 +EXPORT_SYMBOL(drm_plane_cleanup);
 +
  /**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
 @@ -866,6 +920,7 @@ void drm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(dev-mode_config.encoder_list);
INIT_LIST_HEAD(dev-mode_config.property_list);
INIT_LIST_HEAD(dev-mode_config.property_blob_list);
 +   INIT_LIST_HEAD(dev-mode_config.plane_list);
idr_init(dev-mode_config.crtc_idr);

mutex_lock(dev-mode_config.mutex);
 @@ -942,6 +997,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
 +   struct drm_plane *plane, *plt;

list_for_each_entry_safe(encoder, enct,
dev-mode_config.encoder_list,
 head) {
 @@ -966,6 +1022,10 @@ void drm_mode_config_cleanup(struct drm_device *dev)
crtc-funcs-destroy(crtc);
}

 +   list_for_each_entry_safe(plane, plt, dev-mode_config.plane_list,
 +head) {
 +   plane-funcs-destroy(plane);
 +   }
  }
  EXPORT_SYMBOL(drm_mode_config_cleanup);

 @@ -1466,6 +1526,197 @@ out:
  }

  /**
 + * drm_mode_getplane_res - get plane info
 + * @dev: DRM device
 + * @data: ioctl data
 + * @file_priv: DRM file info
 + *
 + * Return an plane count and set of IDs.
 + */
 +int drm_mode_getplane_res(struct drm_device *dev, void *data,
 +   struct drm_file *file_priv)
 +{
 +   struct drm_mode_get_plane_res *plane_resp = data;
 +   struct 

Re: Linux 3.2-rc1

2011-11-09 Thread Wu Fengguang
On Wed, Nov 09, 2011 at 03:40:19PM +0800, Takashi Iwai wrote:
 At Tue, 8 Nov 2011 12:23:30 -0800,
 Linus Torvalds wrote:
  
  Hmm, I don't know what caused this to trigger, but I'm adding both the
  i915 people and the HDA people to the cc, and they can fight to the
  death about this in the HDMI Thunderdome.
 
 It must be the new addition of ELD-passing code.

Yes, it's my fault.

 Fengguang, can the drm or i915 driver check whether ELD is changed or
 not?  Writing ELD at each time even when unchanged confuses the audio
 side, as if the monitor is hotplugged.

It's sure possible to mask out the extra events.
I'll work out a patch tomorrow.

  Guys: One.. Two.. Three.. FIGHT!
 
 Round two!

Three to fight!

Thanks,
Fengguang

  On Tue, Nov 8, 2011 at 6:55 AM, Nick Bowler nbow...@elliptictech.com 
  wrote:
  
   Mode switches are very noisy on an Intel G45 in 3.2-rc1:
  
    HDMI hot plug event: Codec=3 Pin=3 Presence_Detect=1 ELD_Valid=1
    HDMI status: Codec=3 Pin=3 Presence_Detect=1 ELD_Valid=1
    HDMI: detected monitor W2253 at connection type HDMI
    HDMI: available speakers: FL/FR
    HDMI: supports coding type LPCM: channels = 2, rates = 32000 44100 
   48000, bits = 16 20 24
  
   These lines get printed every single switch; previously only a single
   line was printed once at boot (the HDMI status line).
  
   Cheers,
   --
   Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
  
  
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 2/2] drm: add an fb creation ioctl that takes a pixel format

2011-11-09 Thread InKi Dae
Hello, all.

I am trying to implement multi planer using your plane patch and I
think it's good but I am still warried about that drm_mode_fb_cmd2
structure has only one handle. I know this handle is sent to
framebuffer module to create new framebuffer. and the framebuffer
would cover entire a image. as you know, the image could be consisted
of one more planes. so I think now drm_mode_fb_cmd2 structure doesn't
support multi planer because it has only one handle. with update_plane
callback, a buffer of the framebuffer would be set to a hardware
overlay. how we could set two planes or three planes to the hardware
overlay? but there might be my missing point so please give me any
comments. in addition, have you been looked into gem flink and open
functions for memory sharing between processes? gem object basically
has one buffer so we can't modify it because of compatibility. so I
think it's right way that gem object manages only one buffer. for such
a reason, maybe drm_mode_fb_cmd2 structure should include one more
handles and plane count. each handle has a gem object to one plane and
plane count means how many planes are requested and when update_plane
callback is called by setplane(), we could set them of the specific
framebuffer to a hardware overlay.

another one, and also I have tried to implement the way sharing the
memory between v4l2 based drivers and drm based drivers through
application and this works fine. this feature had been introduced by
v4l2 framework as user ptr. my way also is similar to it. the
difference is that application could get new gem handle from specific
gem framework of kernel side if user application requests user ptr
import with the user space address(mmaped memory). the new gem handle
means a gem object to the memory mapped to the user space address.
this way makes different applications to be possible to share the
memory between v4l2 based driver and drm based driver. and also this
feature is considered for IOMMU so it would support non continuous
memory also. I will introduce this feature soon.

Thank you,
Inki Dae.

2011/11/9 Jesse Barnes jbar...@virtuousgeek.org:
 To properly support the various plane formats supported by different
 hardware, the kernel must know the pixel format of a framebuffer object.
 So add a new ioctl taking a format argument corresponding to a fourcc
 name from videodev2.h.  Implement the fb creation hooks in terms of the
 new mode_fb_cmd2 using helpers where the old bpp/depth values are
 needed.

 Acked-by: Alan Cox a...@lxorguk.ukuu.org.uk
 Reviewed-by: Rob Clark rob.cl...@linaro.org
 Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org
 ---
  drivers/gpu/drm/drm_crtc.c                |  108 +++-
  drivers/gpu/drm/drm_crtc_helper.c         |   50 -
  drivers/gpu/drm/drm_drv.c                 |    1 +
  drivers/gpu/drm/i915/intel_display.c      |   36 +-
  drivers/gpu/drm/i915/intel_drv.h          |    2 +-
  drivers/gpu/drm/i915/intel_fb.c           |   11 ++--
  drivers/gpu/drm/nouveau/nouveau_display.c |    4 +-
  drivers/gpu/drm/nouveau/nouveau_fb.h      |    2 +-
  drivers/gpu/drm/nouveau/nouveau_fbcon.c   |   13 ++--
  drivers/gpu/drm/radeon/radeon_display.c   |    4 +-
  drivers/gpu/drm/radeon/radeon_fb.c        |   18 +++--
  drivers/gpu/drm/radeon/radeon_mode.h      |    2 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c       |   22 --
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.h       |    1 +
  drivers/staging/gma500/framebuffer.c      |    2 +-
  include/drm/drm.h                         |    1 +
  include/drm/drm_crtc.h                    |    7 ++-
  include/drm/drm_crtc_helper.h             |    4 +-
  include/drm/drm_mode.h                    |   28 +++-
  include/linux/videodev2.h                 |    1 +
  20 files changed, 256 insertions(+), 61 deletions(-)

 diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
 index 804ef12..39cccb4 100644
 --- a/drivers/gpu/drm/drm_crtc.c
 +++ b/drivers/gpu/drm/drm_crtc.c
 @@ -1910,6 +1910,42 @@ out:
        return ret;
  }

 +/* Original addfb only supported RGB formats, so figure out which one */
 +uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
 +{
 +       uint32_t fmt;
 +
 +       switch (bpp) {
 +       case 8:
 +               fmt = V4L2_PIX_FMT_RGB332;
 +               break;
 +       case 16:
 +               if (depth == 15)
 +                       fmt = V4L2_PIX_FMT_RGB555;
 +               else
 +                       fmt = V4L2_PIX_FMT_RGB565;
 +               break;
 +       case 24:
 +               fmt = V4L2_PIX_FMT_RGB24;
 +               break;
 +       case 32:
 +               if (depth == 24)
 +                       fmt = V4L2_PIX_FMT_RGB24;
 +               else if (depth == 30)
 +                       fmt = V4L2_PIX_FMT_INTC_RGB30;
 +               else
 +                       fmt = V4L2_PIX_FMT_RGB32;
 +               break;
 +       default:
 +               DRM_ERROR(bad bpp, assuming RGB24 

Re: [PATCH 2/2] drm: add an fb creation ioctl that takes a pixel format

2011-11-09 Thread Rob Clark
On Wed, Nov 9, 2011 at 7:25 AM, InKi Dae daei...@gmail.com wrote:
 Hello, all.

 I am trying to implement multi planer using your plane patch and I
 think it's good but I am still warried about that drm_mode_fb_cmd2
 structure has only one handle. I know this handle is sent to
 framebuffer module to create new framebuffer. and the framebuffer
 would cover entire a image. as you know, the image could be consisted
 of one more planes. so I think now drm_mode_fb_cmd2 structure doesn't
 support multi planer because it has only one handle. with update_plane
 callback, a buffer of the framebuffer would be set to a hardware
 overlay. how we could set two planes or three planes to the hardware
 overlay? but there might be my missing point so please give me any
 comments. in addition, have you been looked into gem flink and open
 functions for memory sharing between processes? gem object basically
 has one buffer so we can't modify it because of compatibility. so I
 think it's right way that gem object manages only one buffer. for such
 a reason, maybe drm_mode_fb_cmd2 structure should include one more
 handles and plane count. each handle has a gem object to one plane and
 plane count means how many planes are requested and when update_plane
 callback is called by setplane(), we could set them of the specific
 framebuffer to a hardware overlay.

The current plan is to add a 3rd ioctl, for adding multi-planar fb..
I guess it is a good thing that I'm not the only one who wants this
:-)

 another one, and also I have tried to implement the way sharing the
 memory between v4l2 based drivers and drm based drivers through
 application and this works fine. this feature had been introduced by
 v4l2 framework as user ptr. my way also is similar to it. the
 difference is that application could get new gem handle from specific
 gem framework of kernel side if user application requests user ptr
 import with the user space address(mmaped memory). the new gem handle
 means a gem object to the memory mapped to the user space address.
 this way makes different applications to be possible to share the
 memory between v4l2 based driver and drm based driver. and also this
 feature is considered for IOMMU so it would support non continuous
 memory also. I will introduce this feature soon.

btw, there was an RFC a little while back for dmabuf buffer sharing
mechanism..  the idea would be to export a (for example) GEM buffer to
a dmabuf handle which could be passed in to other devices, including
for example v4l2 (although without necessarily requiring a userspace
mapping)..

http://www.spinics.net/lists/dri-devel/msg15077.html

It sounds like you are looking for a similar thing..

BR,
-R

 Thank you,
 Inki Dae.

 2011/11/9 Jesse Barnes jbar...@virtuousgeek.org:
 To properly support the various plane formats supported by different
 hardware, the kernel must know the pixel format of a framebuffer object.
 So add a new ioctl taking a format argument corresponding to a fourcc
 name from videodev2.h.  Implement the fb creation hooks in terms of the
 new mode_fb_cmd2 using helpers where the old bpp/depth values are
 needed.

 Acked-by: Alan Cox a...@lxorguk.ukuu.org.uk
 Reviewed-by: Rob Clark rob.cl...@linaro.org
 Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org
 ---
  drivers/gpu/drm/drm_crtc.c                |  108 
 +++-
  drivers/gpu/drm/drm_crtc_helper.c         |   50 -
  drivers/gpu/drm/drm_drv.c                 |    1 +
  drivers/gpu/drm/i915/intel_display.c      |   36 +-
  drivers/gpu/drm/i915/intel_drv.h          |    2 +-
  drivers/gpu/drm/i915/intel_fb.c           |   11 ++--
  drivers/gpu/drm/nouveau/nouveau_display.c |    4 +-
  drivers/gpu/drm/nouveau/nouveau_fb.h      |    2 +-
  drivers/gpu/drm/nouveau/nouveau_fbcon.c   |   13 ++--
  drivers/gpu/drm/radeon/radeon_display.c   |    4 +-
  drivers/gpu/drm/radeon/radeon_fb.c        |   18 +++--
  drivers/gpu/drm/radeon/radeon_mode.h      |    2 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c       |   22 --
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.h       |    1 +
  drivers/staging/gma500/framebuffer.c      |    2 +-
  include/drm/drm.h                         |    1 +
  include/drm/drm_crtc.h                    |    7 ++-
  include/drm/drm_crtc_helper.h             |    4 +-
  include/drm/drm_mode.h                    |   28 +++-
  include/linux/videodev2.h                 |    1 +
  20 files changed, 256 insertions(+), 61 deletions(-)

 diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
 index 804ef12..39cccb4 100644
 --- a/drivers/gpu/drm/drm_crtc.c
 +++ b/drivers/gpu/drm/drm_crtc.c
 @@ -1910,6 +1910,42 @@ out:
        return ret;
  }

 +/* Original addfb only supported RGB formats, so figure out which one */
 +uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)
 +{
 +       uint32_t fmt;
 +
 +       switch (bpp) {
 +       case 8:
 +               fmt = V4L2_PIX_FMT_RGB332;
 +               break;
 

[Bug 27314] displayport link training fails on certain panels (channel equalization fails)

2011-11-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=27314

--- Comment #59 from Alex Deucher ag...@yahoo.com 2011-11-09 06:44:37 PST ---
(In reply to comment #57)
 Created attachment 53309 [details]
 xorg log with the ati driver in fedora16
 
 I have just installed fedora 16 on an imac11,1, and I still have the same
 problem. I have attached the xorg log, let me know if there is anything else I
 could do to help.
 
 I checked that the patch pointed by Comment 55 is include in the linux 3.1
 shipping with fedora.
 
 I am going to try the current linus tree and let you know if that helps.

Why are you using UMS?  All of the relevant fixes have been in KMS.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 28426] hardware cursor corruption with radeon+kms

2011-11-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=28426

--- Comment #11 from Jürg Billeter j...@bitron.ch 2011-11-09 08:51:09 PST ---
My Linux 3.1 system has been running for over 6 days now without issues. Seems
like it may finally be fixed for good :) Thanks!

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Bug 42678] Dual Screen Monitor Gnome-shell 3 hard lock ups - ATI open source Radeon

2011-11-09 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=42678

--- Comment #13 from Filip wat...@gmail.com 2011-11-09 10:56:34 PST ---
So, after I ran the following on my system:

sudo sh /usr/share/ati/fglrx-uninstall.sh
sudo apt-get remove --purge fglrx fglrx_* fglrx-amdcccle* fglrx-dev*

sudo apt-get remove --purge xserver-xorg-video-ati xserver-xorg-video-radeon
sudo apt-get install xserver-xorg-video-ati
sudo apt-get install --reinstall libgl1-mesa-glx:amd64 libgl1-mesa-glx:i386
libgl1-mesa-dri xserver-xorg-core
sudo mv /etc/X11/xorg.conf /etc/X11/xorg.conf.backup
sudo rm -rf /etc/ati

I still get the occasional hard freeze (the frequency was reduced to 2 - 4
times a day, which is a lot better than it was before). 

Is it possible that the old fglrx driver touched some other libraries which I
need to install? if yes, which one would those be?

As a next step, I will try the option per Xorg config

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
--- You are receiving this mail because: ---
You are the assignee for the bug.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


ttm: merge ttm_backend ttm_tt, introduce ttm dma allocator

2011-11-09 Thread j . glisse
So i did an overhaul of ttm_memory, i believe the simplification i did
make sense. See patch 5 for a longer explanation.

Thomas with the ttm_memory change the allocation of pages won't happen
if the accounting report that we are going over the limit and bo shrinker
failed to free any memory to make room.

The handling of dma32 zone is done as post pass of ttm memory accounting.

Regarding the pagefault comment i removed, it doesn't make sense anymore
because now we populate the whole page table in one shot. So there is
no more prefaulting few pages but a full prefaulting. Thought i can
add a comment stating that if you like.

For the ttm_tt_dma struct to hold page allocator specific informations
i think it can be done as an followup patch but if you prefer to have
that in this patchset let me know i will respin with such changes.

I am in the process of retesting this whole serie and especialy the
while memory accounting.

Cheers,
Jerome
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 01/13] drm/ttm: remove userspace backed ttm object support

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

This was never use in none of the driver, properly using userspace
page for bo would need more code (vma interaction mostly). Removing
this dead code in preparation of ttm_tt  backend merge.

Signed-off-by: Jerome Glisse jgli...@redhat.com
Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/ttm/ttm_bo.c|   22 
 drivers/gpu/drm/ttm/ttm_tt.c|  105 +--
 include/drm/ttm/ttm_bo_api.h|5 --
 include/drm/ttm/ttm_bo_driver.h |   24 -
 4 files changed, 1 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 617b646..4bde335 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -342,22 +342,6 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, 
bool zero_alloc)
if (unlikely(bo-ttm == NULL))
ret = -ENOMEM;
break;
-   case ttm_bo_type_user:
-   bo-ttm = ttm_tt_create(bdev, bo-num_pages  PAGE_SHIFT,
-   page_flags | TTM_PAGE_FLAG_USER,
-   glob-dummy_read_page);
-   if (unlikely(bo-ttm == NULL)) {
-   ret = -ENOMEM;
-   break;
-   }
-
-   ret = ttm_tt_set_user(bo-ttm, current,
- bo-buffer_start, bo-num_pages);
-   if (unlikely(ret != 0)) {
-   ttm_tt_destroy(bo-ttm);
-   bo-ttm = NULL;
-   }
-   break;
default:
printk(KERN_ERR TTM_PFX Illegal buffer object type\n);
ret = -EINVAL;
@@ -907,16 +891,12 @@ static uint32_t ttm_bo_select_caching(struct 
ttm_mem_type_manager *man,
 }
 
 static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,
-bool disallow_fixed,
 uint32_t mem_type,
 uint32_t proposed_placement,
 uint32_t *masked_placement)
 {
uint32_t cur_flags = ttm_bo_type_flags(mem_type);
 
-   if ((man-flags  TTM_MEMTYPE_FLAG_FIXED)  disallow_fixed)
-   return false;
-
if ((cur_flags  proposed_placement  TTM_PL_MASK_MEM) == 0)
return false;
 
@@ -961,7 +941,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
man = bdev-man[mem_type];
 
type_ok = ttm_bo_mt_compatible(man,
-   bo-type == ttm_bo_type_user,
mem_type,
placement-placement[i],
cur_flags);
@@ -1009,7 +988,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
if (!man-has_type)
continue;
if (!ttm_bo_mt_compatible(man,
-   bo-type == ttm_bo_type_user,
mem_type,
placement-busy_placement[i],
cur_flags))
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 58c271e..82a1161 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -62,43 +62,6 @@ static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
ttm-dma_address = NULL;
 }
 
-static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
-{
-   int write;
-   int dirty;
-   struct page *page;
-   int i;
-   struct ttm_backend *be = ttm-be;
-
-   BUG_ON(!(ttm-page_flags  TTM_PAGE_FLAG_USER));
-   write = ((ttm-page_flags  TTM_PAGE_FLAG_WRITE) != 0);
-   dirty = ((ttm-page_flags  TTM_PAGE_FLAG_USER_DIRTY) != 0);
-
-   if (be)
-   be-func-clear(be);
-
-   for (i = 0; i  ttm-num_pages; ++i) {
-   page = ttm-pages[i];
-   if (page == NULL)
-   continue;
-
-   if (page == ttm-dummy_read_page) {
-   BUG_ON(write);
-   continue;
-   }
-
-   if (write  dirty  !PageReserved(page))
-   set_page_dirty_lock(page);
-
-   ttm-pages[i] = NULL;
-   ttm_mem_global_free(ttm-glob-mem_glob, PAGE_SIZE);
-   put_page(page);
-   }
-   ttm-state = tt_unpopulated;
-   ttm-first_himem_page = ttm-num_pages;
-   ttm-last_lomem_page = -1;
-}
-
 static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
 {
struct page *p;
@@ -325,10 +288,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
}
 
if (likely(ttm-pages != NULL)) {
-   if 

[PATCH 02/13] drm/ttm: remove split btw highmen and lowmem page

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

Split btw highmem and lowmem page was rendered useless by the
pool code. Remove it. Note further cleanup would change the
ttm page allocation helper to actualy take an array instead
of relying on list this could drasticly reduce the number of
function call in the common case of allocation whole buffer.

Signed-off-by: Jerome Glisse jgli...@redhat.com
Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/ttm/ttm_tt.c|   11 ++-
 include/drm/ttm/ttm_bo_driver.h |7 ---
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 82a1161..8b7a6d0 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -69,7 +69,7 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int 
index)
struct ttm_mem_global *mem_glob = ttm-glob-mem_glob;
int ret;
 
-   while (NULL == (p = ttm-pages[index])) {
+   if (NULL == (p = ttm-pages[index])) {
 
INIT_LIST_HEAD(h);
 
@@ -85,10 +85,7 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, 
int index)
if (unlikely(ret != 0))
goto out_err;
 
-   if (PageHighMem(p))
-   ttm-pages[--ttm-first_himem_page] = p;
-   else
-   ttm-pages[++ttm-last_lomem_page] = p;
+   ttm-pages[index] = p;
}
return p;
 out_err:
@@ -270,8 +267,6 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
ttm_put_pages(h, count, ttm-page_flags, ttm-caching_state,
  ttm-dma_address);
ttm-state = tt_unpopulated;
-   ttm-first_himem_page = ttm-num_pages;
-   ttm-last_lomem_page = -1;
 }
 
 void ttm_tt_destroy(struct ttm_tt *ttm)
@@ -315,8 +310,6 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, 
unsigned long size,
 
ttm-glob = bdev-glob;
ttm-num_pages = (size + PAGE_SIZE - 1)  PAGE_SHIFT;
-   ttm-first_himem_page = ttm-num_pages;
-   ttm-last_lomem_page = -1;
ttm-caching_state = tt_cached;
ttm-page_flags = page_flags;
 
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 37527d6..9da182b 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -136,11 +136,6 @@ enum ttm_caching_state {
  * @dummy_read_page: Page to map where the ttm_tt page array contains a NULL
  * pointer.
  * @pages: Array of pages backing the data.
- * @first_himem_page: Himem pages are put last in the page array, which
- * enables us to run caching attribute changes on only the first part
- * of the page array containing lomem pages. This is the index of the
- * first himem page.
- * @last_lomem_page: Index of the last lomem page in the page array.
  * @num_pages: Number of pages in the page array.
  * @bdev: Pointer to the current struct ttm_bo_device.
  * @be: Pointer to the ttm backend.
@@ -157,8 +152,6 @@ enum ttm_caching_state {
 struct ttm_tt {
struct page *dummy_read_page;
struct page **pages;
-   long first_himem_page;
-   long last_lomem_page;
uint32_t page_flags;
unsigned long num_pages;
struct ttm_bo_global *glob;
-- 
1.7.7.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 04/13] drm/ttm: use ttm put pages function to properly restore cache attribute

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

On failure we need to make sure the page we free has wb cache
attribute. Do this pas call the proper ttm page helper function.

Signed-off-by: Jerome Glisse jgli...@redhat.com
Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/ttm/ttm_tt.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 8b7a6d0..3fb4c6d 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -89,7 +89,10 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, 
int index)
}
return p;
 out_err:
-   put_page(p);
+   INIT_LIST_HEAD(h);
+   list_add(p-lru, h);
+   ttm_put_pages(h, 1, ttm-page_flags,
+ ttm-caching_state, ttm-dma_address[index]);
return NULL;
 }
 
-- 
1.7.7.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 05/13] drm/ttm: overhaul memory accounting

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

This is an overhaul of the ttm memory accounting. This tries to keep
the same global behavior while removing the whole zone concept. It
keeps a distrinction for dma32 so that we make sure that ttm don't
starve the dma32 zone.

There is 3 threshold for memory allocation :
- max_mem is the maximum memory the whole ttm infrastructure is
  going to allow allocation for (exception of system process see
  below)
- emer_mem is the maximum memory allowed for system process, this
  limit is  to max_mem
- swap_limit is the threshold at which point ttm will start to
  try to swap object because ttm is getting close the max_mem
  limit
- swap_dma32_limit is the threshold at which point ttm will start
  swap object to try to reduce the pressure on the dma32 zone. Note
  that we don't specificly target object to swap to it might very
  well free more memory from highmem rather than from dma32

Accounting is done through used_mem  used_dma32_mem, which sum give
the total amount of memory actually accounted by ttm.

Idea is that allocation will fail if (used_mem + used_dma32_mem) 
max_mem and if swapping fail to make enough room.

The used_dma32_mem can be updated as a later stage, allowing to
perform accounting test before allocating a whole batch of pages.

Signed-off-by: Jerome Glisse jgli...@redhat.com
---
 drivers/gpu/drm/ttm/ttm_bo.c |2 +-
 drivers/gpu/drm/ttm/ttm_memory.c |  517 +-
 drivers/gpu/drm/ttm/ttm_object.c |3 +-
 drivers/gpu/drm/ttm/ttm_tt.c |2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c|8 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c |8 +-
 include/drm/ttm/ttm_memory.h |   23 +-
 7 files changed, 168 insertions(+), 395 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4bde335..92712798 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1252,7 +1252,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev,
 
size_t acc_size =
ttm_bo_size(bdev-glob, (size + PAGE_SIZE - 1)  PAGE_SHIFT);
-   ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
+   ret = ttm_mem_global_alloc(mem_glob, acc_size, false);
if (unlikely(ret != 0))
return ret;
 
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index e70ddd8..b550baf 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -35,21 +35,10 @@
 #include linux/module.h
 #include linux/slab.h
 
-#define TTM_MEMORY_ALLOC_RETRIES 4
-
-struct ttm_mem_zone {
-   struct kobject kobj;
-   struct ttm_mem_global *glob;
-   const char *name;
-   uint64_t zone_mem;
-   uint64_t emer_mem;
-   uint64_t max_mem;
-   uint64_t swap_limit;
-   uint64_t used_mem;
-};
+#define TTM_MEMORY_RETRIES 4
 
 static struct attribute ttm_mem_sys = {
-   .name = zone_memory,
+   .name = memory,
.mode = S_IRUGO
 };
 static struct attribute ttm_mem_emer = {
@@ -64,140 +53,141 @@ static struct attribute ttm_mem_swap = {
.name = swap_limit,
.mode = S_IRUGO | S_IWUSR
 };
+static struct attribute ttm_mem_dma32_swap = {
+   .name = swap_dma32_limit,
+   .mode = S_IRUGO | S_IWUSR
+};
 static struct attribute ttm_mem_used = {
.name = used_memory,
.mode = S_IRUGO
 };
+static struct attribute ttm_mem_dma32_used = {
+   .name = used_dma32_memory,
+   .mode = S_IRUGO
+};
 
-static void ttm_mem_zone_kobj_release(struct kobject *kobj)
-{
-   struct ttm_mem_zone *zone =
-   container_of(kobj, struct ttm_mem_zone, kobj);
-
-   printk(KERN_INFO TTM_PFX
-  Zone %7s: Used memory at exit: %llu kiB.\n,
-  zone-name, (unsigned long long) zone-used_mem  10);
-   kfree(zone);
-}
-
-static ssize_t ttm_mem_zone_show(struct kobject *kobj,
-struct attribute *attr,
-char *buffer)
+static ssize_t ttm_mem_global_show(struct kobject *kobj,
+  struct attribute *attr,
+  char *buffer)
 {
-   struct ttm_mem_zone *zone =
-   container_of(kobj, struct ttm_mem_zone, kobj);
-   uint64_t val = 0;
+   struct ttm_mem_global *glob =
+   container_of(kobj, struct ttm_mem_global, kobj);
+   unsigned long val = 0;
 
-   spin_lock(zone-glob-lock);
+   spin_lock(glob-lock);
if (attr == ttm_mem_sys)
-   val = zone-zone_mem;
+   val = glob-mem;
else if (attr == ttm_mem_emer)
-   val = zone-emer_mem;
+   val = glob-emer_mem;
else if (attr == ttm_mem_max)
-   val = zone-max_mem;
+   val = glob-max_mem;
else if (attr == ttm_mem_swap)
-   val = zone-swap_limit;
+   val = glob-swap_limit;
   

[PATCH 06/13] drm/ttm: convert page allocation to use page ptr array instead of list V4

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

Use the ttm_tt page ptr array for page allocation, move the list to
array unwinding into the page allocation functions.

V2 split the fix to use ttm put page as a separate fix
properly fill pages array when TTM_PAGE_FLAG_ZERO_ALLOC is not
set
V3 Added back page_count()==1 check when freeing page
V4 Rebase on top of memory accounting overhaul

Signed-off-by: Jerome Glisse jgli...@redhat.com
---
 drivers/gpu/drm/ttm/ttm_memory.c |   47 +++--
 drivers/gpu/drm/ttm/ttm_page_alloc.c |   90 --
 drivers/gpu/drm/ttm/ttm_tt.c |   68 --
 include/drm/ttm/ttm_memory.h |   13 +++--
 include/drm/ttm/ttm_page_alloc.h |   17 +++---
 5 files changed, 120 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index b550baf..98f6899 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -326,32 +326,45 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob,
 }
 EXPORT_SYMBOL(ttm_mem_global_alloc);
 
-int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
- struct page *page,
- bool no_wait)
+int ttm_mem_global_alloc_pages(struct ttm_mem_global *glob,
+  unsigned npages,
+  bool no_wait)
 {
-
-   if (ttm_mem_global_alloc(glob, PAGE_SIZE, no_wait))
+   if (ttm_mem_global_alloc(glob, PAGE_SIZE * npages, no_wait))
return -ENOMEM;
+   ttm_check_swapping(glob);
+   return 0;
+}
+
+void ttm_mem_global_account_pages(struct ttm_mem_global *glob,
+ struct page **pages,
+ unsigned npages)
+{
+   unsigned i;
 
/* check if page is dma32 */
-   if (page_to_pfn(page)  0x0010UL) {
-   spin_lock(glob-lock);
-   glob-used_mem -= PAGE_SIZE;
-   glob-used_dma32_mem += PAGE_SIZE;
-   spin_unlock(glob-lock);
+   spin_lock(glob-lock);
+   for (i = 0; i  npages; i++) {
+   if (page_to_pfn(pages[i])  0x0010UL) {
+   glob-used_mem -= PAGE_SIZE;
+   glob-used_dma32_mem += PAGE_SIZE;
+   }
}
-   ttm_check_swapping(glob);
-   return 0;
+   spin_unlock(glob-lock);
 }
 
-void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page)
+void ttm_mem_global_free_pages(struct ttm_mem_global *glob,
+  struct page **pages, unsigned npages)
 {
+   unsigned i;
+
spin_lock(glob-lock);
-   if (page_to_pfn(page)  0x0010UL) {
-   glob-used_dma32_mem -= PAGE_SIZE;
-   } else {
-   glob-used_mem -= PAGE_SIZE;
+   for (i = 0; i  npages; i++) {
+   if (page_to_pfn(pages[i])  0x0010UL) {
+   glob-used_dma32_mem -= PAGE_SIZE;
+   } else {
+   glob-used_mem -= PAGE_SIZE;
+   }
}
spin_unlock(glob-lock);
 }
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c 
b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 727e93d..c4f18b9 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -619,8 +619,10 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool 
*pool,
  * @return count of pages still required to fulfill the request.
  */
 static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool,
-   struct list_head *pages, int ttm_flags,
-   enum ttm_caching_state cstate, unsigned count)
+   struct list_head *pages,
+   int ttm_flags,
+   enum ttm_caching_state cstate,
+   unsigned count)
 {
unsigned long irq_flags;
struct list_head *p;
@@ -664,13 +666,14 @@ out:
  * On success pages list will hold count number of correctly
  * cached pages.
  */
-int ttm_get_pages(struct list_head *pages, int flags,
- enum ttm_caching_state cstate, unsigned count,
- dma_addr_t *dma_address)
+int ttm_get_pages(struct page **pages, unsigned npages, int flags,
+ enum ttm_caching_state cstate, dma_addr_t *dma_address)
 {
struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
struct page *p = NULL;
+   struct list_head plist;
gfp_t gfp_flags = GFP_USER;
+   unsigned count = 0;
int r;
 
/* set zero flag for page allocation if required */
@@ -684,94 +687,107 @@ int ttm_get_pages(struct list_head *pages, int flags,
else
gfp_flags |= GFP_HIGHUSER;
 
-   for (r = 0; r  count; ++r) {
-   p = alloc_page(gfp_flags);
-   if 

[PATCH 07/13] drm/ttm: test for dma_address array allocation failure

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

Signed-off-by: Jerome Glisse jgli...@redhat.com
Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Reviewed-by: Thomas Hellstrom thellst...@vmware.com
---
 drivers/gpu/drm/ttm/ttm_tt.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 303bbba..2dab08b 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -293,7 +293,7 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, 
unsigned long size,
ttm-dummy_read_page = dummy_read_page;
 
ttm_tt_alloc_page_directory(ttm);
-   if (!ttm-pages) {
+   if (!ttm-pages || !ttm-dma_address) {
ttm_tt_destroy(ttm);
printk(KERN_ERR TTM_PFX Failed allocating page table\n);
return NULL;
-- 
1.7.7.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 08/13] drm/ttm: merge ttm_backend and ttm_tt V2

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

ttm_backend will exist only and only with a ttm_tt, and ttm_tt
will be of interesting use only when bind to a backend. Thus to
avoid code  data duplication btw the two merge them.

V2 Rebase on top of memory accountign overhaul

Signed-off-by: Jerome Glisse jgli...@redhat.com
Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 drivers/gpu/drm/nouveau/nouveau_bo.c|   14 ++-
 drivers/gpu/drm/nouveau/nouveau_drv.h   |5 +-
 drivers/gpu/drm/nouveau/nouveau_sgdma.c |  188 --
 drivers/gpu/drm/radeon/radeon_ttm.c |  222 ---
 drivers/gpu/drm/ttm/ttm_agp_backend.c   |   88 +
 drivers/gpu/drm/ttm/ttm_bo.c|9 +-
 drivers/gpu/drm/ttm/ttm_tt.c|   60 ++---
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c  |   66 +++--
 include/drm/ttm/ttm_bo_driver.h |  104 ++-
 9 files changed, 295 insertions(+), 461 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7226f41..b060fa4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -343,8 +343,10 @@ nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, 
u32 val)
*mem = val;
 }
 
-static struct ttm_backend *
-nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
+static struct ttm_tt *
+nouveau_ttm_tt_create(struct ttm_bo_device *bdev,
+ unsigned long size, uint32_t page_flags,
+ struct page *dummy_read_page)
 {
struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev);
struct drm_device *dev = dev_priv-dev;
@@ -352,11 +354,13 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device 
*bdev)
switch (dev_priv-gart_info.type) {
 #if __OS_HAS_AGP
case NOUVEAU_GART_AGP:
-   return ttm_agp_backend_init(bdev, dev-agp-bridge);
+   return ttm_agp_tt_create(bdev, dev-agp-bridge,
+size, page_flags, dummy_read_page);
 #endif
case NOUVEAU_GART_PDMA:
case NOUVEAU_GART_HW:
-   return nouveau_sgdma_init_ttm(dev);
+   return nouveau_sgdma_create_ttm(bdev, size, page_flags,
+   dummy_read_page);
default:
NV_ERROR(dev, Unknown GART type %d\n,
 dev_priv-gart_info.type);
@@ -1045,7 +1049,7 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
 }
 
 struct ttm_bo_driver nouveau_bo_driver = {
-   .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry,
+   .ttm_tt_create = nouveau_ttm_tt_create,
.invalidate_caches = nouveau_bo_invalidate_caches,
.init_mem_type = nouveau_bo_init_mem_type,
.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 29837da..0c53e39 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1000,7 +1000,10 @@ extern int nouveau_sgdma_init(struct drm_device *);
 extern void nouveau_sgdma_takedown(struct drm_device *);
 extern uint32_t nouveau_sgdma_get_physical(struct drm_device *,
   uint32_t offset);
-extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+extern struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev,
+  unsigned long size,
+  uint32_t page_flags,
+  struct page *dummy_read_page);
 
 /* nouveau_debugfs.c */
 #if defined(CONFIG_DRM_NOUVEAU_DEBUG)
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index b75258a..bc2ab90 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -8,44 +8,23 @@
 #define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)
 
 struct nouveau_sgdma_be {
-   struct ttm_backend backend;
+   struct ttm_tt ttm;
struct drm_device *dev;
-
-   dma_addr_t *pages;
-   unsigned nr_pages;
-   bool unmap_pages;
-
u64 offset;
-   bool bound;
 };
 
 static int
-nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
-  struct page **pages, struct page *dummy_read_page,
-  dma_addr_t *dma_addrs)
+nouveau_sgdma_dma_map(struct ttm_tt *ttm)
 {
-   struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be;
+   struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
struct drm_device *dev = nvbe-dev;
int i;
 
-   NV_DEBUG(nvbe-dev, num_pages = %ld\n, num_pages);
-
-   nvbe-pages = dma_addrs;
-   nvbe-nr_pages = num_pages;
-   nvbe-unmap_pages = true;
-
-   /* this code path isn't 

[PATCH 09/13] drm/ttm: introduce callback for ttm_tt populate unpopulate V2

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

Move the page allocation and freeing to driver callback and
provide ttm code helper function for those.

Most intrusive change, is the fact that we now only fully
populate an object this simplify some of code designed around
the page fault design.

V2 Rebase on top of memory accounting overhaul

Signed-off-by: Jerome Glisse jgli...@redhat.com
Reviewed-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 drivers/gpu/drm/nouveau/nouveau_bo.c   |3 +
 drivers/gpu/drm/radeon/radeon_ttm.c|2 +
 drivers/gpu/drm/ttm/ttm_bo_util.c  |   31 ++-
 drivers/gpu/drm/ttm/ttm_bo_vm.c|   13 +++--
 drivers/gpu/drm/ttm/ttm_page_alloc.c   |   45 +
 drivers/gpu/drm/ttm/ttm_tt.c   |   86 ++--
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c |3 +
 include/drm/ttm/ttm_bo_driver.h|   41 +---
 include/drm/ttm/ttm_page_alloc.h   |   18 +++
 9 files changed, 123 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index b060fa4..7e5ca3f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -28,6 +28,7 @@
  */
 
 #include drmP.h
+#include ttm/ttm_page_alloc.h
 
 #include nouveau_drm.h
 #include nouveau_drv.h
@@ -1050,6 +1051,8 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
 
 struct ttm_bo_driver nouveau_bo_driver = {
.ttm_tt_create = nouveau_ttm_tt_create,
+   .ttm_tt_populate = ttm_page_alloc_ttm_tt_populate,
+   .ttm_tt_unpopulate = ttm_page_alloc_ttm_tt_unpopulate,
.invalidate_caches = nouveau_bo_invalidate_caches,
.init_mem_type = nouveau_bo_init_mem_type,
.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c 
b/drivers/gpu/drm/radeon/radeon_ttm.c
index 53ff62b..490afce 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -584,6 +584,8 @@ struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device 
*bdev,
 
 static struct ttm_bo_driver radeon_bo_driver = {
.ttm_tt_create = radeon_ttm_tt_create,
+   .ttm_tt_populate = ttm_page_alloc_ttm_tt_populate,
+   .ttm_tt_unpopulate = ttm_page_alloc_ttm_tt_unpopulate,
.invalidate_caches = radeon_invalidate_caches,
.init_mem_type = radeon_init_mem_type,
.evict_flags = radeon_evict_flags,
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c 
b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 082fcae..60f204d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -244,7 +244,7 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void 
*src,
unsigned long page,
pgprot_t prot)
 {
-   struct page *d = ttm_tt_get_page(ttm, page);
+   struct page *d = ttm-pages[page];
void *dst;
 
if (!d)
@@ -281,7 +281,7 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void 
*dst,
unsigned long page,
pgprot_t prot)
 {
-   struct page *s = ttm_tt_get_page(ttm, page);
+   struct page *s = ttm-pages[page];
void *src;
 
if (!s)
@@ -342,6 +342,12 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
if (old_iomap == NULL  ttm == NULL)
goto out2;
 
+   if (ttm-state == tt_unpopulated) {
+   ret = ttm-bdev-driver-ttm_tt_populate(ttm);
+   if (ret)
+   goto out1;
+   }
+
add = 0;
dir = 1;
 
@@ -502,10 +508,16 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
 {
struct ttm_mem_reg *mem = bo-mem; pgprot_t prot;
struct ttm_tt *ttm = bo-ttm;
-   struct page *d;
-   int i;
+   int ret;
 
BUG_ON(!ttm);
+
+   if (ttm-state == tt_unpopulated) {
+   ret = ttm-bdev-driver-ttm_tt_populate(ttm);
+   if (ret)
+   return ret;
+   }
+
if (num_pages == 1  (mem-placement  TTM_PL_FLAG_CACHED)) {
/*
 * We're mapping a single page, and the desired
@@ -513,18 +525,9 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
 */
 
map-bo_kmap_type = ttm_bo_map_kmap;
-   map-page = ttm_tt_get_page(ttm, start_page);
+   map-page = ttm-pages[start_page];
map-virtual = kmap(map-page);
} else {
-   /*
-* Populate the part we're mapping;
-*/
-   for (i = start_page; i  start_page + num_pages; ++i) {
-   d = ttm_tt_get_page(ttm, i);
-   if (!d)
-   return -ENOMEM;
-   }
-
/*
 * We need to use vmap to get the desired page protection
 * or to make 

[PATCH 11/13] swiotlb: Expose swiotlb_nr_tlb function to modules

2011-11-09 Thread j . glisse
From: Konrad Rzeszutek Wilk konrad.w...@oracle.com

As a mechanism to detect whether SWIOTLB is enabled or not.
We also fix the spelling - it was swioltb instead of
swiotlb.

CC: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp
[v1: Ripped out swiotlb_enabled]
Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
---
 drivers/xen/swiotlb-xen.c |2 +-
 include/linux/swiotlb.h   |2 +-
 lib/swiotlb.c |5 +++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index c984768..c50fb0b 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -152,7 +152,7 @@ void __init xen_swiotlb_init(int verbose)
char *m = NULL;
unsigned int repeat = 3;
 
-   nr_tbl = swioltb_nr_tbl();
+   nr_tbl = swiotlb_nr_tbl();
if (nr_tbl)
xen_io_tlb_nslabs = nr_tbl;
else {
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 445702c..e872526 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -24,7 +24,7 @@ extern int swiotlb_force;
 
 extern void swiotlb_init(int verbose);
 extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int 
verbose);
-extern unsigned long swioltb_nr_tbl(void);
+extern unsigned long swiotlb_nr_tbl(void);
 
 /*
  * Enumeration for sync targets
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 99093b3..058935e 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -110,11 +110,11 @@ setup_io_tlb_npages(char *str)
 __setup(swiotlb=, setup_io_tlb_npages);
 /* make io_tlb_overflow tunable too? */
 
-unsigned long swioltb_nr_tbl(void)
+unsigned long swiotlb_nr_tbl(void)
 {
return io_tlb_nslabs;
 }
-
+EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
 /* Note that this doesn't work with highmem page */
 static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
  volatile void *address)
@@ -321,6 +321,7 @@ void __init swiotlb_free(void)
free_bootmem_late(__pa(io_tlb_start),
  PAGE_ALIGN(io_tlb_nslabs  IO_TLB_SHIFT));
}
+   io_tlb_nslabs = 0;
 }
 
 static int is_swiotlb_buffer(phys_addr_t paddr)
-- 
1.7.7.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 12/13] drm/radeon/kms: Enable the TTM DMA pool if swiotlb is on V2

2011-11-09 Thread j . glisse
From: Konrad Rzeszutek Wilk konrad.w...@oracle.com

With the exception that we do not handle the AGP case. We only
deal with PCIe cards such as ATI ES1000 or HD3200 that have been
detected to only do DMA up to 32-bits.

V2 force dma32 if we fail to set bigger dma mask

CC: Dave Airlie airl...@redhat.com
CC: Alex Deucher alexdeuc...@gmail.com
Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 drivers/gpu/drm/radeon/radeon.h|1 -
 drivers/gpu/drm/radeon/radeon_device.c |6 ++
 drivers/gpu/drm/radeon/radeon_gart.c   |   29 +---
 drivers/gpu/drm/radeon/radeon_ttm.c|   83 +--
 4 files changed, 84 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e3170c7..63257ba 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -332,7 +332,6 @@ struct radeon_gart {
union radeon_gart_table table;
struct page **pages;
dma_addr_t  *pages_addr;
-   bool*ttm_alloced;
boolready;
 };
 
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index c33bc91..7c31321 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -765,8 +765,14 @@ int radeon_device_init(struct radeon_device *rdev,
r = pci_set_dma_mask(rdev-pdev, DMA_BIT_MASK(dma_bits));
if (r) {
rdev-need_dma32 = true;
+   dma_bits = 32;
printk(KERN_WARNING radeon: No suitable DMA available.\n);
}
+   r = pci_set_consistent_dma_mask(rdev-pdev, DMA_BIT_MASK(dma_bits));
+   if (r) {
+   pci_set_consistent_dma_mask(rdev-pdev, DMA_BIT_MASK(32));
+   printk(KERN_WARNING radeon: No coherent DMA available.\n);
+   }
 
/* Registers mapping */
/* TODO: block userspace mapping of io register */
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c 
b/drivers/gpu/drm/radeon/radeon_gart.c
index fdc3a9a..18f496c 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -149,9 +149,6 @@ void radeon_gart_unbind(struct radeon_device *rdev, 
unsigned offset,
p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
for (i = 0; i  pages; i++, p++) {
if (rdev-gart.pages[p]) {
-   if (!rdev-gart.ttm_alloced[p])
-   pci_unmap_page(rdev-pdev, 
rdev-gart.pages_addr[p],
-   PAGE_SIZE, 
PCI_DMA_BIDIRECTIONAL);
rdev-gart.pages[p] = NULL;
rdev-gart.pages_addr[p] = rdev-dummy_page.addr;
page_base = rdev-gart.pages_addr[p];
@@ -181,23 +178,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned 
offset,
p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);
 
for (i = 0; i  pages; i++, p++) {
-   /* we reverted the patch using dma_addr in TTM for now but this
-* code stops building on alpha so just comment it out for now 
*/
-   if (0) { /*dma_addr[i] != DMA_ERROR_CODE) */
-   rdev-gart.ttm_alloced[p] = true;
-   rdev-gart.pages_addr[p] = dma_addr[i];
-   } else {
-   /* we need to support large memory configurations */
-   /* assume that unbind have already been call on the 
range */
-   rdev-gart.pages_addr[p] = pci_map_page(rdev-pdev, 
pagelist[i],
-   0, PAGE_SIZE,
-   PCI_DMA_BIDIRECTIONAL);
-   if (pci_dma_mapping_error(rdev-pdev, 
rdev-gart.pages_addr[p])) {
-   /* FIXME: failed to map page (return -ENOMEM?) 
*/
-   radeon_gart_unbind(rdev, offset, pages);
-   return -ENOMEM;
-   }
-   }
+   rdev-gart.pages_addr[p] = dma_addr[i];
rdev-gart.pages[p] = pagelist[i];
page_base = rdev-gart.pages_addr[p];
for (j = 0; j  (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
@@ -259,12 +240,6 @@ int radeon_gart_init(struct radeon_device *rdev)
radeon_gart_fini(rdev);
return -ENOMEM;
}
-   rdev-gart.ttm_alloced = kzalloc(sizeof(bool) *
-rdev-gart.num_cpu_pages, GFP_KERNEL);
-   if (rdev-gart.ttm_alloced == NULL) {
-   radeon_gart_fini(rdev);
-   return -ENOMEM;
-   }
/* set GART entry to point to the dummy page by default */
for (i = 0; i  rdev-gart.num_cpu_pages; i++) {

[PATCH 13/13] drm/nouveau: enable the TTM DMA pool on 32-bit DMA only device V2

2011-11-09 Thread j . glisse
From: Konrad Rzeszutek Wilk konrad.w...@oracle.com

If the card is capable of more than 32-bit, then use the default
TTM page pool code which allocates from anywhere in the memory.

Note: If the 'ttm.no_dma' parameter is set, the override is ignored
and the default TTM pool is used.

V2 use pci_set_consistent_dma_mask

CC: Ben Skeggs bske...@redhat.com
CC: Francisco Jerez curroje...@riseup.net
CC: Dave Airlie airl...@redhat.com
Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Reviewed-by: Jerome Glisse jgli...@redhat.com
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  |   73 -
 drivers/gpu/drm/nouveau/nouveau_debugfs.c |1 +
 drivers/gpu/drm/nouveau/nouveau_mem.c |6 ++
 drivers/gpu/drm/nouveau/nouveau_sgdma.c   |   60 +---
 4 files changed, 79 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 7e5ca3f..36234a7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1049,10 +1049,79 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
nouveau_fence_unref(old_fence);
 }
 
+static int
+nouveau_ttm_tt_populate(struct ttm_tt *ttm)
+{
+   struct drm_nouveau_private *dev_priv;
+   struct drm_device *dev;
+   unsigned i;
+   int r;
+
+   if (ttm-state != tt_unpopulated)
+   return 0;
+
+   dev_priv = nouveau_bdev(ttm-bdev);
+   dev = dev_priv-dev;
+
+#ifdef CONFIG_SWIOTLB
+   if ((dma_get_mask(dev-dev) = DMA_BIT_MASK(32))  swiotlb_nr_tbl()) {
+   return ttm_dma_populate(ttm, dev-dev);
+   }
+#endif
+
+   r = ttm_page_alloc_ttm_tt_populate(ttm);
+   if (r) {
+   return r;
+   }
+
+   for (i = 0; i  ttm-num_pages; i++) {
+   ttm-dma_address[i] = pci_map_page(dev-pdev, ttm-pages[i],
+  0, PAGE_SIZE,
+  PCI_DMA_BIDIRECTIONAL);
+   if (pci_dma_mapping_error(dev-pdev, ttm-dma_address[i])) {
+   while (--i) {
+   pci_unmap_page(dev-pdev, ttm-dma_address[i],
+  PAGE_SIZE, 
PCI_DMA_BIDIRECTIONAL);
+   ttm-dma_address[i] = 0;
+   }
+   ttm_page_alloc_ttm_tt_unpopulate(ttm);
+   return -EFAULT;
+   }
+   }
+   return 0;
+}
+
+static void
+nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+   struct drm_nouveau_private *dev_priv;
+   struct drm_device *dev;
+   unsigned i;
+
+   dev_priv = nouveau_bdev(ttm-bdev);
+   dev = dev_priv-dev;
+
+#ifdef CONFIG_SWIOTLB
+   if ((dma_get_mask(dev-dev) = DMA_BIT_MASK(32))  swiotlb_nr_tbl()) {
+   ttm_dma_unpopulate(ttm, dev-dev);
+   return;
+   }
+#endif
+
+   for (i = 0; i  ttm-num_pages; i++) {
+   if (ttm-dma_address[i]) {
+   pci_unmap_page(dev-pdev, ttm-dma_address[i],
+  PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+   }
+   }
+
+   ttm_page_alloc_ttm_tt_unpopulate(ttm);
+}
+
 struct ttm_bo_driver nouveau_bo_driver = {
.ttm_tt_create = nouveau_ttm_tt_create,
-   .ttm_tt_populate = ttm_page_alloc_ttm_tt_populate,
-   .ttm_tt_unpopulate = ttm_page_alloc_ttm_tt_unpopulate,
+   .ttm_tt_populate = nouveau_ttm_tt_populate,
+   .ttm_tt_unpopulate = nouveau_ttm_tt_unpopulate,
.invalidate_caches = nouveau_bo_invalidate_caches,
.init_mem_type = nouveau_bo_init_mem_type,
.evict_flags = nouveau_bo_evict_flags,
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c 
b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
index 8e15923..f52c2db 100644
--- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c
@@ -178,6 +178,7 @@ static struct drm_info_list nouveau_debugfs_list[] = {
{ memory, nouveau_debugfs_memory_info, 0, NULL },
{ vbios.rom, nouveau_debugfs_vbios_image, 0, NULL },
{ ttm_page_pool, ttm_page_alloc_debugfs, 0, NULL },
+   { ttm_dma_page_pool, ttm_dma_page_alloc_debugfs, 0, NULL },
 };
 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c 
b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 36bec48..37fcaa2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -407,6 +407,12 @@ nouveau_mem_vram_init(struct drm_device *dev)
ret = pci_set_dma_mask(dev-pdev, DMA_BIT_MASK(dma_bits));
if (ret)
return ret;
+   ret = pci_set_consistent_dma_mask(dev-pdev, DMA_BIT_MASK(dma_bits));
+   if (ret) {
+   /* Reset to default value. */
+   pci_set_consistent_dma_mask(dev-pdev, 

Re: [PATCH v2] radeon: Make sure CS mutex is held across GPU reset.

2011-11-09 Thread Jerome Glisse
On Tue, Nov 08, 2011 at 06:50:19PM +0100, Michel Dänzer wrote:
 From: Michel Dänzer michel.daen...@amd.com
 
 This was only the case if the GPU reset was triggered from the CS ioctl,
 otherwise other processes could happily enter the CS ioctl and wreak havoc
 during the GPU reset.
 
 This is a little complicated because the GPU reset can be triggered from the
 CS ioctl, in which case we're already holding the mutex, or from other call
 paths, in which case we need to lock the mutex. AFAICT the mutex API doesn't
 allow recursive locking or finding out the mutex owner, so we need to handle
 this with helper functions which allow recursive locking from the same
 process.
 
 Signed-off-by: Michel Dänzer michel.daen...@amd.com

Beside not so important comment below

Reviewed-by: Jerome Glisse jgli...@redhat.com
 ---
 
 v2: Use generic radeon_mutex_(un)lock helpers which allow recursive locking
 from the same process. Eliminates int vs. bool return type issue in v1, and
 maybe these helpers can be used similarly for more locks in the future.
 
  drivers/gpu/drm/radeon/radeon.h|   45 
 +++-
  drivers/gpu/drm/radeon/radeon_cs.c |   14 +-
  drivers/gpu/drm/radeon/radeon_device.c |   16 ---
  3 files changed, 63 insertions(+), 12 deletions(-)
 
 diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
 index c1e056b..671d5a5 100644
 --- a/drivers/gpu/drm/radeon/radeon.h
 +++ b/drivers/gpu/drm/radeon/radeon.h
 @@ -1151,6 +1151,48 @@ struct r700_vram_scratch {
   volatile uint32_t   *ptr;
  };
  
 +
 +/*
 + * Mutex which allows recursive locking from the same process.
 + */
 +struct radeon_mutex {
 + struct mutexmutex;
 + struct task_struct  *owner;
 + int level;
 +};
 +
 +static inline void radeon_mutex_init(struct radeon_mutex *mutex)
 +{
 + mutex_init(mutex-mutex);
 + mutex-owner = NULL;
 + mutex-level = 0;
 +}
 +
 +static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
 +{
 + if (mutex_trylock(mutex-mutex)) {
 + /* The mutex was unlocked before, so it's ours now */
 + mutex-owner = current;
 + } else if (mutex-owner != current) {
 + /* Another process locked the mutex, take it */
 + mutex_lock(mutex-mutex);
 + mutex-owner = current;
 + }
 + /* Otherwise the mutex was already locked by this process */
 +
 + mutex-level++;
 +}
 +
 +static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
 +{
 + if (--mutex-level  0)
 + return;
 +
 + mutex-owner = NULL;
 + mutex_unlock(mutex-mutex);
 +}
 +
 +
  /*
   * Core structure, functions and helpers.
   */
 @@ -1206,7 +1248,7 @@ struct radeon_device {
   struct radeon_gem   gem;
   struct radeon_pmpm;
   uint32_tbios_scratch[RADEON_BIOS_NUM_SCRATCH];
 - struct mutexcs_mutex;
 + struct radeon_mutex cs_mutex;
   struct radeon_wbwb;
   struct radeon_dummy_pagedummy_page;
   boolgpu_lockup;
 @@ -1245,6 +1287,7 @@ struct radeon_device {
   struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS];
  };
  
 +
Adding empty line ?
  int radeon_device_init(struct radeon_device *rdev,
  struct drm_device *ddev,
  struct pci_dev *pdev,
 diff --git a/drivers/gpu/drm/radeon/radeon_cs.c 
 b/drivers/gpu/drm/radeon/radeon_cs.c
 index fae00c0..ccaa243 100644
 --- a/drivers/gpu/drm/radeon/radeon_cs.c
 +++ b/drivers/gpu/drm/radeon/radeon_cs.c
 @@ -222,7 +222,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
 struct drm_file *filp)
   struct radeon_cs_chunk *ib_chunk;
   int r;
  
 - mutex_lock(rdev-cs_mutex);
 + radeon_mutex_lock(rdev-cs_mutex);
   /* initialize parser */
   memset(parser, 0, sizeof(struct radeon_cs_parser));
   parser.filp = filp;
 @@ -233,14 +233,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
 struct drm_file *filp)
   if (r) {
   DRM_ERROR(Failed to initialize parser !\n);
   radeon_cs_parser_fini(parser, r);
 - mutex_unlock(rdev-cs_mutex);
 + radeon_mutex_unlock(rdev-cs_mutex);
   return r;
   }
   r =  radeon_ib_get(rdev, parser.ib);
   if (r) {
   DRM_ERROR(Failed to get ib !\n);
   radeon_cs_parser_fini(parser, r);
 - mutex_unlock(rdev-cs_mutex);
 + radeon_mutex_unlock(rdev-cs_mutex);
   return r;
   }
   r = radeon_cs_parser_relocs(parser);
 @@ -248,7 +248,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, 
 struct drm_file *filp)
   if (r != -ERESTARTSYS)
   DRM_ERROR(Failed to parse relocation %d!\n, r);
   radeon_cs_parser_fini(parser, r);
 -  

Re: ttm: merge ttm_backend ttm_tt, introduce ttm dma allocator

2011-11-09 Thread Thomas Hellstrom

On 11/09/2011 09:22 PM, j.gli...@gmail.com wrote:

So i did an overhaul of ttm_memory, i believe the simplification i did
make sense. See patch 5 for a longer explanation.

   
Thomas with the ttm_memory change the allocation of pages won't happen

if the accounting report that we are going over the limit and bo shrinker
failed to free any memory to make room.

The handling of dma32 zone is done as post pass of ttm memory accounting.
   


OK. I'll take a deeper look into this.


Regarding the pagefault comment i removed, it doesn't make sense anymore
because now we populate the whole page table in one shot. So there is
no more prefaulting few pages but a full prefaulting. Thought i can
add a comment stating that if you like.
   


It's important that we distinguish between populating, which populates 
pages,

and faulting, which add ptes pointing to those pages.

Previously populating happened as a side effect of faulting, but now 
that populating is done
in a single step, faulting (adding ptes) is still not. Usually a fault() 
handler adds a single pte,
but TTM is different and tries to prefault more, but it is important 
that we only error on the first

pte, so that's why the comment should stay.


For the ttm_tt_dma struct to hold page allocator specific informations
i think it can be done as an followup patch but if you prefer to have
that in this patchset let me know i will respin with such changes.

   


I'm fine with having it as a separate patchset as long as it gets done :).



I am in the process of retesting this whole serie and especialy the
while memory accounting.

Cheers,
Jerome
   


/Thomas

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 01/12] drm/ttm: remove userspace backed ttm object support

2011-11-09 Thread Jerome Glisse
On Tue, Nov 08, 2011 at 08:22:48AM +0100, Thomas Hellstrom wrote:
 On 11/08/2011 12:40 AM, j.gli...@gmail.com wrote:
 From: Jerome Glissejgli...@redhat.com
 
 This was never use in none of the driver, properly using userspace
 page for bo would need more code (vma interaction mostly). Removing
 this dead code in preparation of ttm_tt  backend merge.
 
 
 Jerome,
 I actually have using user-space TTMs in the pipe for vmwgfx, and it
 doesn't need more code
 (it was used by the psb driver). There are extra requirements,
 though: It only supports cached memory and user-space CPU-access
 needs to be done using existing VMAs.
 
 Anyway, I'll try to figure out a way to do this in the context of
 the unified tt / tt_backends.
 

Issue, and i might be wrong here, is that you need to mark the user
vma as reserved and you need to split the vma to covert only the
portion you want. linux kernel a no helper for that. omap people
use mlock on the range they want to use to make sure that page
associated to the vma are lock and that the vma is split to only
cover the range. I don't think it's safe/enough as userspace can
unlock the vma in our back and things might fall apart at that
point.

My idea was to use mlock to split the vma and then set the reserved
flags on the vma. This will forbid userspace to munlock. When memory
is no longer needed you have to go back to locked flag and then
munlock. Also we might want to do things with page of the vma, for
instance if the object move to vram we might want to free those
pages, but here i fear i need to take a closer look at linux mm
to see what we can do safely on those page to not break any of
the kernel assumptions on those pages.

Anyway, from my inspection this whole things is fragile in regards
of other mm activities that might happen.

Cheers,
Jerome
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: ttm: merge ttm_backend ttm_tt, introduce ttm dma allocator

2011-11-09 Thread Jerome Glisse
On Wed, Nov 09, 2011 at 09:25:20PM +0100, Thomas Hellstrom wrote:
 On 11/09/2011 09:22 PM, j.gli...@gmail.com wrote:
 So i did an overhaul of ttm_memory, i believe the simplification i did
 make sense. See patch 5 for a longer explanation.
 
 Thomas with the ttm_memory change the allocation of pages won't happen
 if the accounting report that we are going over the limit and bo shrinker
 failed to free any memory to make room.
 
 The handling of dma32 zone is done as post pass of ttm memory accounting.
 
 OK. I'll take a deeper look into this.
 
 Regarding the pagefault comment i removed, it doesn't make sense anymore
 because now we populate the whole page table in one shot. So there is
 no more prefaulting few pages but a full prefaulting. Thought i can
 add a comment stating that if you like.
 It's important that we distinguish between populating, which
 populates pages,
 and faulting, which add ptes pointing to those pages.
 
 Previously populating happened as a side effect of faulting, but now
 that populating is done
 in a single step, faulting (adding ptes) is still not. Usually a
 fault() handler adds a single pte,
 but TTM is different and tries to prefault more, but it is important
 that we only error on the first
 pte, so that's why the comment should stay.
 

Well yes it only fill numprefault pte, but no error can happen in the
prefault loop except for vm_insert_mixed failure, it's why i kept the
report error only if it fails on the first page. I actually did a full
pte populate at one point while working on that, dunno if that would
make sense.

 For the ttm_tt_dma struct to hold page allocator specific informations
 i think it can be done as an followup patch but if you prefer to have
 that in this patchset let me know i will respin with such changes.
 
 
 I'm fine with having it as a separate patchset as long as it gets done :).
 

I will spin a patch for that on top of the patchset.

Cheers,
Jerome
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: serialize access to list of debugfs files

2011-11-09 Thread Marcin Slusarz
Nouveau, when configured with debugfs, creates debugfs files for every
channel, so structure holding list of files needs to be protected from
simultaneous changes by multiple threads.

Without this patch it's possible to hit kernel oops in
drm_debugfs_remove_files just by running a couple of xterms with
looped glxinfo.

Signed-off-by: Marcin Slusarz marcin.slus...@gmail.com
Reviewed-by: Daniel Vetter daniel.vet...@ffwll.ch
---
Updated changelog.
---
 drivers/gpu/drm/drm_debugfs.c   |   12 +---
 drivers/gpu/drm/i915/i915_debugfs.c |5 -
 include/drm/drmP.h  |4 +++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index d067c12..1c7a1c0 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, 
int count,
tmp-minor = minor;
tmp-dent = ent;
tmp-info_ent = files[i];
-   list_add((tmp-list), (minor-debugfs_nodes.list));
+
+   mutex_lock(minor-debugfs_lock);
+   list_add(tmp-list, minor-debugfs_list);
+   mutex_unlock(minor-debugfs_lock);
}
return 0;
 
@@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
char name[64];
int ret;
 
-   INIT_LIST_HEAD(minor-debugfs_nodes.list);
+   INIT_LIST_HEAD(minor-debugfs_list);
+   mutex_init(minor-debugfs_lock);
sprintf(name, %d, minor_id);
minor-debugfs_root = debugfs_create_dir(name, root);
if (!minor-debugfs_root) {
@@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, 
int count,
struct drm_info_node *tmp;
int i;
 
+   mutex_lock(minor-debugfs_lock);
for (i = 0; i  count; i++) {
-   list_for_each_safe(pos, q, minor-debugfs_nodes.list) {
+   list_for_each_safe(pos, q, minor-debugfs_list) {
tmp = list_entry(pos, struct drm_info_node, list);
if (tmp-info_ent == files[i]) {
debugfs_remove(tmp-dent);
@@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, 
int count,
}
}
}
+   mutex_unlock(minor-debugfs_lock);
return 0;
 }
 EXPORT_SYMBOL(drm_debugfs_remove_files);
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index d14b44e..4f40f1c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1506,7 +1506,10 @@ drm_add_fake_info_node(struct drm_minor *minor,
node-minor = minor;
node-dent = ent;
node-info_ent = (void *) key;
-   list_add(node-list, minor-debugfs_nodes.list);
+
+   mutex_lock(minor-debugfs_lock);
+   list_add(node-list, minor-debugfs_list);
+   mutex_unlock(minor-debugfs_lock);
 
return 0;
 }
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index cf39949..1f9e951 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -990,7 +990,9 @@ struct drm_minor {
struct proc_dir_entry *proc_root;  /** proc directory entry */
struct drm_info_node proc_nodes;
struct dentry *debugfs_root;
-   struct drm_info_node debugfs_nodes;
+
+   struct list_head debugfs_list;
+   struct mutex debugfs_lock; /* Protects debugfs_list. */
 
struct drm_master *master; /* currently active master for this node */
struct list_head master_list;
-- 
1.7.7.2

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Isolate dma information from ttm_tt

2011-11-09 Thread j . glisse
This apply on top of the ttm_tt  backend merge patchset.

Cheers,
Jerome

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 14/14] drm/ttm: isolate dma data from ttm_tt

2011-11-09 Thread j . glisse
From: Jerome Glisse jgli...@redhat.com

Move dma data to a superset ttm_dma_tt structure which herit
from ttm_tt. This allow driver that don't use dma functionalities
to not have to waste memory for it.

Signed-off-by: Jerome Glisse jgli...@redhat.com
---
 drivers/gpu/drm/nouveau/nouveau_bo.c |   18 +
 drivers/gpu/drm/nouveau/nouveau_sgdma.c  |   22 +++
 drivers/gpu/drm/radeon/radeon_ttm.c  |   43 +++---
 drivers/gpu/drm/ttm/ttm_page_alloc.c |   10 +++---
 drivers/gpu/drm/ttm/ttm_page_alloc_dma.c |   38 +++-
 drivers/gpu/drm/ttm/ttm_tt.c |   58 -
 drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c   |2 +
 include/drm/ttm/ttm_bo_driver.h  |   31 +++-
 include/drm/ttm/ttm_page_alloc.h |   12 ++
 9 files changed, 155 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 36234a7..df3f19c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1052,6 +1052,7 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct 
nouveau_fence *fence)
 static int
 nouveau_ttm_tt_populate(struct ttm_tt *ttm)
 {
+   struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct drm_nouveau_private *dev_priv;
struct drm_device *dev;
unsigned i;
@@ -1065,7 +1066,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
 
 #ifdef CONFIG_SWIOTLB
if ((dma_get_mask(dev-dev) = DMA_BIT_MASK(32))  swiotlb_nr_tbl()) {
-   return ttm_dma_populate(ttm, dev-dev);
+   return ttm_dma_populate((void *)ttm, dev-dev);
}
 #endif
 
@@ -1075,14 +1076,14 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
}
 
for (i = 0; i  ttm-num_pages; i++) {
-   ttm-dma_address[i] = pci_map_page(dev-pdev, ttm-pages[i],
+   ttm_dma-dma_address[i] = pci_map_page(dev-pdev, ttm-pages[i],
   0, PAGE_SIZE,
   PCI_DMA_BIDIRECTIONAL);
-   if (pci_dma_mapping_error(dev-pdev, ttm-dma_address[i])) {
+   if (pci_dma_mapping_error(dev-pdev, ttm_dma-dma_address[i])) {
while (--i) {
-   pci_unmap_page(dev-pdev, ttm-dma_address[i],
+   pci_unmap_page(dev-pdev, 
ttm_dma-dma_address[i],
   PAGE_SIZE, 
PCI_DMA_BIDIRECTIONAL);
-   ttm-dma_address[i] = 0;
+   ttm_dma-dma_address[i] = 0;
}
ttm_page_alloc_ttm_tt_unpopulate(ttm);
return -EFAULT;
@@ -1094,6 +1095,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
 static void
 nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
 {
+   struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct drm_nouveau_private *dev_priv;
struct drm_device *dev;
unsigned i;
@@ -1103,14 +1105,14 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
 
 #ifdef CONFIG_SWIOTLB
if ((dma_get_mask(dev-dev) = DMA_BIT_MASK(32))  swiotlb_nr_tbl()) {
-   ttm_dma_unpopulate(ttm, dev-dev);
+   ttm_dma_unpopulate((void *)ttm, dev-dev);
return;
}
 #endif
 
for (i = 0; i  ttm-num_pages; i++) {
-   if (ttm-dma_address[i]) {
-   pci_unmap_page(dev-pdev, ttm-dma_address[i],
+   if (ttm_dma-dma_address[i]) {
+   pci_unmap_page(dev-pdev, ttm_dma-dma_address[i],
   PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c 
b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index ee1eb7c..47f245e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -8,7 +8,10 @@
 #define NV_CTXDMA_PAGE_MASK  (NV_CTXDMA_PAGE_SIZE - 1)
 
 struct nouveau_sgdma_be {
-   struct ttm_tt ttm;
+   /* this has to be the first field so populate/unpopulated in
+* nouve_bo.c works properly, otherwise have to move them here
+*/
+   struct ttm_dma_tt ttm;
struct drm_device *dev;
u64 offset;
 };
@@ -20,6 +23,7 @@ nouveau_sgdma_destroy(struct ttm_tt *ttm)
 
if (ttm) {
NV_DEBUG(nvbe-dev, \n);
+   ttm_dma_tt_fini(nvbe-ttm);
kfree(nvbe);
}
 }
@@ -38,7 +42,7 @@ nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
nvbe-offset = mem-start  PAGE_SHIFT;
pte = (nvbe-offset  NV_CTXDMA_PAGE_SHIFT) + 2;
for (i = 0; i  ttm-num_pages; i++) {
-   dma_addr_t dma_offset = ttm-dma_address[i];
+   dma_addr_t dma_offset = nvbe-ttm.dma_address[i];
uint32_t offset_l = lower_32_bits(dma_offset);
 
for (j =