mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-20 11:34:57 +02:00
Import ipset-2.3.1a-20080617
This commit is contained in:
143
extensions/ipset/ip_set_malloc.h
Normal file
143
extensions/ipset/ip_set_malloc.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef _IP_SET_MALLOC_H
|
||||
#define _IP_SET_MALLOC_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
static size_t max_malloc_size = 0, max_page_size = 0;
|
||||
|
||||
static inline bool init_max_page_size(void)
|
||||
{
|
||||
size_t page_size = 0;
|
||||
|
||||
#define CACHE(x) if (max_page_size == 0 || x < max_page_size) \
|
||||
page_size = x;
|
||||
#include <linux/kmalloc_sizes.h>
|
||||
#undef CACHE
|
||||
if (page_size) {
|
||||
if (max_malloc_size == 0)
|
||||
max_malloc_size = page_size;
|
||||
|
||||
max_page_size = page_size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct harray {
|
||||
size_t max_elements;
|
||||
void *arrays[0];
|
||||
};
|
||||
|
||||
static inline void *
|
||||
__harray_malloc(size_t hashsize, size_t typesize, int flags)
|
||||
{
|
||||
struct harray *harray;
|
||||
size_t max_elements, size, i, j;
|
||||
|
||||
BUG_ON(max_page_size == 0);
|
||||
|
||||
if (typesize > max_page_size)
|
||||
return NULL;
|
||||
|
||||
max_elements = max_page_size/typesize;
|
||||
size = hashsize/max_elements;
|
||||
if (hashsize % max_elements)
|
||||
size++;
|
||||
|
||||
/* Last pointer signals end of arrays */
|
||||
harray = kmalloc(sizeof(struct harray) + (size + 1) * sizeof(void *),
|
||||
flags);
|
||||
|
||||
if (!harray)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < size - 1; i++) {
|
||||
harray->arrays[i] = kmalloc(max_elements * typesize, flags);
|
||||
if (!harray->arrays[i])
|
||||
goto undo;
|
||||
memset(harray->arrays[i], 0, max_elements * typesize);
|
||||
}
|
||||
harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize,
|
||||
flags);
|
||||
if (!harray->arrays[i])
|
||||
goto undo;
|
||||
memset(harray->arrays[i], 0, (hashsize - i * max_elements) * typesize);
|
||||
|
||||
harray->max_elements = max_elements;
|
||||
harray->arrays[size] = NULL;
|
||||
|
||||
return (void *)harray;
|
||||
|
||||
undo:
|
||||
for (j = 0; j < i; j++) {
|
||||
kfree(harray->arrays[j]);
|
||||
}
|
||||
kfree(harray);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
harray_malloc(size_t hashsize, size_t typesize, int flags)
|
||||
{
|
||||
void *harray;
|
||||
|
||||
do {
|
||||
harray = __harray_malloc(hashsize, typesize, flags|__GFP_NOWARN);
|
||||
} while (harray == NULL && init_max_page_size());
|
||||
|
||||
return harray;
|
||||
}
|
||||
|
||||
static inline void harray_free(void *h)
|
||||
{
|
||||
struct harray *harray = (struct harray *) h;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; harray->arrays[i] != NULL; i++)
|
||||
kfree(harray->arrays[i]);
|
||||
kfree(harray);
|
||||
}
|
||||
|
||||
static inline void harray_flush(void *h, size_t hashsize, size_t typesize)
|
||||
{
|
||||
struct harray *harray = (struct harray *) h;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; harray->arrays[i+1] != NULL; i++)
|
||||
memset(harray->arrays[i], 0, harray->max_elements * typesize);
|
||||
memset(harray->arrays[i], 0,
|
||||
(hashsize - i * harray->max_elements) * typesize);
|
||||
}
|
||||
|
||||
#define HARRAY_ELEM(h, type, which) \
|
||||
({ \
|
||||
struct harray *__h = (struct harray *)(h); \
|
||||
((type)((__h)->arrays[(which)/(__h)->max_elements]) \
|
||||
+ (which)%(__h)->max_elements); \
|
||||
})
|
||||
|
||||
/* General memory allocation and deallocation */
|
||||
static inline void * ip_set_malloc(size_t bytes)
|
||||
{
|
||||
BUG_ON(max_malloc_size == 0);
|
||||
|
||||
if (bytes > max_malloc_size)
|
||||
return vmalloc(bytes);
|
||||
else
|
||||
return kmalloc(bytes, GFP_KERNEL | __GFP_NOWARN);
|
||||
}
|
||||
|
||||
static inline void ip_set_free(void * data, size_t bytes)
|
||||
{
|
||||
BUG_ON(max_malloc_size == 0);
|
||||
|
||||
if (bytes > max_malloc_size)
|
||||
vfree(data);
|
||||
else
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /*_IP_SET_MALLOC_H*/
|
Reference in New Issue
Block a user