#include <string.h>
#include <linux/kernel.h>
+#include <linux/log2.h>
#include <linux/page.h>
+#include <linux/shrinker.h>
#include <linux/types.h>
#define ARCH_KMALLOC_MINALIGN 16
static inline void *kmalloc(size_t size, gfp_t flags)
{
- void *p = malloc(size);
+ void *p;
+ run_shrinkers();
+
+ size_t alignment = min(rounddown_pow_of_two(size),
+ (size_t)PAGE_SIZE);
+ size = roundup(size, alignment);
+ p = size
+ ? aligned_alloc(alignment, size)
+ : malloc(0);
if (p && (flags & __GFP_ZERO))
memset(p, 0, size);
static inline void *krealloc(void *old, size_t size, gfp_t flags)
{
- void *new = kmalloc(size, flags);
+ void *new;
+
+ run_shrinkers();
+
+ new = malloc(size);
+ if (!new)
+ return NULL;
- if (new && (flags & __GFP_ZERO))
+ if (flags & __GFP_ZERO)
memset(new, 0, size);
- if (new) {
- memcpy(new, old,
- min(malloc_usable_size(old),
- malloc_usable_size(new)));
- free(old);
- }
+ memcpy(new, old,
+ min(malloc_usable_size(old),
+ malloc_usable_size(new)));
+ free(old);
return new;
}
-#define kzalloc(size, flags) calloc(1, size)
-#define kcalloc(n, size, flags) calloc(n, size)
-#define kmalloc_array(n, size, flags) calloc(n, size)
+#define kzalloc(size, flags) kmalloc(size, flags|__GFP_ZERO)
+#define kmalloc_array(n, size, flags) \
+ ((size) != 0 && (n) > SIZE_MAX / (size) \
+ ? NULL : kmalloc(n * size, flags))
+
+#define kcalloc(n, size, flags) kmalloc_array(n, size, flags|__GFP_ZERO)
#define kfree(p) free(p)
-#define kvfree(p) free(p)
#define kzfree(p) free(p)
+#define kvmalloc(size, flags) kmalloc(size, flags)
+#define kvfree(p) kfree(p)
+
static inline struct page *alloc_pages(gfp_t flags, unsigned int order)
{
size_t size = PAGE_SIZE << order;
- void *p = memalign(PAGE_SIZE, size);
+ void *p;
+
+ run_shrinkers();
+ p = aligned_alloc(PAGE_SIZE, size);
if (p && (flags & __GFP_ZERO))
memset(p, 0, size);
static inline void *vmap(struct page **pages, unsigned int count,
unsigned long flags, unsigned prot)
{
- return page_address(pages[0]);
+ return NULL;
}
#define is_vmalloc_addr(page) 0
#define vmalloc_to_page(addr) ((struct page *) (addr))
+static inline void *kmemdup(const void *src, size_t len, gfp_t gfp)
+{
+ void *p;
+
+ p = kmalloc(len, gfp);
+ if (p)
+ memcpy(p, src, len);
+ return p;
+}
+
#endif /* __TOOLS_LINUX_SLAB_H */