From 11f51a9a877d1231551e8c6482a6f70daf380cdd Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 1 Sep 2006 15:41:55 +0200 Subject: Bugfixes, Memory allocation optimizations. Buffer manager takedown. --- linux-core/drm_mm.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'linux-core/drm_mm.c') diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index 617526bd..6e2da81a 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -42,6 +42,9 @@ */ #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) @@ -57,7 +60,9 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, parent->free = 0; return parent; } else { - child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); + + child = (drm_mm_node_t *) kmem_cache_alloc(mm_cache, + GFP_KERNEL); if (!child) return NULL; @@ -105,8 +110,8 @@ 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); - drm_free(next_node, sizeof(*next_node), - DRM_MEM_MM); + kmem_cache_free(mm_cache, next_node); + } else { next_node->size += cur->size; next_node->start = cur->start; @@ -119,7 +124,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); - drm_free(cur, sizeof(*cur), DRM_MEM_MM); + kmem_cache_free(mm_cache, cur); } } @@ -154,13 +159,34 @@ 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; + + return (head->next->next == head); +} + 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 *) drm_alloc(sizeof(*child), DRM_MEM_MM); + + + child = (drm_mm_node_t *) kmem_cache_alloc(mm_cache, GFP_KERNEL); + if (!child) return -ENOMEM; @@ -194,8 +220,7 @@ void drm_mm_takedown(drm_mm_t * mm) list_del(&entry->fl_entry); list_del(&entry->ml_entry); - - drm_free(entry, sizeof(*entry), DRM_MEM_MM); + kmem_cache_free(mm_cache, entry); } EXPORT_SYMBOL(drm_mm_takedown); -- cgit v1.2.3 From a6b8e3eaf49044e135a0b9288192525f301458d5 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 4 Sep 2006 16:57:20 +0200 Subject: Make memory caches global so that they can be used with multiple heads. --- linux-core/drm_mm.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'linux-core/drm_mm.c') 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); -- cgit v1.2.3 From db5c671e86c3db8c99ce5a4954632248e6f849aa Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 11:28:48 +0200 Subject: Remove the memory manager parameter from the put_block function, as this makes the client code a lot cleaner. Prepare buffer manager for lock and unlock calls. --- linux-core/drm_mm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'linux-core/drm_mm.c') diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index debac9d9..ef8bd7e9 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -70,6 +70,7 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, child->free = 0; child->size = size; child->start = parent->start; + child->mm = parent->mm; list_add_tail(&child->ml_entry, &parent->ml_entry); parent->size -= size; @@ -83,9 +84,10 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, * Otherwise add to the free stack. */ -void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) +void drm_mm_put_block(drm_mm_node_t * cur) { + drm_mm_t *mm = cur->mm; drm_mm_node_t *list_root = &mm->root_node; struct list_head *cur_head = &cur->ml_entry; struct list_head *root_head = &list_root->ml_entry; @@ -183,6 +185,7 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) child->start = start; child->size = size; child->free = 1; + child->mm = mm; list_add(&child->fl_entry, &mm->root_node.fl_entry); list_add(&child->ml_entry, &mm->root_node.ml_entry); -- cgit v1.2.3 From d515936ea7f98f6aaa9217699796beadef9d664b Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 19:40:57 +0200 Subject: Add memory usage accounting to avoid DOS problems. --- linux-core/drm_mm.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'linux-core/drm_mm.c') diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index ef8bd7e9..6ab13af3 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -59,8 +59,9 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, return parent; } else { - child = (drm_mm_node_t *) kmem_cache_alloc(drm_cache.mm, - GFP_KERNEL); + child = (drm_mm_node_t *) + drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), + GFP_KERNEL); if (!child) return NULL; @@ -110,8 +111,9 @@ void drm_mm_put_block(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(drm_cache.mm, next_node); - + drm_ctl_cache_free(drm_cache.mm, + sizeof(*next_node), + next_node); } else { next_node->size += cur->size; next_node->start = cur->start; @@ -124,7 +126,7 @@ void drm_mm_put_block(drm_mm_node_t * cur) list_add(&cur->fl_entry, &list_root->fl_entry); } else { list_del(&cur->ml_entry); - kmem_cache_free(drm_cache.mm, cur); + drm_ctl_cache_free(drm_cache.mm, sizeof(*cur), cur); } } @@ -174,7 +176,8 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) INIT_LIST_HEAD(&mm->root_node.fl_entry); - child = (drm_mm_node_t *) kmem_cache_alloc(drm_cache.mm, GFP_KERNEL); + child = (drm_mm_node_t *) + drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), GFP_KERNEL); if (!child) return -ENOMEM; @@ -210,7 +213,7 @@ void drm_mm_takedown(drm_mm_t * mm) list_del(&entry->fl_entry); list_del(&entry->ml_entry); - kmem_cache_free(drm_cache.mm, entry); + drm_ctl_cache_free(drm_cache.mm, sizeof(*entry), entry); } EXPORT_SYMBOL(drm_mm_takedown); -- cgit v1.2.3 From 89b944179856fadf8667587eff142129c2c6b826 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Oct 2006 19:57:06 +0200 Subject: Lindent. --- linux-core/drm_mm.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'linux-core/drm_mm.c') diff --git a/linux-core/drm_mm.c b/linux-core/drm_mm.c index 6ab13af3..4af33bde 100644 --- a/linux-core/drm_mm.c +++ b/linux-core/drm_mm.c @@ -59,9 +59,9 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, return parent; } else { - child = (drm_mm_node_t *) - drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), - GFP_KERNEL); + child = (drm_mm_node_t *) + drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), + GFP_KERNEL); if (!child) return NULL; @@ -111,8 +111,8 @@ void drm_mm_put_block(drm_mm_node_t * cur) prev_node->size += next_node->size; list_del(&next_node->ml_entry); list_del(&next_node->fl_entry); - drm_ctl_cache_free(drm_cache.mm, - sizeof(*next_node), + drm_ctl_cache_free(drm_cache.mm, + sizeof(*next_node), next_node); } else { next_node->size += cur->size; @@ -161,9 +161,9 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, return best; } -int drm_mm_clean(drm_mm_t *mm) +int drm_mm_clean(drm_mm_t * mm) { - struct list_head *head = &mm->root_node.ml_entry; + struct list_head *head = &mm->root_node.ml_entry; return (head->next->next == head); } @@ -175,9 +175,8 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) INIT_LIST_HEAD(&mm->root_node.ml_entry); INIT_LIST_HEAD(&mm->root_node.fl_entry); - - child = (drm_mm_node_t *) - drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), GFP_KERNEL); + child = (drm_mm_node_t *) + drm_ctl_cache_alloc(drm_cache.mm, sizeof(*child), GFP_KERNEL); if (!child) return -ENOMEM; -- cgit v1.2.3