From 11f9e404fb66927146de30227fa05c5485aa1726 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 21 Aug 2006 17:02:44 +0200 Subject: Avoid using vmalloc for small hash tables. --- linux-core/drm_hashtab.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'linux-core/drm_hashtab.c') diff --git a/linux-core/drm_hashtab.c b/linux-core/drm_hashtab.c index 48061139..40599227 100644 --- a/linux-core/drm_hashtab.c +++ b/linux-core/drm_hashtab.c @@ -43,7 +43,16 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order) ht->size = 1 << order; ht->order = order; ht->fill = 0; - ht->table = vmalloc(ht->size*sizeof(*ht->table)); + ht->table = NULL; + ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > 4*PAGE_SIZE); + if (!ht->use_vmalloc) { + ht->table = drm_calloc(ht->size, sizeof(*ht->table), + DRM_MEM_HASHTAB); + } + if (!ht->table) { + ht->use_vmalloc = 1; + ht->table = vmalloc(ht->size*sizeof(*ht->table)); + } if (!ht->table) { DRM_ERROR("Out of memory for hash table\n"); return -ENOMEM; @@ -183,7 +192,11 @@ int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) void drm_ht_remove(drm_open_hash_t *ht) { if (ht->table) { - vfree(ht->table); + if (ht->use_vmalloc) + vfree(ht->table); + else + drm_free(ht->table, ht->size*sizeof(*ht->table), + DRM_MEM_HASHTAB); ht->table = NULL; } } -- cgit v1.2.3 From 8dfe917cb26bbeddda0e1b52060d8dce188468f3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 23 Aug 2006 11:21:33 +0200 Subject: Fix hashtab implementation leaking illegal error codes to user space. (Reported by Dave Airlie) --- linux-core/drm_hashtab.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux-core/drm_hashtab.c') diff --git a/linux-core/drm_hashtab.c b/linux-core/drm_hashtab.c index 48061139..a0b2d680 100644 --- a/linux-core/drm_hashtab.c +++ b/linux-core/drm_hashtab.c @@ -106,7 +106,7 @@ int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item) hlist_for_each(list, h_list) { entry = hlist_entry(list, drm_hash_item_t, head); if (entry->key == key) - return -1; + return -EINVAL; if (entry->key > key) break; parent = list; @@ -154,7 +154,7 @@ int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, list = drm_ht_find_key(ht, key); if (!list) - return -1; + return -EINVAL; *item = hlist_entry(list, drm_hash_item_t, head); return 0; @@ -170,7 +170,7 @@ int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key) ht->fill--; return 0; } - return -1; + return -EINVAL; } int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) -- 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_hashtab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/drm_hashtab.c') diff --git a/linux-core/drm_hashtab.c b/linux-core/drm_hashtab.c index 63ee5f91..3a2aa80e 100644 --- a/linux-core/drm_hashtab.c +++ b/linux-core/drm_hashtab.c @@ -44,7 +44,7 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order) ht->order = order; ht->fill = 0; ht->table = NULL; - ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > 4*PAGE_SIZE); + ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); if (!ht->use_vmalloc) { ht->table = drm_calloc(ht->size, sizeof(*ht->table), DRM_MEM_HASHTAB); -- 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_hashtab.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'linux-core/drm_hashtab.c') diff --git a/linux-core/drm_hashtab.c b/linux-core/drm_hashtab.c index 3a2aa80e..6f17e114 100644 --- a/linux-core/drm_hashtab.c +++ b/linux-core/drm_hashtab.c @@ -36,7 +36,7 @@ #include "drm_hashtab.h" #include -int drm_ht_create(drm_open_hash_t *ht, unsigned int order) +int drm_ht_create(drm_open_hash_t * ht, unsigned int order) { unsigned int i; @@ -46,24 +46,24 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order) ht->table = NULL; ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); if (!ht->use_vmalloc) { - ht->table = drm_calloc(ht->size, sizeof(*ht->table), + ht->table = drm_calloc(ht->size, sizeof(*ht->table), DRM_MEM_HASHTAB); - } + } if (!ht->table) { ht->use_vmalloc = 1; - ht->table = vmalloc(ht->size*sizeof(*ht->table)); - } + ht->table = vmalloc(ht->size * sizeof(*ht->table)); + } if (!ht->table) { DRM_ERROR("Out of memory for hash table\n"); return -ENOMEM; } - for (i=0; i< ht->size; ++i) { + for (i = 0; i < ht->size; ++i) { INIT_HLIST_HEAD(&ht->table[i]); } return 0; } -void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key) +void drm_ht_verbose_list(drm_open_hash_t * ht, unsigned long key) { drm_hash_item_t *entry; struct hlist_head *h_list; @@ -80,7 +80,7 @@ void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key) } } -static struct hlist_node *drm_ht_find_key(drm_open_hash_t *ht, +static struct hlist_node *drm_ht_find_key(drm_open_hash_t * ht, unsigned long key) { drm_hash_item_t *entry; @@ -100,8 +100,7 @@ static struct hlist_node *drm_ht_find_key(drm_open_hash_t *ht, return NULL; } - -int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item) +int drm_ht_insert_item(drm_open_hash_t * ht, drm_hash_item_t * item) { drm_hash_item_t *entry; struct hlist_head *h_list; @@ -132,7 +131,7 @@ int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item) * Just insert an item and return any "bits" bit key that hasn't been * used before. */ -int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, +int drm_ht_just_insert_please(drm_open_hash_t * ht, drm_hash_item_t * item, unsigned long seed, int bits, int shift, unsigned long add) { @@ -147,7 +146,7 @@ int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, ret = drm_ht_insert_item(ht, item); if (ret) unshifted_key = (unshifted_key + 1) & mask; - } while(ret && (unshifted_key != first)); + } while (ret && (unshifted_key != first)); if (ret) { DRM_ERROR("Available key bit space exhausted\n"); @@ -156,8 +155,8 @@ int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, return 0; } -int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, - drm_hash_item_t **item) +int drm_ht_find_item(drm_open_hash_t * ht, unsigned long key, + drm_hash_item_t ** item) { struct hlist_node *list; @@ -169,7 +168,7 @@ int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, return 0; } -int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key) +int drm_ht_remove_key(drm_open_hash_t * ht, unsigned long key) { struct hlist_node *list; @@ -182,22 +181,21 @@ int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key) return -EINVAL; } -int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) +int drm_ht_remove_item(drm_open_hash_t * ht, drm_hash_item_t * item) { hlist_del_init(&item->head); ht->fill--; return 0; } -void drm_ht_remove(drm_open_hash_t *ht) +void drm_ht_remove(drm_open_hash_t * ht) { if (ht->table) { - if (ht->use_vmalloc) + if (ht->use_vmalloc) vfree(ht->table); else - drm_free(ht->table, ht->size*sizeof(*ht->table), + drm_free(ht->table, ht->size * sizeof(*ht->table), DRM_MEM_HASHTAB); ht->table = NULL; } } - -- cgit v1.2.3