diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c6646212..23766373 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -745,6 +745,18 @@ typedef struct drm_head { struct class_device *dev_class; } drm_head_t; +typedef struct drm_cache { + + /* + * Memory caches + */ + + kmem_cache_t *mm; + kmem_cache_t *fence_object; + kmem_cache_t *ref_object; +} drm_cache_t; + + typedef struct drm_fence_driver{ int no_types; @@ -926,12 +938,6 @@ typedef struct drm_device { drm_fence_manager_t fm; drm_buffer_manager_t bm; - /* - * Memory caches - */ - kmem_cache_t *mm_cache; - kmem_cache_t *fence_object_cache; - } drm_device_t; #if __OS_HAS_AGP @@ -1254,6 +1260,7 @@ extern int drm_put_head(drm_head_t * head); extern unsigned int drm_debug; /* 1 to enable debug output */ extern unsigned int drm_cards_limit; extern drm_head_t **drm_heads; +extern drm_cache_t drm_cache; extern struct drm_sysfs_class *drm_class; extern struct proc_dir_entry *drm_proc_root; @@ -1302,7 +1309,6 @@ extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, unsigned alignment, int best_match); extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); extern void drm_mm_takedown(drm_mm_t *mm); -extern void drm_mm_set_cache(kmem_cache_t *cache); extern int drm_mm_clean(drm_mm_t *mm); /* diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 368ec0c5..7f50bacf 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -91,7 +91,8 @@ static void drm_bo_destroy_locked(drm_device_t * dev, drm_buffer_object_t * bo) drm_buffer_manager_t *bm = &dev->bm; - BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED); + DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED); + if (bo->fence) { if (!drm_fence_object_signaled(bo->fence, bo->fence_flags)) { drm_fence_object_flush(dev, bo->fence, bo->fence_flags); @@ -229,7 +230,7 @@ int drm_fence_buffer_objects(drm_file_t * priv, goto out; } } else { - fence = kmem_cache_alloc(dev->fence_object_cache, GFP_KERNEL); + fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL); if (!fence) { ret = -ENOMEM; @@ -239,7 +240,7 @@ int drm_fence_buffer_objects(drm_file_t * priv, ret = drm_fence_object_init(dev, fence_flags, 1, fence); if (ret) { - kmem_cache_free(dev->fence_object_cache, fence); + kmem_cache_free(drm_cache.fence_object, fence); goto out; } } @@ -1124,8 +1125,9 @@ static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo, bo->ttm_object = to; ttm = drm_ttm_from_object(to); ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT, - bo->num_pages, - bo->mask & DRM_BO_FLAG_BIND_CACHED, + bo->num_pages,1, + + /* bo->mask & DRM_BO_FLAG_BIND_CACHED,*/ &bo->ttm_region); if (ret) { drm_ttm_object_deref_unlocked(dev, to); diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 8a1dcab9..bca7b868 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -129,27 +129,6 @@ static drm_ioctl_desc_t drm_ioctls[] = { #define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) -static void drm_free_mem_cache(kmem_cache_t *cache, - const char *name) -{ - if (!cache) - return; - if (kmem_cache_destroy(cache)) { - DRM_ERROR("Warning! DRM is leaking %s memory.\n", - name); - } -} - -static void drm_free_memory_caches(drm_device_t *dev) -{ - - drm_free_mem_cache(dev->fence_object_cache, "fence object"); - dev->fence_object_cache = NULL; - drm_mm_set_cache(NULL); - drm_free_mem_cache(dev->mm_cache, "memory manager block"); - dev->mm_cache = NULL; -} - /** * Take down the DRM device. @@ -378,7 +357,6 @@ static void drm_cleanup(drm_device_t * dev) } drm_lastclose(dev); - drm_free_memory_caches(dev); drm_fence_manager_takedown(dev); if (dev->maplist) { @@ -450,10 +428,67 @@ static struct file_operations drm_stub_fops = { .open = drm_stub_open }; +static int drm_create_memory_caches(void) +{ + drm_cache.mm = kmem_cache_create("drm_mm_node_t", + sizeof(drm_mm_node_t), + 0, + SLAB_HWCACHE_ALIGN, + NULL,NULL); + if (!drm_cache.mm) + return -ENOMEM; + + drm_cache.fence_object= kmem_cache_create("drm_fence_object_t", + sizeof(drm_fence_object_t), + 0, + SLAB_HWCACHE_ALIGN, + NULL,NULL); + if (!drm_cache.ref_object) + return -ENOMEM; + + drm_cache.ref_object= kmem_cache_create("drm_ref_object_t", + sizeof(drm_ref_object_t), + 0, + SLAB_HWCACHE_ALIGN, + NULL,NULL); + if (!drm_cache.ref_object) + return -ENOMEM; + + return 0; +} + +static void drm_free_mem_cache(kmem_cache_t *cache, + const char *name) +{ + if (!cache) + return; + if (kmem_cache_destroy(cache)) { + DRM_ERROR("Warning! DRM is leaking %s memory.\n", + name); + } +} + +static void drm_free_memory_caches(void ) +{ + + drm_free_mem_cache(drm_cache.ref_object, "ref object"); + drm_cache.ref_object = NULL; + drm_free_mem_cache(drm_cache.fence_object, "fence object"); + drm_cache.fence_object = NULL; + drm_free_mem_cache(drm_cache.mm, "memory manager block"); + drm_cache.mm = NULL; +} + + static int __init drm_core_init(void) { - int ret = -ENOMEM; + int ret; + + ret = drm_create_memory_caches(); + if (ret) + goto err_p1; + ret = -ENOMEM; drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1); drm_heads = drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB); @@ -494,6 +529,7 @@ err_p1: static void __exit drm_core_exit(void) { + drm_free_memory_caches(); remove_proc_entry("dri", NULL); drm_sysfs_destroy(drm_class); diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index b4d13621..622cad10 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -172,7 +172,7 @@ void drm_fence_usage_deref_locked(drm_device_t * dev, { if (atomic_dec_and_test(&fence->usage)) { drm_fence_unring(dev, &fence->ring); - kmem_cache_free(dev->fence_object_cache, fence); + kmem_cache_free(drm_cache.fence_object, fence); } } @@ -183,7 +183,7 @@ void drm_fence_usage_deref_unlocked(drm_device_t * dev, mutex_lock(&dev->struct_mutex); if (atomic_read(&fence->usage) == 0) { drm_fence_unring(dev, &fence->ring); - kmem_cache_free(dev->fence_object_cache, fence); + kmem_cache_free(drm_cache.fence_object, fence); } mutex_unlock(&dev->struct_mutex); } @@ -426,7 +426,7 @@ static int drm_fence_object_create(drm_file_t * priv, uint32_t type, int ret; drm_fence_object_t *fence; - fence = kmem_cache_alloc(dev->fence_object_cache, GFP_KERNEL); + fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL); if (!fence) return -ENOMEM; ret = drm_fence_object_init(dev, type, emit, fence); diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index 6e2da81a..debac9d9 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -44,8 +44,6 @@ #include "drmP.h" #include -static kmem_cache_t *mm_cache = NULL; - drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, unsigned long size, unsigned alignment) { @@ -61,7 +59,7 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, return parent; } else { - child = (drm_mm_node_t *) kmem_cache_alloc(mm_cache, + child = (drm_mm_node_t *) kmem_cache_alloc(drm_cache.mm, GFP_KERNEL); if (!child) return NULL; @@ -110,7 +108,7 @@ void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) prev_node->size += next_node->size; list_del(&next_node->ml_entry); list_del(&next_node->fl_entry); - kmem_cache_free(mm_cache, next_node); + kmem_cache_free(drm_cache.mm, next_node); } else { next_node->size += cur->size; @@ -124,7 +122,7 @@ void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) list_add(&cur->fl_entry, &list_root->fl_entry); } else { list_del(&cur->ml_entry); - kmem_cache_free(mm_cache, cur); + kmem_cache_free(drm_cache.mm, cur); } } @@ -159,11 +157,6 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, return best; } -void drm_mm_set_cache(kmem_cache_t *cache) -{ - mm_cache = cache; -} - int drm_mm_clean(drm_mm_t *mm) { struct list_head *head = &mm->root_node.ml_entry; @@ -175,17 +168,11 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) { drm_mm_node_t *child; - if (!mm_cache) { - DRM_ERROR("Memory manager memory cache " - "is not initialized.\n"); - return -EINVAL; - } - INIT_LIST_HEAD(&mm->root_node.ml_entry); INIT_LIST_HEAD(&mm->root_node.fl_entry); - child = (drm_mm_node_t *) kmem_cache_alloc(mm_cache, GFP_KERNEL); + child = (drm_mm_node_t *) kmem_cache_alloc(drm_cache.mm, GFP_KERNEL); if (!child) return -ENOMEM; @@ -220,7 +207,7 @@ void drm_mm_takedown(drm_mm_t * mm) list_del(&entry->fl_entry); list_del(&entry->ml_entry); - kmem_cache_free(mm_cache, entry); + kmem_cache_free(drm_cache.mm, entry); } EXPORT_SYMBOL(drm_mm_takedown); diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 2d0f1d24..c4f33813 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -54,29 +54,11 @@ drm_head_t **drm_heads; struct drm_sysfs_class *drm_class; struct proc_dir_entry *drm_proc_root; - -static int drm_create_memory_caches(drm_device_t *dev) -{ - dev->mm_cache = kmem_cache_create("drm_mm_node_t", - sizeof(drm_mm_node_t), - 0, - SLAB_HWCACHE_ALIGN, - NULL,NULL); - if (!dev->mm_cache) - return -ENOMEM; - - drm_mm_set_cache(dev->mm_cache); - dev->fence_object_cache = kmem_cache_create("drm_fence_object_t", - sizeof(drm_fence_object_t), - 0, - SLAB_HWCACHE_ALIGN, - NULL,NULL); - if (!dev->fence_object_cache) - return -ENOMEM; - - return 0; -} - +drm_cache_t drm_cache = +{ .mm = NULL, + .fence_object = NULL, + .ref_object = NULL +}; static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, const struct pci_device_id *ent, @@ -151,12 +133,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, goto error_out_unreg; } - retcode = drm_create_memory_caches(dev); - if (retcode) { - DRM_ERROR("Failed creating memory caches\n"); - goto error_out_unreg; - } - drm_fence_manager_init(dev); return 0;