Currently a single type of surface is allocated in a specific BAR. This also changes from userspace driver to the kernel one. This way it could happen that allocation are failing even if there are plenty of space in the other BAR. For instance this can happen trying to change resolution as the old and the new virtual screen is supposed to be contained in a single BAR. The change allows allocation to occur in the BAR not being the default for a surface type.
The patches prove to be really stable. I tested setting quite small BARs (one or the oher) or changing default allocation BAR and continued working. Setting large resolution is working fine while without these patches fails for not so big BAR sizes.
Changes from previous version: - remove RFC; - added signed-off-by; - added prefix in commit title; - rebased.
Frediano Ziglio (2): drm/qxl: change the way slot is detected drm/qxl: allocate objects in both video rams
drivers/gpu/drm/qxl/qxl_cmd.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.h | 9 ++++++++- drivers/gpu/drm/qxl/qxl_object.c | 11 +++++++---- 3 files changed, 16 insertions(+), 6 deletions(-)
Instead of relaying on surface type use the actual placement. This allow to have different placement for a single type of surface.
Signed-off-by: Frediano Ziglio fziglio@redhat.com --- drivers/gpu/drm/qxl/qxl_cmd.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.h | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index fdc1833..3a1b055 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -511,7 +511,7 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, cmd->u.surface_create.height = surf->surf.height; cmd->u.surface_create.stride = surf->surf.stride; if (new_mem) { - int slot_id = surf->type == QXL_GEM_DOMAIN_VRAM ? qdev->main_mem_slot : qdev->surfaces_mem_slot; + int slot_id = qxl_bo_get_slot_id(qdev, surf); struct qxl_memslot *slot = &(qdev->mem_slots[slot_id]);
/* TODO - need to hold one of the locks to read tbo.offset */ diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 01a8694..60f0062 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -365,11 +365,18 @@ qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical) return 0; }
+static inline int +qxl_bo_get_slot_id(struct qxl_device *qdev, struct qxl_bo *bo) +{ + return ((bo->tbo.cur_placement & TTM_PL_MASK_MEM) == TTM_PL_FLAG_VRAM) ? + qdev->main_mem_slot : qdev->surfaces_mem_slot; +} + static inline uint64_t qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo, unsigned long offset) { - int slot_id = bo->type == QXL_GEM_DOMAIN_VRAM ? qdev->main_mem_slot : qdev->surfaces_mem_slot; + int slot_id = qxl_bo_get_slot_id(qdev, bo); struct qxl_memslot *slot = &(qdev->mem_slots[slot_id]);
/* TODO - need to hold one of the locks to read tbo.offset */
If memory is not enough in the default BAR for a type try other BAR this allow better memory usage and avoid memory allocation failure if a BAR is quite small and other is quite unused.
Signed-off-by: Frediano Ziglio fziglio@redhat.com --- drivers/gpu/drm/qxl/qxl_object.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index b28370e..b99395e 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -58,14 +58,17 @@ void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned)
qbo->placement.placement = qbo->placements; qbo->placement.busy_placement = qbo->placements; - if (domain == QXL_GEM_DOMAIN_VRAM) + if (domain == QXL_GEM_DOMAIN_VRAM) { qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM | pflag; - if (domain == QXL_GEM_DOMAIN_SURFACE) qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0 | pflag; - if (domain == QXL_GEM_DOMAIN_CPU) + } else if (domain == QXL_GEM_DOMAIN_SURFACE) { + qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0 | pflag; + qbo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM | pflag; + } else if (domain == QXL_GEM_DOMAIN_CPU) { qbo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM | pflag; - if (!c) + } else { qbo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; + } qbo->placement.num_placement = c; qbo->placement.num_busy_placement = c; for (i = 0; i < c; ++i) {
dri-devel@lists.freedesktop.org