Skip to content

Commit b72af44

Browse files
committed
drm/etnaviv: request pages from DMA32 zone when needed
Some Vivante GPUs are found in systems that have interconnects restricted to 32 address bits, but may have system memory mapped above the 4GB mark. As this region isn't accessible to the GPU via DMA any GPU memory allocated in the upper part needs to go through SWIOTLB bounce buffering. This kills performance if it happens too often, as well as overrunning the available bounce buffer space, as the GPU buffer may stay mapped for a long time. Avoid bounce buffering by checking the addressing restrictions. If the GPU is unable to access memory above the 4GB mark, request our SHM buffers to be located in the DMA32 zone. Signed-off-by: Lucas Stach <[email protected]>
1 parent 1442d81 commit b72af44

File tree

4 files changed

+12
-2
lines changed

4 files changed

+12
-2
lines changed

drivers/gpu/drm/etnaviv/etnaviv_drv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ static int etnaviv_bind(struct device *dev)
551551
mutex_init(&priv->gem_lock);
552552
INIT_LIST_HEAD(&priv->gem_list);
553553
priv->num_gpus = 0;
554+
priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
554555

555556
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
556557
if (IS_ERR(priv->cmdbuf_suballoc)) {

drivers/gpu/drm/etnaviv/etnaviv_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct etnaviv_drm_private {
3535
int num_gpus;
3636
struct device_dma_parameters dma_parms;
3737
struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
38+
gfp_t shm_gfp_mask;
3839

3940
struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
4041
struct etnaviv_iommu_global *mmu_global;

drivers/gpu/drm/etnaviv/etnaviv_gem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
602602
int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
603603
u32 size, u32 flags, u32 *handle)
604604
{
605+
struct etnaviv_drm_private *priv = dev->dev_private;
605606
struct drm_gem_object *obj = NULL;
606607
int ret;
607608

@@ -624,8 +625,7 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
624625
* above new_inode() why this is required _and_ expected if you're
625626
* going to pin these pages.
626627
*/
627-
mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER |
628-
__GFP_RETRY_MAYFAIL | __GFP_NOWARN);
628+
mapping_set_gfp_mask(obj->filp->f_mapping, priv->shm_gfp_mask);
629629

630630
etnaviv_gem_obj_add(dev, obj);
631631

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
781781
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
782782
}
783783

784+
/*
785+
* If the GPU is part of a system with DMA addressing limitations,
786+
* request pages for our SHM backend buffers from the DMA32 zone to
787+
* hopefully avoid performance killing SWIOTLB bounce buffering.
788+
*/
789+
if (dma_addressing_limited(gpu->dev))
790+
priv->shm_gfp_mask |= GFP_DMA32;
791+
784792
/* Create buffer: */
785793
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
786794
PAGE_SIZE);

0 commit comments

Comments
 (0)