msm_gem.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (C) 2013 Red Hat
  3. * Author: Rob Clark <robdclark@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 as published by
  7. * the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef __MSM_GEM_H__
  18. #define __MSM_GEM_H__
  19. #include <linux/kref.h>
  20. #include <linux/reservation.h>
  21. #include "msm_drv.h"
  22. /* Additional internal-use only BO flags: */
  23. #define MSM_BO_STOLEN 0x10000000 /* try to use stolen/splash memory */
  24. struct msm_gem_address_space {
  25. const char *name;
  26. /* NOTE: mm managed at the page level, size is in # of pages
  27. * and position mm_node->start is in # of pages:
  28. */
  29. struct drm_mm mm;
  30. spinlock_t lock; /* Protects drm_mm node allocation/removal */
  31. struct msm_mmu *mmu;
  32. struct kref kref;
  33. };
  34. struct msm_gem_vma {
  35. struct drm_mm_node node;
  36. uint64_t iova;
  37. struct msm_gem_address_space *aspace;
  38. struct list_head list; /* node in msm_gem_object::vmas */
  39. };
  40. struct msm_gem_object {
  41. struct drm_gem_object base;
  42. uint32_t flags;
  43. /**
  44. * Advice: are the backing pages purgeable?
  45. */
  46. uint8_t madv;
  47. /**
  48. * count of active vmap'ing
  49. */
  50. uint8_t vmap_count;
  51. /* And object is either:
  52. * inactive - on priv->inactive_list
  53. * active - on one one of the gpu's active_list.. well, at
  54. * least for now we don't have (I don't think) hw sync between
  55. * 2d and 3d one devices which have both, meaning we need to
  56. * block on submit if a bo is already on other ring
  57. *
  58. */
  59. struct list_head mm_list;
  60. struct msm_gpu *gpu; /* non-null if active */
  61. /* Transiently in the process of submit ioctl, objects associated
  62. * with the submit are on submit->bo_list.. this only lasts for
  63. * the duration of the ioctl, so one bo can never be on multiple
  64. * submit lists.
  65. */
  66. struct list_head submit_entry;
  67. struct page **pages;
  68. struct sg_table *sgt;
  69. void *vaddr;
  70. struct list_head vmas; /* list of msm_gem_vma */
  71. /* normally (resv == &_resv) except for imported bo's */
  72. struct reservation_object *resv;
  73. struct reservation_object _resv;
  74. /* For physically contiguous buffers. Used when we don't have
  75. * an IOMMU. Also used for stolen/splashscreen buffer.
  76. */
  77. struct drm_mm_node *vram_node;
  78. struct mutex lock; /* Protects resources associated with bo */
  79. };
  80. #define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
  81. static inline bool is_active(struct msm_gem_object *msm_obj)
  82. {
  83. return msm_obj->gpu != NULL;
  84. }
  85. static inline bool is_purgeable(struct msm_gem_object *msm_obj)
  86. {
  87. WARN_ON(!mutex_is_locked(&msm_obj->base.dev->struct_mutex));
  88. return (msm_obj->madv == MSM_MADV_DONTNEED) && msm_obj->sgt &&
  89. !msm_obj->base.dma_buf && !msm_obj->base.import_attach;
  90. }
  91. static inline bool is_vunmapable(struct msm_gem_object *msm_obj)
  92. {
  93. return (msm_obj->vmap_count == 0) && msm_obj->vaddr;
  94. }
  95. /* The shrinker can be triggered while we hold objA->lock, and need
  96. * to grab objB->lock to purge it. Lockdep just sees these as a single
  97. * class of lock, so we use subclasses to teach it the difference.
  98. *
  99. * OBJ_LOCK_NORMAL is implicit (ie. normal mutex_lock() call), and
  100. * OBJ_LOCK_SHRINKER is used by shrinker.
  101. *
  102. * It is *essential* that we never go down paths that could trigger the
  103. * shrinker for a purgable object. This is ensured by checking that
  104. * msm_obj->madv == MSM_MADV_WILLNEED.
  105. */
  106. enum msm_gem_lock {
  107. OBJ_LOCK_NORMAL,
  108. OBJ_LOCK_SHRINKER,
  109. };
  110. void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass);
  111. void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass);
  112. /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
  113. * associated with the cmdstream submission for synchronization (and
  114. * make it easier to unwind when things go wrong, etc). This only
  115. * lasts for the duration of the submit-ioctl.
  116. */
  117. struct msm_gem_submit {
  118. struct drm_device *dev;
  119. struct msm_gpu *gpu;
  120. struct list_head node; /* node in ring submit list */
  121. struct list_head bo_list;
  122. struct ww_acquire_ctx ticket;
  123. uint32_t seqno; /* Sequence number of the submit on the ring */
  124. struct dma_fence *fence;
  125. struct msm_gpu_submitqueue *queue;
  126. struct pid *pid; /* submitting process */
  127. bool valid; /* true if no cmdstream patching needed */
  128. bool in_rb; /* "sudo" mode, copy cmds into RB */
  129. struct msm_ringbuffer *ring;
  130. unsigned int nr_cmds;
  131. unsigned int nr_bos;
  132. struct {
  133. uint32_t type;
  134. uint32_t size; /* in dwords */
  135. uint64_t iova;
  136. uint32_t idx; /* cmdstream buffer idx in bos[] */
  137. } *cmd; /* array of size nr_cmds */
  138. struct {
  139. uint32_t flags;
  140. struct msm_gem_object *obj;
  141. uint64_t iova;
  142. } bos[0];
  143. };
  144. #endif /* __MSM_GEM_H__ */