Commit c7926831 authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: kmalloc/kfree wrappers



Very basic, simple and stupid wrappers for kmalloc family.
It tries kfree_ruc() as possible, with hoping a better performance.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 78ac643d
# SPDX-License-Identifier: GPL-2.0
-include ${srctree}/${src}/priv_def.mk
# sparse requires the full pathname
ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h
obj-$(CONFIG_AUFS_FS) += aufs.o
aufs-y := module.o
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2005-2019 Junjiro R. Okajima
*/
/*
* all header files
*/
#ifndef __AUFS_H__
#define __AUFS_H__
#ifdef __KERNEL__
#include "module.h"
#endif /* __KERNEL__ */
#endif /* __AUFS_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2005-2019 Junjiro R. Okajima
*/
/*
* debug print functions
*/
#ifndef __AUFS_DEBUG_H__
#define __AUFS_DEBUG_H__
#ifdef __KERNEL__
#ifdef CONFIG_AUFS_DEBUG
#define AuDebugOn(a) BUG_ON(a)
#else
#define AuDebugOn(a) do {} while (0)
#endif /* CONFIG_AUFS_DEBUG */
#endif /* __KERNEL__ */
#endif /* __AUFS_DEBUG_H__ */
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2005-2019 Junjiro R. Okajima
*/
/*
* module global variables and operations
*/
#include <linux/module.h>
#include "aufs.h"
/* shrinkable realloc */
void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink)
{
size_t sz;
int diff;
sz = 0;
diff = -1;
if (p) {
#if 0 /* unused */
if (!new_sz) {
au_kfree_rcu(p);
p = NULL;
goto out;
}
#else
AuDebugOn(!new_sz);
#endif
sz = ksize(p);
diff = au_kmidx_sub(sz, new_sz);
}
if (sz && !diff)
goto out;
if (sz < new_sz)
/* expand or SLOB */
p = krealloc(p, new_sz, gfp);
else if (new_sz < sz && may_shrink) {
/* shrink */
void *q;
q = kmalloc(new_sz, gfp);
if (q) {
if (p) {
memcpy(q, p, new_sz);
au_kfree_try_rcu(p);
}
p = q;
} else
p = NULL;
}
out:
return p;
}
void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
int may_shrink)
{
p = au_krealloc(p, new_sz, gfp, may_shrink);
if (p && new_sz > nused)
memset(p + nused, 0, new_sz - nused);
return p;
}
/* ---------------------------------------------------------------------- */
/*
* functions for module interface.
*/
MODULE_LICENSE("GPL");
/* MODULE_LICENSE("GPL v2"); */
MODULE_AUTHOR("Junjiro R. Okajima <aufs-users@lists.sourceforge.net>");
MODULE_DESCRIPTION(AUFS_NAME
" -- Advanced multi layered unification filesystem");
MODULE_VERSION(AUFS_VERSION);
/* ---------------------------------------------------------------------- */
static int __init aufs_init(void)
{
/* since we define pr_fmt, call printk directly */
printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n");
return 0;
}
module_init(aufs_init);
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2005-2019 Junjiro R. Okajima
*/
/*
* module initialization and module-global
*/
#ifndef __AUFS_MODULE_H__
#define __AUFS_MODULE_H__
#ifdef __KERNEL__
#include <linux/slab.h>
#include "debug.h"
void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink);
void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp,
int may_shrink);
/*
* Comparing the size of the object with sizeof(struct rcu_head)
* case 1: object is always larger
* --> au_kfree_rcu() or au_kfree_do_rcu()
* case 2: object is always smaller
* --> au_kfree_small()
* case 3: object can be any size
* --> au_kfree_try_rcu()
*/
static inline void au_kfree_do_rcu(const void *p)
{
struct {
struct rcu_head rcu;
} *a = (void *)p;
kfree_rcu(a, rcu);
}
#define au_kfree_rcu(_p) do { \
typeof(_p) p = (_p); \
BUILD_BUG_ON(sizeof(*p) < sizeof(struct rcu_head)); \
if (p) \
au_kfree_do_rcu(p); \
} while (0)
#define au_kfree_do_sz_test(sz) (sz >= sizeof(struct rcu_head))
#define au_kfree_sz_test(p) (p && au_kfree_do_sz_test(ksize(p)))
static inline void au_kfree_try_rcu(const void *p)
{
if (!p)
return;
if (au_kfree_sz_test(p))
au_kfree_do_rcu(p);
else
kfree(p);
}
static inline void au_kfree_small(const void *p)
{
if (!p)
return;
AuDebugOn(au_kfree_sz_test(p));
kfree(p);
}
static inline int au_kmidx_sub(size_t sz, size_t new_sz)
{
#ifndef CONFIG_SLOB
return kmalloc_index(sz) - kmalloc_index(new_sz);
#else
return -1; /* SLOB is untested */
#endif
}
#endif /* __KERNEL__ */
#endif /* __AUFS_MODULE_H__ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment