From 3024f23c6551e219b0236041a8205bf1bc60ed94 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 31 Jan 2007 14:50:57 +0100 Subject: memory manager: Make device driver aware of different memory types. Memory types are either fixed (on-card or pre-bound AGP) or not fixed (dynamically bound) to an aperture. They also carry information about: 1) Whether they can be mapped cached. 2) Whether they are at all mappable. 3) Whether they need an ioremap to be accessible from kernel space. In this way VRAM memory and, for example, pre-bound AGP appear identical to the memory manager. This also makes support for unmappable VRAM simple to implement. --- linux-core/drmP.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 9c748e6e..c0064bb7 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -650,17 +650,30 @@ typedef struct drm_ref_object { #include "drm_ttm.h" + +typedef struct drm_mem_type_manager { + int has_type; + int use_type; + drm_mm_t manager; + struct list_head lru; + struct list_head pinned; + uint32_t flags; + unsigned long io_offset; + unsigned long io_size; + void *io_addr; +} drm_mem_type_manager_t; + /* * buffer object driver */ typedef struct drm_bo_driver{ - int cached[DRM_BO_MEM_TYPES]; - drm_local_map_t *iomap[DRM_BO_MEM_TYPES]; drm_ttm_backend_t *(*create_ttm_backend_entry) (struct drm_device *dev); int (*fence_type)(uint32_t flags, uint32_t *class, uint32_t *type); int (*invalidate_caches)(struct drm_device *dev, uint32_t flags); + int (*init_mem_type)(struct drm_device *dev, uint32_t type, + drm_mem_type_manager_t *man); } drm_bo_driver_t; @@ -782,16 +795,18 @@ typedef struct drm_fence_manager{ atomic_t count; } drm_fence_manager_t; +#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */ +#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */ +#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Supports cached binding */ +#define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap + before kernel access. */ + typedef struct drm_buffer_manager{ struct mutex init_mutex; int nice_mode; int initialized; drm_file_t *last_to_validate; - int has_type[DRM_BO_MEM_TYPES]; - int use_type[DRM_BO_MEM_TYPES]; - drm_mm_t manager[DRM_BO_MEM_TYPES]; - struct list_head lru[DRM_BO_MEM_TYPES]; - struct list_head pinned[DRM_BO_MEM_TYPES]; + drm_mem_type_manager_t man[DRM_BO_MEM_TYPES]; struct list_head unfenced; struct list_head ddestroy; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -- cgit v1.2.3 From 9677c5ecc6b97ef75b3141b671fb5cfbbf8a3fa8 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 1 Feb 2007 10:53:07 +0100 Subject: Prepare for removal of the ttm_object type. --- linux-core/drmP.h | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c0064bb7..2453c756 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -650,6 +650,11 @@ typedef struct drm_ref_object { #include "drm_ttm.h" +#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */ +#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */ +#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Supports cached binding */ +#define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap + before kernel access. */ typedef struct drm_mem_type_manager { int has_type; @@ -795,11 +800,16 @@ typedef struct drm_fence_manager{ atomic_t count; } drm_fence_manager_t; -#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */ -#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */ -#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Supports cached binding */ -#define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap - before kernel access. */ + +typedef struct drm_bo_mem_region { + drm_mm_node_t *node; + uint32_t memory_type; + drm_ttm_t *ttm; + unsigned long bus_offset; + unsigned long num_pages; + uint32_t vm_flags; +} drm_bo_mem_region_t; + typedef struct drm_buffer_manager{ struct mutex init_mutex; @@ -1005,8 +1015,6 @@ typedef struct drm_buffer_object{ atomic_t usage; drm_ttm_object_t *ttm_object; - drm_ttm_t *ttm; - unsigned long num_pages; unsigned long buffer_start; drm_bo_type_t type; unsigned long offset; @@ -1016,7 +1024,7 @@ typedef struct drm_buffer_object{ uint32_t mask; uint32_t mem_type; - drm_mm_node_t *mm_node; /* MM node for on-card RAM */ + drm_mm_node_t *mm_node; struct list_head lru; struct list_head ddestroy; @@ -1026,6 +1034,16 @@ typedef struct drm_buffer_object{ uint32_t priv_flags; wait_queue_head_t event_queue; struct mutex mutex; + + /* For vm */ + + drm_mm_node_t *node; + uint32_t memory_type; + drm_ttm_t *ttm; + unsigned long bus_offset; + unsigned long num_pages; + uint32_t vm_flags; + } drm_buffer_object_t; #define _DRM_BO_FLAG_UNFENCED 0x00000001 -- cgit v1.2.3 From dd733dea3856e7ddbba7c4c3928ccaba909b4535 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 1 Feb 2007 13:19:05 +0100 Subject: Fix missing ttm_open_vma call from previous commit. Honour the ttm backend cant-use-aperture flag. --- linux-core/drmP.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 2453c756..090bd124 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1043,6 +1043,7 @@ typedef struct drm_buffer_object{ unsigned long bus_offset; unsigned long num_pages; uint32_t vm_flags; + void *iomap; } drm_buffer_object_t; -- cgit v1.2.3 From c269d560e4d71448cfc9c2ea51eee3d5feafaad4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 2 Feb 2007 14:47:44 +0100 Subject: Make vm handle buffer objects instead of ttm objects. Remove ttm objects. Make vm aware of PCI memory type buffer objects. (Only works for pre 2.6.16 kernels for now). --- linux-core/drmP.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 090bd124..84a06470 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1014,7 +1014,6 @@ typedef struct drm_buffer_object{ */ atomic_t usage; - drm_ttm_object_t *ttm_object; unsigned long buffer_start; drm_bo_type_t type; unsigned long offset; @@ -1037,6 +1036,7 @@ typedef struct drm_buffer_object{ /* For vm */ + drm_map_list_t map_list; drm_mm_node_t *node; uint32_t memory_type; drm_ttm_t *ttm; @@ -1485,6 +1485,11 @@ extern int drm_bo_ioctl(DRM_IOCTL_ARGS); extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS); extern int drm_bo_driver_finish(drm_device_t *dev); extern int drm_bo_driver_init(drm_device_t *dev); +extern int drm_bo_pci_offset(const drm_buffer_object_t *bo, + unsigned long *bus_base, + unsigned long *bus_offset, + unsigned long *bus_size); +extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo); extern int drm_fence_buffer_objects(drm_file_t * priv, struct list_head *list, uint32_t fence_flags, -- cgit v1.2.3 From 63f2abd721c40f1cddae555c79b4ab4c55aae006 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 2 Feb 2007 19:49:11 +0100 Subject: Make also later kernels work with buffer object vm and clean up some function names. --- linux-core/drmP.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 84a06470..dd07a603 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1044,6 +1044,13 @@ typedef struct drm_buffer_object{ unsigned long num_pages; uint32_t vm_flags; void *iomap; + + +#ifdef DRM_ODD_MM_COMPAT + /* dev->struct_mutex only protected. */ + struct list_head vma_list; + struct list_head p_mm_list; +#endif } drm_buffer_object_t; -- cgit v1.2.3 From 609e3b037526021d20c7cc18b7fed1152206dc68 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 6 Feb 2007 14:20:33 +0100 Subject: Implement a policy for selecting memory types. --- linux-core/drmP.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index dd07a603..5834c9dc 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -673,12 +673,17 @@ typedef struct drm_mem_type_manager { */ typedef struct drm_bo_driver{ + const uint32_t *mem_type_prio; + const uint32_t *mem_busy_prio; + uint32_t num_mem_type_prio; + uint32_t num_mem_busy_prio; drm_ttm_backend_t *(*create_ttm_backend_entry) (struct drm_device *dev); int (*fence_type)(uint32_t flags, uint32_t *class, uint32_t *type); int (*invalidate_caches)(struct drm_device *dev, uint32_t flags); int (*init_mem_type)(struct drm_device *dev, uint32_t type, drm_mem_type_manager_t *man); + uint32_t (*evict_flags) (struct drm_device *dev, uint32_t type); } drm_bo_driver_t; @@ -800,19 +805,9 @@ typedef struct drm_fence_manager{ atomic_t count; } drm_fence_manager_t; - -typedef struct drm_bo_mem_region { - drm_mm_node_t *node; - uint32_t memory_type; - drm_ttm_t *ttm; - unsigned long bus_offset; - unsigned long num_pages; - uint32_t vm_flags; -} drm_bo_mem_region_t; - - typedef struct drm_buffer_manager{ struct mutex init_mutex; + struct mutex evict_mutex; int nice_mode; int initialized; drm_file_t *last_to_validate; @@ -1003,6 +998,16 @@ typedef struct drm_fence_object{ uint32_t submitted_flush; } drm_fence_object_t; +typedef struct drm_bo_mem_reg { + drm_mm_node_t *mm_node; + unsigned long size; + unsigned long num_pages; + uint32_t page_alignment; + uint32_t mem_type; + uint32_t flags; + uint32_t mask; +} drm_bo_mem_reg_t; + typedef struct drm_buffer_object{ drm_device_t *dev; -- cgit v1.2.3 From 40ce53dfde11f84d7bf8db5db93fb73715b2e96e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 6 Feb 2007 15:56:43 +0100 Subject: Implement a drm_mem_reg_t substructure in the buffer object type. --- linux-core/drmP.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 5834c9dc..a8f5e3e2 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1022,13 +1022,9 @@ typedef struct drm_buffer_object{ unsigned long buffer_start; drm_bo_type_t type; unsigned long offset; - uint32_t page_alignment; atomic_t mapped; - uint32_t flags; - uint32_t mask; - uint32_t mem_type; + drm_bo_mem_reg_t mem; - drm_mm_node_t *mm_node; struct list_head lru; struct list_head ddestroy; @@ -1042,11 +1038,9 @@ typedef struct drm_buffer_object{ /* For vm */ drm_map_list_t map_list; - drm_mm_node_t *node; uint32_t memory_type; drm_ttm_t *ttm; unsigned long bus_offset; - unsigned long num_pages; uint32_t vm_flags; void *iomap; -- cgit v1.2.3 From 71b9e876f99db219fcbf4e3ab977b64b068cc2b4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 6 Feb 2007 16:59:45 +0100 Subject: Simplify pci map vs no pci map choice. --- linux-core/drmP.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index a8f5e3e2..62efddd9 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -655,6 +655,7 @@ typedef struct drm_ref_object { #define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Supports cached binding */ #define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap before kernel access. */ +#define _DRM_FLAG_MEMTYPE_CMA 0x00000010 /* Can't map aperture */ typedef struct drm_mem_type_manager { int has_type; @@ -1037,9 +1038,9 @@ typedef struct drm_buffer_object{ /* For vm */ + drm_ttm_t *ttm; drm_map_list_t map_list; uint32_t memory_type; - drm_ttm_t *ttm; unsigned long bus_offset; uint32_t vm_flags; void *iomap; @@ -1491,10 +1492,14 @@ extern int drm_bo_ioctl(DRM_IOCTL_ARGS); extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS); extern int drm_bo_driver_finish(drm_device_t *dev); extern int drm_bo_driver_init(drm_device_t *dev); -extern int drm_bo_pci_offset(const drm_buffer_object_t *bo, +extern int drm_bo_pci_offset(drm_device_t *dev, + drm_bo_mem_reg_t *mem, unsigned long *bus_base, unsigned long *bus_offset, unsigned long *bus_size); +extern int drm_mem_reg_is_pci(drm_device_t *dev, drm_bo_mem_reg_t *mem); + + extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo); extern int drm_fence_buffer_objects(drm_file_t * priv, struct list_head *list, -- cgit v1.2.3 From af24465b2eddfcc5296edc830ea5ed86065a4abd Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 7 Feb 2007 12:52:23 +0100 Subject: Fix a stray unlock_kernel() in drm_vm.c Add a file for memory move helpers, drm_bo_move.c Implement generic memory move. Cached, no_move and unmapped memory temporarily broken. --- linux-core/drmP.h | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 62efddd9..cdab1cb1 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -669,6 +669,16 @@ typedef struct drm_mem_type_manager { void *io_addr; } drm_mem_type_manager_t; +typedef struct drm_bo_mem_reg { + drm_mm_node_t *mm_node; + unsigned long size; + unsigned long num_pages; + uint32_t page_alignment; + uint32_t mem_type; + uint32_t flags; + uint32_t mask; +} drm_bo_mem_reg_t; + /* * buffer object driver */ @@ -685,6 +695,10 @@ typedef struct drm_bo_driver{ int (*init_mem_type)(struct drm_device *dev, uint32_t type, drm_mem_type_manager_t *man); uint32_t (*evict_flags) (struct drm_device *dev, uint32_t type); + int (*move)(struct drm_device *dev, + struct drm_ttm *ttm, int evict, int no_wait, + struct drm_bo_mem_reg *old_mem, + struct drm_bo_mem_reg *new_mem); } drm_bo_driver_t; @@ -999,16 +1013,6 @@ typedef struct drm_fence_object{ uint32_t submitted_flush; } drm_fence_object_t; -typedef struct drm_bo_mem_reg { - drm_mm_node_t *mm_node; - unsigned long size; - unsigned long num_pages; - uint32_t page_alignment; - uint32_t mem_type; - uint32_t flags; - uint32_t mask; -} drm_bo_mem_reg_t; - typedef struct drm_buffer_object{ drm_device_t *dev; @@ -1506,6 +1510,16 @@ extern int drm_fence_buffer_objects(drm_file_t * priv, uint32_t fence_flags, drm_fence_object_t *fence, drm_fence_object_t **used_fence); +/* + * Buffer object memory move helpers. + * drm_bo_move.c + */ + +extern int drm_bo_move_ttm(drm_device_t *dev, + drm_ttm_t *ttm, int evict, + int no_wait, + drm_bo_mem_reg_t *old_mem, + drm_bo_mem_reg_t *new_mem); extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); -- cgit v1.2.3 From c1fbd8a56653b91af57a408bbcf20a760a2bd8c8 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 7 Feb 2007 17:25:13 +0100 Subject: Checkpoint commit. Flag handling and memory type selection cleanup. glxgears won't start. --- linux-core/drmP.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index cdab1cb1..d3a9a2a5 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -652,10 +652,12 @@ typedef struct drm_ref_object { #define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */ #define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */ -#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Supports cached binding */ +#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Cached binding */ #define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap before kernel access. */ #define _DRM_FLAG_MEMTYPE_CMA 0x00000010 /* Can't map aperture */ +#define _DRM_FLAG_MEMTYPE_CSELECT 0x00000020 /* Select caching */ + typedef struct drm_mem_type_manager { int has_type; -- cgit v1.2.3 From 1257907fa9a24de7aa95485e1b3ab509fdc4d4e6 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 8 Feb 2007 13:29:08 +0100 Subject: Simplify external ttm page allocation. Implement a memcpy fallback for copying between buffers. --- linux-core/drmP.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index d3a9a2a5..aff10b62 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1522,7 +1522,11 @@ extern int drm_bo_move_ttm(drm_device_t *dev, int no_wait, drm_bo_mem_reg_t *old_mem, drm_bo_mem_reg_t *new_mem); - +extern int drm_bo_move_memcpy(drm_device_t *dev, + drm_ttm_t *ttm, int evict, + int no_wait, + drm_bo_mem_reg_t *old_mem, + drm_bo_mem_reg_t *new_mem); extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); -- cgit v1.2.3 From e4b2da440699f581a8779ea8cb9e99e4c903e6a7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 8 Feb 2007 16:21:38 +0100 Subject: A minor function interface change and some memcpy bugfixing. Hooray!! it sort of works with a fixed AGP area as faked VRAM. --- linux-core/drmP.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index aff10b62..7b8f2c66 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -697,9 +697,8 @@ typedef struct drm_bo_driver{ int (*init_mem_type)(struct drm_device *dev, uint32_t type, drm_mem_type_manager_t *man); uint32_t (*evict_flags) (struct drm_device *dev, uint32_t type); - int (*move)(struct drm_device *dev, - struct drm_ttm *ttm, int evict, int no_wait, - struct drm_bo_mem_reg *old_mem, + int (*move)(struct drm_buffer_object *bo, + int evict, int no_wait, struct drm_bo_mem_reg *new_mem); } drm_bo_driver_t; @@ -1517,15 +1516,13 @@ extern int drm_fence_buffer_objects(drm_file_t * priv, * drm_bo_move.c */ -extern int drm_bo_move_ttm(drm_device_t *dev, - drm_ttm_t *ttm, int evict, +extern int drm_bo_move_ttm(drm_buffer_object_t *bo, + int evict, int no_wait, - drm_bo_mem_reg_t *old_mem, drm_bo_mem_reg_t *new_mem); -extern int drm_bo_move_memcpy(drm_device_t *dev, - drm_ttm_t *ttm, int evict, +extern int drm_bo_move_memcpy(drm_buffer_object_t *bo, + int evict, int no_wait, - drm_bo_mem_reg_t *old_mem, drm_bo_mem_reg_t *new_mem); extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); -- cgit v1.2.3 From bf8f46d4c64eb5b66814223f7e5ddb8d8e7a555e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 8 Feb 2007 18:59:02 +0100 Subject: Fix mm_block leak. Some other minor fixes. --- linux-core/drmP.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 7b8f2c66..55035210 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -608,9 +608,6 @@ typedef enum { } drm_object_type_t; - - - /* * A user object is a structure that helps the drm give out user handles * to kernel internal objects and to keep track of these objects so that @@ -647,6 +644,7 @@ typedef struct drm_ref_object { drm_ref_t unref_action; } drm_ref_object_t; +struct drm_buffer_object; #include "drm_ttm.h" -- cgit v1.2.3 From b2bcbf874b0f26ca0c490fb0453bef64ce6d9dd7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 8 Feb 2007 21:28:33 +0100 Subject: Add an accelerated buffer copy cleanup helper. Export helper functions and make some important buffer-object functions non-static. Add an i915 accelerated blit buffer move for pci memory buffers. --- linux-core/drmP.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 55035210..86dcd79f 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1509,6 +1509,15 @@ extern int drm_fence_buffer_objects(drm_file_t * priv, uint32_t fence_flags, drm_fence_object_t *fence, drm_fence_object_t **used_fence); +extern void drm_bo_add_to_lru(drm_buffer_object_t * bo, + drm_buffer_manager_t * bm); +extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals, + int no_wait); +extern int drm_bo_mem_space(drm_device_t *dev, + drm_bo_mem_reg_t *mem, + int no_wait); + + /* * Buffer object memory move helpers. * drm_bo_move.c @@ -1522,6 +1531,13 @@ extern int drm_bo_move_memcpy(drm_buffer_object_t *bo, int evict, int no_wait, drm_bo_mem_reg_t *new_mem); +extern int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo, + int evict, + int no_wait, + uint32_t fence_type, + uint32_t fence_flags, + drm_bo_mem_reg_t *new_mem); + extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); -- cgit v1.2.3 From f02f83ee08a2bb87700544a9b67f475532e84af4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 12 Feb 2007 17:47:57 +0100 Subject: Cleanup and fix support for pinned buffers. --- linux-core/drmP.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 86dcd79f..b2ce724d 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1039,6 +1039,11 @@ typedef struct drm_buffer_object{ wait_queue_head_t event_queue; struct mutex mutex; + /* For pinned buffers */ + drm_mm_node_t *pinned_node; + uint32_t pinned_mem_type; + struct list_head pinned_lru; + /* For vm */ drm_ttm_t *ttm; @@ -1509,11 +1514,10 @@ extern int drm_fence_buffer_objects(drm_file_t * priv, uint32_t fence_flags, drm_fence_object_t *fence, drm_fence_object_t **used_fence); -extern void drm_bo_add_to_lru(drm_buffer_object_t * bo, - drm_buffer_manager_t * bm); +extern void drm_bo_add_to_lru(drm_buffer_object_t * bo); extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals, int no_wait); -extern int drm_bo_mem_space(drm_device_t *dev, +extern int drm_bo_mem_space(drm_buffer_object_t *bo, drm_bo_mem_reg_t *mem, int no_wait); -- cgit v1.2.3 From 9efdae317ce01cea95f75855b175243ae858fde4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 13 Feb 2007 20:05:32 +0100 Subject: More bugfixes. Fixed memory, pinned buffers and unmappable memory now seems fully functional. --- linux-core/drmP.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index b2ce724d..c472689b 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1520,6 +1520,8 @@ extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals, extern int drm_bo_mem_space(drm_buffer_object_t *bo, drm_bo_mem_reg_t *mem, int no_wait); +extern int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags, + int no_wait, int move_unfenced); /* -- cgit v1.2.3 From e1460426b885ab656e3cda3fd3841d64260434c5 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sun, 11 Feb 2007 20:33:57 +0100 Subject: Bugzilla Bug #9457 Add refcounting of user waiters to the DRM hardware lock, so that we can use the DRM_LOCK_CONT flag more conservatively. Also add a kernel waiter refcount that if nonzero transfers the lock for the kernel context, when it is released. This is useful when waiting for idle and can be used for very simple fence object driver implementations for the new memory manager. It also resolves the AIGLX startup deadlock for the sis and the via drivers. i810, i830 still require that the hardware lock is really taken so the deadlock remains for those two. I'm not sure about ffb. Anyone familiar with that code? --- linux-core/drmP.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 9c748e6e..edc15575 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -458,6 +458,10 @@ typedef struct drm_lock_data { struct file *filp; /**< File descr of lock holder (0=kernel) */ wait_queue_head_t lock_queue; /**< Queue of blocked processes */ unsigned long lock_time; /**< Time of last lock in jiffies */ + spinlock_t spinlock; + uint32_t kernel_waiters; + uint32_t user_waiters; + int idle_has_lock; } drm_lock_data_t; /** @@ -712,6 +716,8 @@ struct drm_driver { void (*reclaim_buffers) (struct drm_device *dev, struct file * filp); void (*reclaim_buffers_locked) (struct drm_device *dev, struct file * filp); + void (*reclaim_buffers_idlelocked) (struct drm_device *dev, + struct file * filp); unsigned long (*get_map_ofs) (drm_map_t * map); unsigned long (*get_reg_ofs) (struct drm_device * dev); void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); @@ -1193,12 +1199,14 @@ extern int drm_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_unlock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context); -extern int drm_lock_free(drm_device_t * dev, - __volatile__ unsigned int *lock, unsigned int context); +extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context); +extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context); +extern void drm_idlelock_take(drm_lock_data_t *lock_data); +extern void drm_idlelock_release(drm_lock_data_t *lock_data); + /* * These are exported to drivers so that they can implement fencing using - * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. + * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. */ extern int drm_i_have_hw_lock(struct file *filp); -- cgit v1.2.3 From 04760563b88c8e94f3ae448710d1ab8b350c2e5f Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 12:39:02 +0100 Subject: Set the drm bus map type for each buffer object memory type. --- linux-core/drmP.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c472689b..e070c073 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -664,6 +664,7 @@ typedef struct drm_mem_type_manager { struct list_head lru; struct list_head pinned; uint32_t flags; + uint32_t drm_bus_maptype; unsigned long io_offset; unsigned long io_size; void *io_addr; -- cgit v1.2.3 From 5c9a7b0f9499b94856916facd110059223d243dc Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 13:31:35 +0100 Subject: Remove an intel-specific hack and replace it with a fence driver callback. --- linux-core/drmP.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index e070c073..e0afc508 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -793,10 +793,11 @@ typedef struct drm_fence_driver{ uint32_t flush_diff; uint32_t sequence_mask; int lazy_capable; - int (*emit) (struct drm_device *dev, uint32_t flags, + int (*has_irq) (struct drm_device *dev, uint32_t class, uint32_t flags); + int (*emit) (struct drm_device *dev, uint32_t class, uint32_t flags, uint32_t *breadcrumb, uint32_t *native_type); - void (*poke_flush) (struct drm_device *dev); + void (*poke_flush) (struct drm_device *dev, uint32_t class); } drm_fence_driver_t; #define _DRM_FENCE_TYPE_EXE 0x00 @@ -1464,7 +1465,8 @@ extern int drm_user_object_unref(drm_file_t *priv, uint32_t user_token, drm_obje * fence objects (drm_fence.c) */ -extern void drm_fence_handler(drm_device_t *dev, uint32_t breadcrumb, uint32_t type); +extern void drm_fence_handler(drm_device_t *dev, uint32_t class, + uint32_t sequence, uint32_t type); extern void drm_fence_manager_init(drm_device_t *dev); extern void drm_fence_manager_takedown(drm_device_t *dev); extern void drm_fence_flush_old(drm_device_t *dev, uint32_t sequence); -- cgit v1.2.3 From 8ffc1844b083e36266ebc4d1a47f6e8fe619fd05 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 14:05:40 +0100 Subject: Move fence- and buffer-object related header stuff to drm_ttm.h --- linux-core/drmP.h | 369 ------------------------------------------------------ 1 file changed, 369 deletions(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index e0afc508..c3607c3f 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -591,117 +591,9 @@ typedef struct ati_pcigart_info { drm_local_map_t mapping; } drm_ati_pcigart_info; -/* - * User space objects and their references. - */ - -#define drm_user_object_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) - -typedef enum { - drm_fence_type, - drm_buffer_type, - drm_ttm_type - - /* - * Add other user space object types here. - */ - -} drm_object_type_t; - -/* - * A user object is a structure that helps the drm give out user handles - * to kernel internal objects and to keep track of these objects so that - * they can be destroyed, for example when the user space process exits. - * Designed to be accessible using a user space 32-bit handle. - */ - -typedef struct drm_user_object{ - drm_hash_item_t hash; - struct list_head list; - drm_object_type_t type; - atomic_t refcount; - int shareable; - drm_file_t *owner; - void (*ref_struct_locked) (drm_file_t *priv, struct drm_user_object *obj, - drm_ref_t ref_action); - void (*unref)(drm_file_t *priv, struct drm_user_object *obj, - drm_ref_t unref_action); - void (*remove)(drm_file_t *priv, struct drm_user_object *obj); -} drm_user_object_t; - -/* - * A ref object is a structure which is used to - * keep track of references to user objects and to keep track of these - * references so that they can be destroyed for example when the user space - * process exits. Designed to be accessible using a pointer to the _user_ object. - */ - - -typedef struct drm_ref_object { - drm_hash_item_t hash; - struct list_head list; - atomic_t refcount; - drm_ref_t unref_action; -} drm_ref_object_t; - -struct drm_buffer_object; #include "drm_ttm.h" -#define _DRM_FLAG_MEMTYPE_FIXED 0x00000001 /* Fixed (on-card) PCI memory */ -#define _DRM_FLAG_MEMTYPE_MAPPABLE 0x00000002 /* Memory mappable */ -#define _DRM_FLAG_MEMTYPE_CACHED 0x00000004 /* Cached binding */ -#define _DRM_FLAG_NEEDS_IOREMAP 0x00000008 /* Fixed memory needs ioremap - before kernel access. */ -#define _DRM_FLAG_MEMTYPE_CMA 0x00000010 /* Can't map aperture */ -#define _DRM_FLAG_MEMTYPE_CSELECT 0x00000020 /* Select caching */ - - -typedef struct drm_mem_type_manager { - int has_type; - int use_type; - drm_mm_t manager; - struct list_head lru; - struct list_head pinned; - uint32_t flags; - uint32_t drm_bus_maptype; - unsigned long io_offset; - unsigned long io_size; - void *io_addr; -} drm_mem_type_manager_t; - -typedef struct drm_bo_mem_reg { - drm_mm_node_t *mm_node; - unsigned long size; - unsigned long num_pages; - uint32_t page_alignment; - uint32_t mem_type; - uint32_t flags; - uint32_t mask; -} drm_bo_mem_reg_t; - -/* - * buffer object driver - */ - -typedef struct drm_bo_driver{ - const uint32_t *mem_type_prio; - const uint32_t *mem_busy_prio; - uint32_t num_mem_type_prio; - uint32_t num_mem_busy_prio; - drm_ttm_backend_t *(*create_ttm_backend_entry) - (struct drm_device *dev); - int (*fence_type)(uint32_t flags, uint32_t *class, uint32_t *type); - int (*invalidate_caches)(struct drm_device *dev, uint32_t flags); - int (*init_mem_type)(struct drm_device *dev, uint32_t type, - drm_mem_type_manager_t *man); - uint32_t (*evict_flags) (struct drm_device *dev, uint32_t type); - int (*move)(struct drm_buffer_object *bo, - int evict, int no_wait, - struct drm_bo_mem_reg *new_mem); -} drm_bo_driver_t; - - /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -787,61 +679,6 @@ typedef struct drm_head { } drm_head_t; -typedef struct drm_fence_driver{ - int no_types; - uint32_t wrap_diff; - uint32_t flush_diff; - uint32_t sequence_mask; - int lazy_capable; - int (*has_irq) (struct drm_device *dev, uint32_t class, uint32_t flags); - int (*emit) (struct drm_device *dev, uint32_t class, uint32_t flags, - uint32_t *breadcrumb, - uint32_t *native_type); - void (*poke_flush) (struct drm_device *dev, uint32_t class); -} drm_fence_driver_t; - -#define _DRM_FENCE_TYPE_EXE 0x00 - -typedef struct drm_fence_manager{ - int initialized; - rwlock_t lock; - - /* - * The list below should be maintained in sequence order and - * access is protected by the above spinlock. - */ - - struct list_head ring; - struct list_head *fence_types[32]; - volatile uint32_t pending_flush; - wait_queue_head_t fence_queue; - int pending_exe_flush; - uint32_t last_exe_flush; - uint32_t exe_flush_sequence; - atomic_t count; -} drm_fence_manager_t; - -typedef struct drm_buffer_manager{ - struct mutex init_mutex; - struct mutex evict_mutex; - int nice_mode; - int initialized; - drm_file_t *last_to_validate; - drm_mem_type_manager_t man[DRM_BO_MEM_TYPES]; - struct list_head unfenced; - struct list_head ddestroy; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) - struct work_struct wq; -#else - struct delayed_work wq; -#endif - uint32_t fence_type; - unsigned long cur_pages; - atomic_t count; -} drm_buffer_manager_t; - - - /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. @@ -996,77 +833,6 @@ typedef struct drm_agp_ttm_priv { } drm_agp_ttm_priv; #endif -typedef struct drm_fence_object{ - drm_user_object_t base; - atomic_t usage; - - /* - * The below three fields are protected by the fence manager spinlock. - */ - - struct list_head ring; - int class; - uint32_t native_type; - uint32_t type; - uint32_t signaled; - uint32_t sequence; - uint32_t flush_mask; - uint32_t submitted_flush; -} drm_fence_object_t; - - -typedef struct drm_buffer_object{ - drm_device_t *dev; - drm_user_object_t base; - - /* - * If there is a possibility that the usage variable is zero, - * then dev->struct_mutext should be locked before incrementing it. - */ - - atomic_t usage; - unsigned long buffer_start; - drm_bo_type_t type; - unsigned long offset; - atomic_t mapped; - drm_bo_mem_reg_t mem; - - struct list_head lru; - struct list_head ddestroy; - - uint32_t fence_type; - uint32_t fence_class; - drm_fence_object_t *fence; - uint32_t priv_flags; - wait_queue_head_t event_queue; - struct mutex mutex; - - /* For pinned buffers */ - drm_mm_node_t *pinned_node; - uint32_t pinned_mem_type; - struct list_head pinned_lru; - - /* For vm */ - - drm_ttm_t *ttm; - drm_map_list_t map_list; - uint32_t memory_type; - unsigned long bus_offset; - uint32_t vm_flags; - void *iomap; - - -#ifdef DRM_ODD_MM_COMPAT - /* dev->struct_mutex only protected. */ - struct list_head vma_list; - struct list_head p_mm_list; -#endif - -} drm_buffer_object_t; - -#define _DRM_BO_FLAG_UNFENCED 0x00000001 -#define _DRM_BO_FLAG_EVICTED 0x00000002 - static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature) @@ -1408,144 +1174,9 @@ static inline drm_mm_t *drm_get_mm(drm_mm_node_t *block) } -/* - * User space object bookkeeping (drm_object.c) - */ - -/* - * Must be called with the struct_mutex held. - */ - -extern int drm_add_user_object(drm_file_t *priv, drm_user_object_t *item, - -/* - * Must be called with the struct_mutex held. - */ - int shareable); -extern drm_user_object_t *drm_lookup_user_object(drm_file_t *priv, uint32_t key); - -/* - * Must be called with the struct_mutex held. - * If "item" has been obtained by a call to drm_lookup_user_object. You may not - * release the struct_mutex before calling drm_remove_ref_object. - * This function may temporarily release the struct_mutex. - */ - -extern int drm_remove_user_object(drm_file_t *priv, drm_user_object_t *item); -/* - * Must be called with the struct_mutex held. May temporarily release it. - */ -extern int drm_add_ref_object(drm_file_t *priv, drm_user_object_t *referenced_object, - drm_ref_t ref_action); - -/* - * Must be called with the struct_mutex held. - */ - -drm_ref_object_t *drm_lookup_ref_object(drm_file_t *priv, - drm_user_object_t *referenced_object, - drm_ref_t ref_action); -/* - * Must be called with the struct_mutex held. - * If "item" has been obtained by a call to drm_lookup_ref_object. You may not - * release the struct_mutex before calling drm_remove_ref_object. - * This function may temporarily release the struct_mutex. - */ - -extern void drm_remove_ref_object(drm_file_t *priv, drm_ref_object_t *item); -extern int drm_user_object_ref(drm_file_t *priv, uint32_t user_token, drm_object_type_t type, - drm_user_object_t **object); -extern int drm_user_object_unref(drm_file_t *priv, uint32_t user_token, drm_object_type_t type); - - - -/* - * fence objects (drm_fence.c) - */ - -extern void drm_fence_handler(drm_device_t *dev, uint32_t class, - uint32_t sequence, uint32_t type); -extern void drm_fence_manager_init(drm_device_t *dev); -extern void drm_fence_manager_takedown(drm_device_t *dev); -extern void drm_fence_flush_old(drm_device_t *dev, uint32_t sequence); -extern int drm_fence_object_flush(drm_device_t * dev, - volatile drm_fence_object_t * fence, - uint32_t type); -extern int drm_fence_object_signaled(volatile drm_fence_object_t * fence, - uint32_t type); -extern void drm_fence_usage_deref_locked(drm_device_t * dev, - drm_fence_object_t * fence); -extern void drm_fence_usage_deref_unlocked(drm_device_t * dev, - drm_fence_object_t * fence); -extern int drm_fence_object_wait(drm_device_t * dev, - volatile drm_fence_object_t * fence, - int lazy, int ignore_signals, uint32_t mask); -extern int drm_fence_object_create(drm_device_t *dev, uint32_t type, - uint32_t fence_flags, - drm_fence_object_t **c_fence); -extern int drm_fence_add_user_object(drm_file_t *priv, - drm_fence_object_t *fence, - int shareable); - - - - - -extern int drm_fence_ioctl(DRM_IOCTL_ARGS); - -/* - * buffer objects (drm_bo.c) - */ - -extern int drm_bo_ioctl(DRM_IOCTL_ARGS); -extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS); -extern int drm_bo_driver_finish(drm_device_t *dev); -extern int drm_bo_driver_init(drm_device_t *dev); -extern int drm_bo_pci_offset(drm_device_t *dev, - drm_bo_mem_reg_t *mem, - unsigned long *bus_base, - unsigned long *bus_offset, - unsigned long *bus_size); -extern int drm_mem_reg_is_pci(drm_device_t *dev, drm_bo_mem_reg_t *mem); - - -extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo); -extern int drm_fence_buffer_objects(drm_file_t * priv, - struct list_head *list, - uint32_t fence_flags, - drm_fence_object_t *fence, - drm_fence_object_t **used_fence); -extern void drm_bo_add_to_lru(drm_buffer_object_t * bo); -extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals, - int no_wait); -extern int drm_bo_mem_space(drm_buffer_object_t *bo, - drm_bo_mem_reg_t *mem, - int no_wait); -extern int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags, - int no_wait, int move_unfenced); - - -/* - * Buffer object memory move helpers. - * drm_bo_move.c - */ -extern int drm_bo_move_ttm(drm_buffer_object_t *bo, - int evict, - int no_wait, - drm_bo_mem_reg_t *new_mem); -extern int drm_bo_move_memcpy(drm_buffer_object_t *bo, - int evict, - int no_wait, - drm_bo_mem_reg_t *new_mem); -extern int drm_bo_move_accel_cleanup(drm_buffer_object_t *bo, - int evict, - int no_wait, - uint32_t fence_type, - uint32_t fence_flags, - drm_bo_mem_reg_t *new_mem); extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev); extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev); -- cgit v1.2.3 From 1345076c8f93936563cd5c15588b1d76d87969d3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 14:10:10 +0100 Subject: Rename drm_ttm.h to drm_objects.h Fix up some header incompatibilities in drm_fence.c caused by the previous commit. --- linux-core/drmP.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/drmP.h') diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c3607c3f..0bf71c49 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -592,7 +592,7 @@ typedef struct ati_pcigart_info { } drm_ati_pcigart_info; -#include "drm_ttm.h" +#include "drm_objects.h" /** * DRM driver structure. This structure represent the common code for -- cgit v1.2.3