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