- ttm_mem_global_release(&ttm_mem_glob);
__free_page(glob->dummy_read_page);
memset(glob, 0, sizeof(*glob));
out:
@@ -61,6 +66,8 @@ static void ttm_global_release(void)
static int ttm_global_init(void)
{
struct ttm_global *glob = &ttm_glob;
+ unsigned long num_pages;
+ struct sysinfo si;
int ret = 0;
unsigned i;
@@ -68,9 +75,14 @@ static int ttm_global_init(void)
if (++ttm_glob_use_count > 1)
goto out;
- ret = ttm_mem_global_init(&ttm_mem_glob);
- if (ret)
- goto out;
+ si_meminfo(&si);
+
+ /* Limit the number of pages in the pool to about 50% of the total
+ * system memory.
+ */
+ num_pages = ((u64)si.totalram * si.mem_unit) >> PAGE_SHIFT;
+ ttm_pool_mgr_init(num_pages * 50 / 100);
+ ttm_tt_mgr_init();
spin_lock_init(&glob->lru_lock);
glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index e0617717113f..6b0f957d63d5 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -404,16 +404,10 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
caching = pages + (1 << order);
}
- r = ttm_mem_global_alloc_page(&ttm_mem_glob, p,
- (1 << order) * PAGE_SIZE,
- ctx);
- if (r)
- goto error_free_page;
-
if (dma_addr) {
r = ttm_pool_map(pool, order, p, &dma_addr);
if (r)
- goto error_global_free;
+ goto error_free_page;
}
num_pages -= 1 << order;
@@ -427,9 +421,6 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
return 0;
-error_global_free:
- ttm_mem_global_free_page(&ttm_mem_glob, p, (1 << order) * PAGE_SIZE);
-
error_free_page:
ttm_pool_free_page(pool, tt->caching, order, p);
@@ -464,8 +455,6 @@ void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt)
order = ttm_pool_page_order(pool, p);
num_pages = 1ULL << order;
- ttm_mem_global_free_page(&ttm_mem_glob, p,
- num_pages * PAGE_SIZE);
if (tt->dma_address)
ttm_pool_unmap(pool, tt->dma_address[i], num_pages);
diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index cc4cdca7176e..8c02fa5852e7 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -9,7 +9,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \
vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \
- ttm_object.o ttm_lock.o
+ ttm_object.o ttm_lock.o ttm_memory.o
vmwgfx-$(CONFIG_TRANSPARENT_HUGEPAGE) += vmwgfx_thp.o
obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/vmwgfx/ttm_memory.c
similarity index 97%
rename from drivers/gpu/drm/ttm/ttm_memory.c
rename to drivers/gpu/drm/vmwgfx/ttm_memory.c
index 634a85c2dc4c..e972af07d029 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/vmwgfx/ttm_memory.c
@@ -28,7 +28,6 @@
#define pr_fmt(fmt) "[TTM] " fmt
-#include <drm/ttm/ttm_memory.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/wait.h>
@@ -36,10 +35,11 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/swap.h>
-#include <drm/ttm/ttm_pool.h>
-#include <drm/ttm/ttm_tt.h>
-#include "ttm_module.h"
+#include <drm/drm_device.h>
+#include <drm/drm_file.h>
+
+#include "ttm_memory.h"
#define TTM_MEMORY_ALLOC_RETRIES 4
@@ -414,7 +414,7 @@ static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,
}
#endif
-int ttm_mem_global_init(struct ttm_mem_global *glob)
+int ttm_mem_global_init(struct ttm_mem_global *glob, struct device *dev)
{
struct sysinfo si;
int ret;
@@ -424,8 +424,9 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
spin_lock_init(&glob->lock);
glob->swap_queue = create_singlethread_workqueue("ttm_swap");
INIT_WORK(&glob->work, ttm_shrink_work);
- ret = kobject_init_and_add(
- &glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting");
+
+ ret = kobject_init_and_add(&glob->kobj, &ttm_mem_glob_kobj_type,
+ &dev->kobj, "memory_accounting");
if (unlikely(ret != 0)) {
kobject_put(&glob->kobj);
return ret;
@@ -453,8 +454,6 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
pr_info("Zone %7s: Available graphics memory: %llu KiB\n",
zone->name, (unsigned long long)zone->max_mem >> 10);
}
- ttm_pool_mgr_init(glob->zone_kernel->max_mem/(2*PAGE_SIZE));
- ttm_tt_mgr_init();
return 0;
out_no_zone:
ttm_mem_global_release(glob);
@@ -466,10 +465,6 @@ void ttm_mem_global_release(struct ttm_mem_global *glob)
struct ttm_mem_zone *zone;
unsigned int i;
- /* let the page allocator first stop the shrink work. */
- ttm_pool_mgr_fini();
- ttm_tt_mgr_fini();
-
flush_workqueue(glob->swap_queue);
destroy_workqueue(glob->swap_queue);
glob->swap_queue = NULL;
diff --git a/include/drm/ttm/ttm_memory.h b/drivers/gpu/drm/vmwgfx/ttm_memory.h
similarity index 97%
rename from include/drm/ttm/ttm_memory.h
rename to drivers/gpu/drm/vmwgfx/ttm_memory.h
index c1f167881e33..c50dba774485 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/drivers/gpu/drm/vmwgfx/ttm_memory.h
@@ -35,7 +35,8 @@
#include <linux/errno.h>
#include <linux/kobject.h>
#include <linux/mm.h>
-#include "ttm_bo_api.h"
+
+#include <drm/ttm/ttm_bo_api.h>
/**
* struct ttm_mem_global - Global memory accounting structure.
@@ -79,7 +80,7 @@ extern struct ttm_mem_global {
#endif
} ttm_mem_glob;
-int ttm_mem_global_init(struct ttm_mem_global *glob);
+int ttm_mem_global_init(struct ttm_mem_global *glob, struct device *dev);
void ttm_mem_global_release(struct ttm_mem_global *glob);
int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
struct ttm_operation_ctx *ctx);
diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.h b/drivers/gpu/drm/vmwgfx/ttm_object.h
index ede26df87c93..49b064f0cb19 100644
--- a/drivers/gpu/drm/vmwgfx/ttm_object.h
+++ b/drivers/gpu/drm/vmwgfx/ttm_object.h
@@ -43,7 +43,8 @@
#include <linux/rcupdate.h>
#include <drm/drm_hashtab.h>
-#include <drm/ttm/ttm_memory.h>
+
+#include "ttm_memory.h"
/**
* enum ttm_ref_type
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
index 6b3bfd8c678a..50e529a01677 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -507,11 +507,16 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
acc_size = ttm_round_pot(sizeof(*bo));
acc_size += ttm_round_pot(npages * sizeof(void *));
acc_size += ttm_round_pot(sizeof(struct ttm_tt));
+
+ ret = ttm_mem_global_alloc(&ttm_mem_glob, acc_size, &ctx);
+ if (unlikely(ret))
+ goto error_free;
+
ret = ttm_bo_init_reserved(&dev_priv->bdev, bo, size,
ttm_bo_type_device, placement, 0,
- &ctx, acc_size, NULL, NULL, NULL);
+ &ctx, NULL, NULL, NULL);
if (unlikely(ret))
- goto error_free;
+ goto error_account;
ttm_bo_pin(bo);
ttm_bo_unreserve(bo);
@@ -519,6 +524,9 @@ int vmw_bo_create_kernel(struct vmw_private *dev_priv, unsigned long size,
return 0;
+error_account:
+ ttm_mem_global_free(&ttm_mem_glob, acc_size);
+
error_free:
kfree(bo);
return ret;
@@ -558,11 +566,17 @@ int vmw_bo_init(struct vmw_private *dev_priv,
vmw_bo->base.priority = 3;
vmw_bo->res_tree = RB_ROOT;
+ ret = ttm_mem_global_alloc(&ttm_mem_glob, acc_size, &ctx);
+ if (unlikely(ret))
+ return ret;
+
ret = ttm_bo_init_reserved(bdev, &vmw_bo->base, size,
ttm_bo_type_device, placement,
- 0, &ctx, acc_size, NULL, NULL, bo_free);
- if (unlikely(ret))
+ 0, &ctx, NULL, NULL, bo_free);
+ if (unlikely(ret)) {
+ ttm_mem_global_free(&ttm_mem_glob, acc_size);
return ret;
+ }
if (pin)
ttm_bo_pin(&vmw_bo->base);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 9a9afa087802..4efed3bf0ef9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1268,6 +1268,7 @@ static void vmw_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
+ ttm_mem_global_release(&ttm_mem_glob);
drm_dev_unregister(dev);
vmw_driver_unload(dev);
}
@@ -1518,6 +1519,10 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, &vmw->drm);
+ ret = ttm_mem_global_init(&ttm_mem_glob, &pdev->dev);
+ if (ret)
+ return ret;
+
ret = vmw_driver_load(vmw, ent->device);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index d1bfa59579f1..63f10c865061 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -576,11 +576,31 @@ static void vmw_ttm_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
static int vmw_ttm_populate(struct ttm_device *bdev,
struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
{
+ unsigned int i;
+ int ret;
+
/* TODO: maybe completely drop this ? */
if (ttm_tt_is_populated(ttm))
return 0;
- return ttm_pool_alloc(&bdev->pool, ttm, ctx);
+ ret = ttm_pool_alloc(&bdev->pool, ttm, ctx);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < ttm->num_pages; ++i) {
+ ret = ttm_mem_global_alloc_page(&ttm_mem_glob, ttm->pages[i],
+ PAGE_SIZE, ctx);
+ if (ret)
+ goto error;
+ }
+ return 0;
+
+error:
+ while (i--)
+ ttm_mem_global_free_page(&ttm_mem_glob, ttm->pages[i],
+ PAGE_SIZE);
+ ttm_pool_free(&bdev->pool, ttm);
+ return ret;
}
static void vmw_ttm_unpopulate(struct ttm_device *bdev,
@@ -588,6 +608,7 @@ static void vmw_ttm_unpopulate(struct ttm_device *bdev,
{
struct vmw_ttm_tt *vmw_tt = container_of(ttm, struct vmw_ttm_tt,
dma_ttm);
+ unsigned int i;
if (vmw_tt->mob) {
vmw_mob_destroy(vmw_tt->mob);
@@ -595,6 +616,11 @@ static void vmw_ttm_unpopulate(struct ttm_device *bdev,
}
vmw_ttm_unmap_dma(vmw_tt);
+
+ for (i = 0; i < ttm->num_pages; ++i)
+ ttm_mem_global_free_page(&ttm_mem_glob, ttm->pages[i],
+ PAGE_SIZE);
+
ttm_pool_free(&bdev->pool, ttm);
}
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index 1297a8fb7ccb..4fb523dfab32 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -88,7 +88,6 @@ struct ttm_tt;
* @type: The bo type.
* @destroy: Destruction function. If NULL, kfree is used.
* @num_pages: Actual number of pages.
- * @acc_size: Accounted size for this object.
* @kref: Reference count of this buffer object. When this refcount reaches
* zero, the object is destroyed or put on the delayed delete list.
* @mem: structure describing current placement.
@@ -125,7 +124,6 @@ struct ttm_buffer_object {
struct ttm_device *bdev;
enum ttm_bo_type type;
void (*destroy) (struct ttm_buffer_object *);
- size_t acc_size;
/**
* Members not needing protection.
@@ -357,10 +355,6 @@ void ttm_bo_unlock_delayed_workqueue(struct ttm_device *bdev, int resched);
bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place);
-size_t ttm_bo_dma_acc_size(struct ttm_device *bdev,
- unsigned long bo_size,
- unsigned struct_size);
-
/**
* ttm_bo_init_reserved
*
@@ -371,7 +365,6 @@ size_t ttm_bo_dma_acc_size(struct ttm_device *bdev,
* @flags: Initial placement flags.
* @page_alignment: Data alignment in pages.
* @ctx: TTM operation context for memory allocation.
- * @acc_size: Accounted size for this object.
* @resv: Pointer to a dma_resv, or NULL to let ttm allocate one.
* @destroy: Destroy function. Use NULL for kfree().
*
@@ -402,8 +395,7 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
struct ttm_placement *placement,
uint32_t page_alignment,
struct ttm_operation_ctx *ctx,
- size_t acc_size, struct sg_table *sg,
- struct dma_resv *resv,
+ struct sg_table *sg, struct dma_resv *resv,
void (*destroy) (struct ttm_buffer_object *));
/**
@@ -421,7 +413,6 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
* holds a pointer to a persistent shmem object. Typically, this would
* point to the shmem object backing a GEM object if TTM is used to back a
* GEM user interface.
- * @acc_size: Accounted size for this object.
* @resv: Pointer to a dma_resv, or NULL to let ttm allocate one.
* @destroy: Destroy function. Use NULL for kfree().
*
@@ -446,7 +437,7 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
int ttm_bo_init(struct ttm_device *bdev, struct ttm_buffer_object *bo,
size_t size, enum ttm_bo_type type,
struct ttm_placement *placement,
- uint32_t page_alignment, bool interrubtible, size_t acc_size,
+ uint32_t page_alignment, bool interrubtible,
struct sg_table *sg, struct dma_resv *resv,
void (*destroy) (struct ttm_buffer_object *));
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 1c9bf993e252..8959c0075cfd 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -40,7 +40,6 @@
#include <drm/ttm/ttm_device.h>
#include "ttm_bo_api.h"
-#include "ttm_memory.h"
#include "ttm_placement.h"
#include "ttm_tt.h"
#include "ttm_pool.h"
diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
index cce57fb49e2c..069f8130241a 100644
--- a/include/drm/ttm/ttm_tt.h
+++ b/include/drm/ttm/ttm_tt.h
@@ -30,6 +30,7 @@
#include <linux/types.h>
#include <drm/ttm/ttm_caching.h>
+struct ttm_bo_device;
struct ttm_tt;
struct ttm_resource;
struct ttm_buffer_object;