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 *p);
67 
68 /* Free an allocation, and zero the pointer to it. */
69 #define XFREE(p) do {                       \
70     void *_ptr_ = (p);                      \
71     (p) = NULL;                             \
72     xfree(_ptr_);                           \
73 } while ( false )
74 
75 /* Underlying functions */
76 extern void *_xmalloc(unsigned long size, unsigned long align);
77 extern void *_xzalloc(unsigned long size, unsigned long align);
78 extern void *_xrealloc(void *ptr, unsigned long size, unsigned long align);
79 
_xmalloc_array(unsigned long size,unsigned long align,unsigned long num)80 static inline void *_xmalloc_array(
81     unsigned long size, unsigned long align, unsigned long num)
82 {
83     /* Check for overflow. */
84     if ( size && num > UINT_MAX / size )
85         return NULL;
86     return _xmalloc(size * num, align);
87 }
88 
_xzalloc_array(unsigned long size,unsigned long align,unsigned long num)89 static inline void *_xzalloc_array(
90     unsigned long size, unsigned long align, unsigned long num)
91 {
92     /* Check for overflow. */
93     if ( size && num > UINT_MAX / size )
94         return NULL;
95     return _xzalloc(size * num, align);
96 }
97 
98 /*
99  * Pooled allocator interface.
100  */
101 
102 struct xmem_pool;
103 
104 typedef void *(xmem_pool_get_memory)(unsigned long bytes);
105 typedef void (xmem_pool_put_memory)(void *ptr);
106 
107 /**
108  * xmem_pool_create - create dynamic memory pool
109  * @name: name of the pool
110  * @get_mem: callback function used to expand pool
111  * @put_mem: callback function used to shrink pool
112  * @max_size: maximum pool size (in bytes) - set this as 0 for no limit
113  * @grow_size: amount of memory (in bytes) added to pool whenever required
114  *
115  * All size values are rounded up to next page boundary.
116  */
117 struct xmem_pool *xmem_pool_create(
118     const char *name,
119     xmem_pool_get_memory get_mem,
120     xmem_pool_put_memory put_mem,
121     unsigned long max_size,
122     unsigned long grow_size);
123 
124 /**
125  * xmem_pool_destroy - cleanup given pool
126  * @mem_pool: Pool to be destroyed
127  *
128  * Data structures associated with pool are freed.
129  * All memory allocated from pool must be freed before
130  * destorying it.
131  */
132 void xmem_pool_destroy(struct xmem_pool *pool);
133 
134 /**
135  * xmem_pool_alloc - allocate memory from given pool
136  * @size: no. of bytes
137  * @mem_pool: pool to allocate from
138  */
139 void *xmem_pool_alloc(unsigned long size, struct xmem_pool *pool);
140 
141 /**
142  * xmem_pool_maxalloc - xmem_pool_alloc's greater than this size will fail
143  * @mem_pool: pool
144  */
145 int xmem_pool_maxalloc(struct xmem_pool *pool);
146 
147 /**
148  * xmem_pool_maxsize -
149  * @ptr: address of memory to be freed
150  * @mem_pool: pool to free from
151  */
152 void xmem_pool_free(void *ptr, struct xmem_pool *pool);
153 
154 /**
155  * xmem_pool_get_used_size - get memory currently used by given pool
156  *
157  * Used memory includes stored data + metadata + internal fragmentation
158  */
159 unsigned long xmem_pool_get_used_size(struct xmem_pool *pool);
160 
161 /**
162  * xmem_pool_get_total_size - get total memory currently allocated for pool
163  *
164  * This is the total memory currently allocated for this pool which includes
165  * used size + free size.
166  *
167  * (Total - Used) is good indicator of memory efficiency of allocator.
168  */
169 unsigned long xmem_pool_get_total_size(struct xmem_pool *pool);
170 
171 #endif /* __XMALLOC_H__ */
172