diff options
| author | Thomas Hellstrom <thellstrom@vmware.com> | 2010-11-11 03:41:57 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2010-11-21 22:25:22 -0500 |
| commit | eba67093f535322cb4f1c4b737319c0907a0c81d (patch) | |
| tree | 695b9a43d558a2870b23d6813f60387d7d61c614 /include/drm/ttm | |
| parent | 65705962025df490d13df59ec57c5329d1bd0a16 (diff) | |
drm/ttm: Fix up io_mem_reserve / io_mem_free calling
This patch attempts to fix up shortcomings with the current calling
sequences.
1) There's a fastpath where no locking occurs and only io_mem_reserved is
called to obtain needed info for mapping. The fastpath is set per
memory type manager.
2) If the fastpath is disabled, io_mem_reserve and io_mem_free will be exactly
balanced and not called recursively for the same struct ttm_mem_reg.
3) Optionally the driver can choose to enable a per memory type manager LRU
eviction mechanism that, when io_mem_reserve returns -EAGAIN will attempt
to kill user-space mappings of memory in that manager to free up needed
resources
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include/drm/ttm')
| -rw-r--r-- | include/drm/ttm/ttm_bo_api.h | 6 | ||||
| -rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 104 |
2 files changed, 60 insertions, 50 deletions
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index edacd483c59..50852aad260 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h | |||
| @@ -74,6 +74,8 @@ struct ttm_placement { | |||
| 74 | * @is_iomem: is this io memory ? | 74 | * @is_iomem: is this io memory ? |
| 75 | * @size: size in byte | 75 | * @size: size in byte |
| 76 | * @offset: offset from the base address | 76 | * @offset: offset from the base address |
| 77 | * @io_reserved_vm: The VM system has a refcount in @io_reserved_count | ||
| 78 | * @io_reserved_count: Refcounting the numbers of callers to ttm_mem_io_reserve | ||
| 77 | * | 79 | * |
| 78 | * Structure indicating the bus placement of an object. | 80 | * Structure indicating the bus placement of an object. |
| 79 | */ | 81 | */ |
| @@ -83,7 +85,8 @@ struct ttm_bus_placement { | |||
| 83 | unsigned long size; | 85 | unsigned long size; |
| 84 | unsigned long offset; | 86 | unsigned long offset; |
| 85 | bool is_iomem; | 87 | bool is_iomem; |
| 86 | bool io_reserved; | 88 | bool io_reserved_vm; |
| 89 | uint64_t io_reserved_count; | ||
| 87 | }; | 90 | }; |
| 88 | 91 | ||
| 89 | 92 | ||
| @@ -235,6 +238,7 @@ struct ttm_buffer_object { | |||
| 235 | struct list_head lru; | 238 | struct list_head lru; |
| 236 | struct list_head ddestroy; | 239 | struct list_head ddestroy; |
| 237 | struct list_head swap; | 240 | struct list_head swap; |
| 241 | struct list_head io_reserve_lru; | ||
| 238 | uint32_t val_seq; | 242 | uint32_t val_seq; |
| 239 | bool seq_valid; | 243 | bool seq_valid; |
| 240 | 244 | ||
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index e3b2e245db1..1da8af6ac88 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
| @@ -179,30 +179,6 @@ struct ttm_tt { | |||
| 179 | #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ | 179 | #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ |
| 180 | #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ | 180 | #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ |
| 181 | 181 | ||
| 182 | /** | ||
| 183 | * struct ttm_mem_type_manager | ||
| 184 | * | ||
| 185 | * @has_type: The memory type has been initialized. | ||
| 186 | * @use_type: The memory type is enabled. | ||
| 187 | * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory | ||
| 188 | * managed by this memory type. | ||
| 189 | * @gpu_offset: If used, the GPU offset of the first managed page of | ||
| 190 | * fixed memory or the first managed location in an aperture. | ||
| 191 | * @size: Size of the managed region. | ||
| 192 | * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, | ||
| 193 | * as defined in ttm_placement_common.h | ||
| 194 | * @default_caching: The default caching policy used for a buffer object | ||
| 195 | * placed in this memory type if the user doesn't provide one. | ||
| 196 | * @manager: The range manager used for this memory type. FIXME: If the aperture | ||
| 197 | * has a page size different from the underlying system, the granularity | ||
| 198 | * of this manager should take care of this. But the range allocating code | ||
| 199 | * in ttm_bo.c needs to be modified for this. | ||
| 200 | * @lru: The lru list for this memory type. | ||
| 201 | * | ||
| 202 | * This structure is used to identify and manage memory types for a device. | ||
| 203 | * It's set up by the ttm_bo_driver::init_mem_type method. | ||
| 204 | */ | ||
| 205 | |||
| 206 | struct ttm_mem_type_manager; | 182 | struct ttm_mem_type_manager; |
| 207 | 183 | ||
| 208 | struct ttm_mem_type_manager_func { | 184 | struct ttm_mem_type_manager_func { |
| @@ -287,6 +263,36 @@ struct ttm_mem_type_manager_func { | |||
| 287 | void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); | 263 | void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); |
| 288 | }; | 264 | }; |
| 289 | 265 | ||
| 266 | /** | ||
| 267 | * struct ttm_mem_type_manager | ||
| 268 | * | ||
| 269 | * @has_type: The memory type has been initialized. | ||
| 270 | * @use_type: The memory type is enabled. | ||
| 271 | * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory | ||
| 272 | * managed by this memory type. | ||
| 273 | * @gpu_offset: If used, the GPU offset of the first managed page of | ||
| 274 | * fixed memory or the first managed location in an aperture. | ||
| 275 | * @size: Size of the managed region. | ||
| 276 | * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, | ||
| 277 | * as defined in ttm_placement_common.h | ||
| 278 | * @default_caching: The default caching policy used for a buffer object | ||
| 279 | * placed in this memory type if the user doesn't provide one. | ||
| 280 | * @func: structure pointer implementing the range manager. See above | ||
| 281 | * @priv: Driver private closure for @func. | ||
| 282 | * @io_reserve_mutex: Mutex optionally protecting shared io_reserve structures | ||
| 283 | * @use_io_reserve_lru: Use an lru list to try to unreserve io_mem_regions | ||
| 284 | * reserved by the TTM vm system. | ||
| 285 | * @io_reserve_lru: Optional lru list for unreserving io mem regions. | ||
| 286 | * @io_reserve_fastpath: Only use bdev::driver::io_mem_reserve to obtain | ||
| 287 | * static information. bdev::driver::io_mem_free is never used. | ||
| 288 | * @lru: The lru list for this memory type. | ||
| 289 | * | ||
| 290 | * This structure is used to identify and manage memory types for a device. | ||
| 291 | * It's set up by the ttm_bo_driver::init_mem_type method. | ||
| 292 | */ | ||
| 293 | |||
| 294 | |||
| 295 | |||
| 290 | struct ttm_mem_type_manager { | 296 | struct ttm_mem_type_manager { |
| 291 | struct ttm_bo_device *bdev; | 297 | struct ttm_bo_device *bdev; |
| 292 | 298 | ||
| @@ -303,6 +309,15 @@ struct ttm_mem_type_manager { | |||
| 303 | uint32_t default_caching; | 309 | uint32_t default_caching; |
| 304 | const struct ttm_mem_type_manager_func *func; | 310 | const struct ttm_mem_type_manager_func *func; |
| 305 | void *priv; | 311 | void *priv; |
| 312 | struct mutex io_reserve_mutex; | ||
| 313 | bool use_io_reserve_lru; | ||
| 314 | bool io_reserve_fastpath; | ||
| 315 | |||
| 316 | /* | ||
| 317 | * Protected by @io_reserve_mutex: | ||
| 318 | */ | ||
| 319 | |||
| 320 | struct list_head io_reserve_lru; | ||
| 306 | 321 | ||
| 307 | /* | 322 | /* |
| 308 | * Protected by the global->lru_lock. | 323 | * Protected by the global->lru_lock. |
| @@ -758,31 +773,6 @@ extern void ttm_bo_mem_put_locked(struct ttm_buffer_object *bo, | |||
| 758 | 773 | ||
| 759 | extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); | 774 | extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); |
| 760 | 775 | ||
| 761 | /** | ||
| 762 | * ttm_bo_pci_offset - Get the PCI offset for the buffer object memory. | ||
| 763 | * | ||
| 764 | * @bo Pointer to a struct ttm_buffer_object. | ||
| 765 | * @bus_base On return the base of the PCI region | ||
| 766 | * @bus_offset On return the byte offset into the PCI region | ||
| 767 | * @bus_size On return the byte size of the buffer object or zero if | ||
| 768 | * the buffer object memory is not accessible through a PCI region. | ||
| 769 | * | ||
| 770 | * Returns: | ||
| 771 | * -EINVAL if the buffer object is currently not mappable. | ||
| 772 | * 0 otherwise. | ||
| 773 | */ | ||
| 774 | |||
| 775 | extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, | ||
| 776 | struct ttm_mem_reg *mem, | ||
| 777 | unsigned long *bus_base, | ||
| 778 | unsigned long *bus_offset, | ||
| 779 | unsigned long *bus_size); | ||
| 780 | |||
| 781 | extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev, | ||
| 782 | struct ttm_mem_reg *mem); | ||
| 783 | extern void ttm_mem_io_free(struct ttm_bo_device *bdev, | ||
| 784 | struct ttm_mem_reg *mem); | ||
| 785 | |||
| 786 | extern void ttm_bo_global_release(struct drm_global_reference *ref); | 776 | extern void ttm_bo_global_release(struct drm_global_reference *ref); |
| 787 | extern int ttm_bo_global_init(struct drm_global_reference *ref); | 777 | extern int ttm_bo_global_init(struct drm_global_reference *ref); |
| 788 | 778 | ||
| @@ -815,6 +805,22 @@ extern int ttm_bo_device_init(struct ttm_bo_device *bdev, | |||
| 815 | extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); | 805 | extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); |
| 816 | 806 | ||
| 817 | /** | 807 | /** |
| 808 | * ttm_bo_unmap_virtual | ||
| 809 | * | ||
| 810 | * @bo: tear down the virtual mappings for this BO | ||
| 811 | * | ||
| 812 | * The caller must take ttm_mem_io_lock before calling this function. | ||
| 813 | */ | ||
| 814 | extern void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo); | ||
| 815 | |||
| 816 | extern int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo); | ||
| 817 | extern void ttm_mem_io_free_vm(struct ttm_buffer_object *bo); | ||
| 818 | extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man, | ||
| 819 | bool interruptible); | ||
| 820 | extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); | ||
| 821 | |||
| 822 | |||
| 823 | /** | ||
| 818 | * ttm_bo_reserve: | 824 | * ttm_bo_reserve: |
| 819 | * | 825 | * |
| 820 | * @bo: A pointer to a struct ttm_buffer_object. | 826 | * @bo: A pointer to a struct ttm_buffer_object. |
