1 
2 #ifndef __XMALLOC_H__
3 #define __XMALLOC_H__
4 
5 #include <xen/types.h>
6 #include <xen/cache.h>
7 
8 /*
9  * Xen malloc/free-style interface.
10  */
11 
12 /* Allocate space for typed object. */
13 #define xmalloc(_type) ((_type *)_xmalloc(sizeof(_type), __alignof__(_type)))
14 #define xzalloc(_type) ((_type *)_xzalloc(sizeof(_type), __alignof__(_type)))
15 
16 /*
17  * Allocate space for a typed object and copy an existing instance.
18  *
19  * Note: Due to const propagating in the typeof(), ptr needs to be mutable.
20  * This can be fixed by changing n_ to being void *, but then we lose type
21  * safety on the return value.
22  */
23 #define xmemdup(ptr)                                         \
24 ({                                                           \
25     typeof(*(ptr)) *p_ = (ptr), *n_ = xmalloc(typeof(*p_));  \
26                                                              \
27     if ( n_ )                                                \
28         memcpy(n_, p_, sizeof(*n_));                         \
29     n_;                                                      \
30 })
31 
32 /* Allocate space for array of typed objects. */
33 #define xmalloc_array(_type, _num) \
34     ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
35 #define xzalloc_array(_type, _num) \
36     ((_type *)_xzalloc_array(sizeof(_type), __alignof__(_type), _num))
37 
38 /* Allocate space for a structure with a flexible array of typed objects. */
39 #define xzalloc_flex_struct(type, field, nr) \
40     ((type *)_xzalloc(offsetof(type, field[nr]), __alignof__(type)))
41 
42 #define xmalloc_flex_struct(type, field, nr) \
43     ((type *)_xmalloc(offsetof(type, field[nr]), __alignof__(type)))
44 
45 /* Re-allocate space for a structure with a flexible array of typed objects. */
46 #define xrealloc_flex_struct(ptr, field, nr)                           \
47     ((typeof(ptr))_xrealloc(ptr, offsetof(typeof(*(ptr)), field[nr]),  \
48                             __alignof__(typeof(*(ptr)))))
49 
50 /* Allocate untyped storage. */
51 #define xmalloc_bytes(_bytes) _xmalloc(_bytes, SMP_CACHE_BYTES)
52 #define xzalloc_bytes(_bytes) _xzalloc(_bytes, SMP_CACHE_BYTES)
53 
54 /* Allocate untyped storage and copying an existing instance. */
55 #define xmemdup_bytes(_src, _nr)                \
56     ({                                          \
57         unsigned long nr_ = (_nr);              \
58         void *dst_ = xmalloc_bytes(nr_);        \
59                                                 \
60         if ( dst_ )                             \
61             memcpy(dst_, _src, nr_);            \
62         dst_;                                   \
63     })
64 
65 /* Free any of the above. */
66 extern void xfree(void *);
67 
68 /* Free an allocation, and zero the pointer to it. */
69 #define XFREE(p) do { \
70     xfree(p);         \
71     (p) = NULL;       \
72 } while ( false )
73 
74 /* Underlying functions */
75 extern void *_xmalloc(unsigned long size, unsigned long align);
76 extern void *_xzalloc(unsigned long size, unsigned long align);
77 extern void *_xrealloc(void *ptr, unsigned long size, unsigned long align);
78 
_xmalloc_array(unsigned long size,unsigned long align,unsigned long num)79 static inline void *_xmalloc_array(
80     unsigned long size, unsigned long align, unsigned long num)
81 {
82     /* Check for overflow. */
83     if ( size && num > UINT_MAX / size )
84         return NULL;
85     return _xmalloc(size * num, align);
86 }
87 
_xzalloc_array(unsigned long size,unsigned long align,unsigned long num)88 static inline void *_xzalloc_array(
89     unsigned long size, unsigned long align, unsigned long num)
90 {
91     /* Check for overflow. */
92     if ( size && num > UINT_MAX / size )
93         return NULL;
94     return _xzalloc(size * num, align);
95 }
96 
97 /*
98  * Pooled allocator interface.
99  */
100 
101 struct xmem_pool;
102 
103 typedef void *(xmem_pool_get_memory)(unsigned long bytes);
104 typedef void (xmem_pool_put_memory)(void *ptr);
105 
106 /**
107  * xmem_pool_create - create dynamic memory pool
108  * @name: name of the pool
109  * @get_mem: callback function used to expand pool
110  * @put_mem: callback function used to shrink pool
111  * @max_size: maximum pool size (in bytes) - set this as 0 for no limit
112  * @grow_size: amount of memory (in bytes) added to pool whenever required
113  *
114  * All size values are rounded up to next page boundary.
115  */
116 struct xmem_pool *xmem_pool_create(
117     const char *name,
118     xmem_pool_get_memory get_mem,
119     xmem_pool_put_memory put_mem,
120     unsigned long max_size,
121     unsigned long grow_size);
122 
123 /**
124  * xmem_pool_destroy - cleanup given pool
125  * @mem_pool: Pool to be destroyed
126  *
127  * Data structures associated with pool are freed.
128  * All memory allocated from pool must be freed before
129  * destorying it.
130  */
131 void xmem_pool_destroy(struct xmem_pool *pool);
132 
133 /**
134  * xmem_pool_alloc - allocate memory from given pool
135  * @size: no. of bytes
136  * @mem_pool: pool to allocate from
137  */
138 void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool);
139 
140 /**
141  * xmem_pool_maxalloc - xmem_pool_alloc's greater than this size will fail
142  * @mem_pool: pool
143  */
144 int xmem_pool_maxalloc(struct xmem_pool *pool);
145 
146 /**
147  * xmem_pool_maxsize -
148  * @ptr: address of memory to be freed
149  * @mem_pool: pool to free from
150  */
151 void xmem_pool_free(void *ptr, struct xmem_pool *pool);
152 
153 /**
154  * xmem_pool_get_used_size - get memory currently used by given pool
155  *
156  * Used memory includes stored data + metadata + internal fragmentation
157  */
158 unsigned long xmem_pool_get_used_size(struct xmem_pool *pool);
159 
160 /**
161  * xmem_pool_get_total_size - get total memory currently allocated for pool
162  *
163  * This is the total memory currently allocated for this pool which includes
164  * used size + free size.
165  *
166  * (Total - Used) is good indicator of memory efficiency of allocator.
167  */
168 unsigned long xmem_pool_get_total_size(struct xmem_pool *pool);
169 
170 #endif /* __XMALLOC_H__ */
171