vmwgfx: Implement a proper GMR eviction mechanism

Use Ben's new range manager hooks to implement a manager for
GMRs that manages ids rather than ranges.
This means we can use the standard TTM code for binding, unbinding and
eviction.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Thomas Hellstrom
2010-10-26 21:21:47 +02:00
committed by Dave Airlie
parent 8f895da57d
commit 135cba0dc3
9 changed files with 252 additions and 160 deletions

View File

@@ -146,7 +146,7 @@ static void vmw_gmr_fire_descriptors(struct vmw_private *dev_priv,
*/
static unsigned long vmw_gmr_count_descriptors(struct page *pages[],
unsigned long num_pages)
unsigned long num_pages)
{
unsigned long prev_pfn = ~(0UL);
unsigned long pfn;
@@ -163,45 +163,33 @@ static unsigned long vmw_gmr_count_descriptors(struct page *pages[],
}
int vmw_gmr_bind(struct vmw_private *dev_priv,
struct ttm_buffer_object *bo)
struct page *pages[],
unsigned long num_pages,
int gmr_id)
{
struct ttm_tt *ttm = bo->ttm;
unsigned long descriptors;
int ret;
uint32_t id;
struct list_head desc_pages;
int ret;
if (!(dev_priv->capabilities & SVGA_CAP_GMR))
if (unlikely(!(dev_priv->capabilities & SVGA_CAP_GMR)))
return -EINVAL;
ret = ttm_tt_populate(ttm);
if (unlikely(ret != 0))
return ret;
descriptors = vmw_gmr_count_descriptors(ttm->pages, ttm->num_pages);
if (unlikely(descriptors > dev_priv->max_gmr_descriptors))
if (vmw_gmr_count_descriptors(pages, num_pages) >
dev_priv->max_gmr_descriptors)
return -EINVAL;
INIT_LIST_HEAD(&desc_pages);
ret = vmw_gmr_build_descriptors(&desc_pages, ttm->pages,
ttm->num_pages);
ret = vmw_gmr_build_descriptors(&desc_pages, pages, num_pages);
if (unlikely(ret != 0))
return ret;
ret = vmw_gmr_id_alloc(dev_priv, &id);
if (unlikely(ret != 0))
goto out_no_id;
vmw_gmr_fire_descriptors(dev_priv, id, &desc_pages);
vmw_gmr_fire_descriptors(dev_priv, gmr_id, &desc_pages);
vmw_gmr_free_descriptors(&desc_pages);
vmw_dmabuf_set_gmr(bo, id);
return 0;
out_no_id:
vmw_gmr_free_descriptors(&desc_pages);
return ret;
}
void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id)
{
mutex_lock(&dev_priv->hw_mutex);