|
@@ -48,24 +48,12 @@ static struct sg_table *
|
|
i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
|
|
i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
|
|
{
|
|
{
|
|
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
|
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
|
- unsigned int npages = obj->base.size / PAGE_SIZE;
|
|
|
|
struct sg_table *st;
|
|
struct sg_table *st;
|
|
struct scatterlist *sg;
|
|
struct scatterlist *sg;
|
|
|
|
+ unsigned int npages;
|
|
int max_order;
|
|
int max_order;
|
|
gfp_t gfp;
|
|
gfp_t gfp;
|
|
|
|
|
|
- st = kmalloc(sizeof(*st), GFP_KERNEL);
|
|
|
|
- if (!st)
|
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
|
-
|
|
|
|
- if (sg_alloc_table(st, npages, GFP_KERNEL)) {
|
|
|
|
- kfree(st);
|
|
|
|
- return ERR_PTR(-ENOMEM);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- sg = st->sgl;
|
|
|
|
- st->nents = 0;
|
|
|
|
-
|
|
|
|
max_order = MAX_ORDER;
|
|
max_order = MAX_ORDER;
|
|
#ifdef CONFIG_SWIOTLB
|
|
#ifdef CONFIG_SWIOTLB
|
|
if (swiotlb_nr_tbl()) {
|
|
if (swiotlb_nr_tbl()) {
|
|
@@ -87,6 +75,20 @@ i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
|
|
gfp |= __GFP_DMA32;
|
|
gfp |= __GFP_DMA32;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+create_st:
|
|
|
|
+ st = kmalloc(sizeof(*st), GFP_KERNEL);
|
|
|
|
+ if (!st)
|
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
|
+
|
|
|
|
+ npages = obj->base.size / PAGE_SIZE;
|
|
|
|
+ if (sg_alloc_table(st, npages, GFP_KERNEL)) {
|
|
|
|
+ kfree(st);
|
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sg = st->sgl;
|
|
|
|
+ st->nents = 0;
|
|
|
|
+
|
|
do {
|
|
do {
|
|
int order = min(fls(npages) - 1, max_order);
|
|
int order = min(fls(npages) - 1, max_order);
|
|
struct page *page;
|
|
struct page *page;
|
|
@@ -114,8 +116,15 @@ i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
|
|
sg = __sg_next(sg);
|
|
sg = __sg_next(sg);
|
|
} while (1);
|
|
} while (1);
|
|
|
|
|
|
- if (i915_gem_gtt_prepare_pages(obj, st))
|
|
|
|
|
|
+ if (i915_gem_gtt_prepare_pages(obj, st)) {
|
|
|
|
+ /* Failed to dma-map try again with single page sg segments */
|
|
|
|
+ if (get_order(st->sgl->length)) {
|
|
|
|
+ internal_free_pages(st);
|
|
|
|
+ max_order = 0;
|
|
|
|
+ goto create_st;
|
|
|
|
+ }
|
|
goto err;
|
|
goto err;
|
|
|
|
+ }
|
|
|
|
|
|
/* Mark the pages as dontneed whilst they are still pinned. As soon
|
|
/* Mark the pages as dontneed whilst they are still pinned. As soon
|
|
* as they are unpinned they are allowed to be reaped by the shrinker,
|
|
* as they are unpinned they are allowed to be reaped by the shrinker,
|