This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / include / linux / netfilter_ipv4 / ip_set_malloc.h
1 #ifndef _IP_SET_MALLOC_H
2 #define _IP_SET_MALLOC_H
3
4 #ifdef __KERNEL__
5
6 /* Memory allocation and deallocation */
7 static size_t max_malloc_size = 0;
8
9 static inline void init_max_malloc_size(void)
10 {
11 #define CACHE(x) max_malloc_size = x;
12 #include <linux/kmalloc_sizes.h>
13 #undef CACHE
14 }
15
16 static inline void * ip_set_malloc(size_t bytes)
17 {
18         if (bytes > max_malloc_size)
19                 return vmalloc(bytes);
20         else
21                 return kmalloc(bytes, GFP_KERNEL);
22 }
23
24 static inline void ip_set_free(void * data, size_t bytes)
25 {
26         if (bytes > max_malloc_size)
27                 vfree(data);
28         else
29                 kfree(data);
30 }
31
32 struct harray {
33         size_t max_elements;
34         void *arrays[0];
35 };
36
37 static inline void * 
38 harray_malloc(size_t hashsize, size_t typesize, int flags)
39 {
40         struct harray *harray;
41         size_t max_elements, size, i, j;
42
43         if (!max_malloc_size)
44                 init_max_malloc_size();
45
46         if (typesize > max_malloc_size)
47                 return NULL;
48
49         max_elements = max_malloc_size/typesize;
50         size = hashsize/max_elements;
51         if (hashsize % max_elements)
52                 size++;
53         
54         /* Last pointer signals end of arrays */
55         harray = kmalloc(sizeof(struct harray) + (size + 1) * sizeof(void *),
56                          flags);
57
58         if (!harray)
59                 return NULL;
60         
61         for (i = 0; i < size - 1; i++) {
62                 harray->arrays[i] = kmalloc(max_elements * typesize, flags);
63                 if (!harray->arrays[i])
64                         goto undo;
65                 memset(harray->arrays[i], 0, max_elements * typesize);
66         }
67         harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize, 
68                                     flags);
69         if (!harray->arrays[i])
70                 goto undo;
71         memset(harray->arrays[i], 0, (hashsize - i * max_elements) * typesize);
72
73         harray->max_elements = max_elements;
74         harray->arrays[size] = NULL;
75         
76         return (void *)harray;
77
78     undo:
79         for (j = 0; j < i; j++) {
80                 kfree(harray->arrays[j]);
81         }
82         kfree(harray);
83         return NULL;
84 }
85
86 static inline void harray_free(void *h)
87 {
88         struct harray *harray = (struct harray *) h;
89         size_t i;
90         
91         for (i = 0; harray->arrays[i] != NULL; i++)
92                 kfree(harray->arrays[i]);
93         kfree(harray);
94 }
95
96 static inline void harray_flush(void *h, size_t hashsize, size_t typesize)
97 {
98         struct harray *harray = (struct harray *) h;
99         size_t i;
100         
101         for (i = 0; harray->arrays[i+1] != NULL; i++)
102                 memset(harray->arrays[i], 0, harray->max_elements * typesize);
103         memset(harray->arrays[i], 0, 
104                (hashsize - i * harray->max_elements) * typesize);
105 }
106
107 #define HARRAY_ELEM(h, type, which)                             \
108 ({                                                              \
109         struct harray *__h = (struct harray *)(h);              \
110         ((type)((__h)->arrays[(which)/(__h)->max_elements])     \
111                 + (which)%(__h)->max_elements);                 \
112 })
113
114 #endif                          /* __KERNEL__ */
115
116 #endif /*_IP_SET_MALLOC_H*/