summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2012-11-12 13:13:13 +1000
committerAlon Levy <alevy@redhat.com>2012-11-12 14:01:59 +0200
commit85af3963af033e2d33f76d1666334959fa792168 (patch)
tree7fe7c7a3542717b06b605337365c3ed812cf4869
parent25780ae6898a7846b95522698330bda18d6109bc (diff)
qxl/ttm: fix hang when out of memory.qxl
If userspace keeps allocating and never freeing, we need to start evicting. fix ttm pop/unpop so eviction works.
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index b119afe8243..b01ab1fbdd3 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -2,6 +2,7 @@
#include <ttm/ttm_bo_api.h>
#include <ttm/ttm_bo_driver.h>
#include <ttm/ttm_placement.h>
+#include <ttm/ttm_page_alloc.h>
#include <ttm/ttm_module.h>
#include <drm/drmP.h>
#include <drm/drm.h>
@@ -151,11 +152,17 @@ static int qxl_bo_man_get_node(struct ttm_mem_type_manager *man,
mman.bdev);
int ret;
int res = 0;
+ int count_loops = 0;
ret = ttm_bo_manager_func.get_node(man, bo, placement, mem);
while (unlikely(ret || mem->mm_node == NULL)) {
qxl_io_notify_oom(qdev);
res += qxl_garbage_collect(qdev);
+ if (res == 0)
+ mdelay(10);
+ count_loops++;
+ if (count_loops == 2)
+ return 0;
/* TODO - sleep here */
ret = ttm_bo_manager_func.get_node(man, bo, placement, mem);
}
@@ -322,6 +329,25 @@ static struct ttm_backend_func qxl_backend_func = {
.destroy = &qxl_ttm_backend_destroy,
};
+static int qxl_ttm_tt_populate(struct ttm_tt *ttm)
+{
+ int r;
+
+ if (ttm->state != tt_unpopulated)
+ return 0;
+
+ r = ttm_pool_populate(ttm);
+ if (r) {
+ return r;
+ }
+
+ return 0;
+}
+
+static void qxl_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+ ttm_pool_unpopulate(ttm);
+}
struct ttm_tt *qxl_ttm_tt_create(struct ttm_bo_device *bdev,
unsigned long size, uint32_t page_flags,
@@ -346,6 +372,8 @@ struct ttm_tt *qxl_ttm_tt_create(struct ttm_bo_device *bdev,
static struct ttm_bo_driver qxl_bo_driver = {
.ttm_tt_create = &qxl_ttm_tt_create,
+ .ttm_tt_populate = &qxl_ttm_tt_populate,
+ .ttm_tt_unpopulate = &qxl_ttm_tt_unpopulate,
.invalidate_caches = &qxl_invalidate_caches,
.init_mem_type = &qxl_init_mem_type,
.evict_flags = &qxl_evict_flags,