diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem.h')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem.h | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 7a9107cf1818..13aabfe92dac 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -51,17 +51,23 @@ struct msm_gem_object { uint8_t madv; /** + * Is object on inactive_dontneed list (ie. counted in priv->shrinkable_count)? + */ + bool dontneed : 1; + + /** * count of active vmap'ing */ uint8_t vmap_count; - /* And object is either: - * inactive - on priv->inactive_list + /** + * An object is either: + * inactive - on priv->inactive_dontneed/willneed/purged depending + * on status * active - on one one of the gpu's active_list.. well, at * least for now we don't have (I don't think) hw sync between * 2d and 3d one devices which have both, meaning we need to * block on submit if a bo is already on other ring - * */ struct list_head mm_list; @@ -186,10 +192,16 @@ static inline bool is_active(struct msm_gem_object *msm_obj) return msm_obj->active_count; } +/* imported/exported objects are not purgable: */ +static inline bool is_unpurgable(struct msm_gem_object *msm_obj) +{ + return msm_obj->base.dma_buf && msm_obj->base.import_attach; +} + static inline bool is_purgeable(struct msm_gem_object *msm_obj) { return (msm_obj->madv == MSM_MADV_DONTNEED) && msm_obj->sgt && - !msm_obj->base.dma_buf && !msm_obj->base.import_attach; + !is_unpurgable(msm_obj); } static inline bool is_vunmapable(struct msm_gem_object *msm_obj) @@ -198,6 +210,39 @@ static inline bool is_vunmapable(struct msm_gem_object *msm_obj) return (msm_obj->vmap_count == 0) && msm_obj->vaddr; } +static inline void mark_purgable(struct msm_gem_object *msm_obj) +{ + struct msm_drm_private *priv = msm_obj->base.dev->dev_private; + + WARN_ON(!mutex_is_locked(&priv->mm_lock)); + + if (is_unpurgable(msm_obj)) + return; + + if (WARN_ON(msm_obj->dontneed)) + return; + + priv->shrinkable_count += msm_obj->base.size >> PAGE_SHIFT; + msm_obj->dontneed = true; +} + +static inline void mark_unpurgable(struct msm_gem_object *msm_obj) +{ + struct msm_drm_private *priv = msm_obj->base.dev->dev_private; + + WARN_ON(!mutex_is_locked(&priv->mm_lock)); + + if (is_unpurgable(msm_obj)) + return; + + if (WARN_ON(!msm_obj->dontneed)) + return; + + priv->shrinkable_count -= msm_obj->base.size >> PAGE_SHIFT; + WARN_ON(priv->shrinkable_count < 0); + msm_obj->dontneed = false; +} + void msm_gem_purge(struct drm_gem_object *obj); void msm_gem_vunmap(struct drm_gem_object *obj); |