kmem.h 4.0 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2 3
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
L
Linus Torvalds 已提交
4
 *
5 6
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
L
Linus Torvalds 已提交
7 8
 * published by the Free Software Foundation.
 *
9 10 11 12
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
L
Linus Torvalds 已提交
13
 *
14 15 16
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24 25
 */
#ifndef __XFS_SUPPORT_KMEM_H__
#define __XFS_SUPPORT_KMEM_H__

#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/mm.h>

/*
26
 * Process flags handling
L
Linus Torvalds 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
 */

#define PFLAGS_TEST_NOIO()              (current->flags & PF_NOIO)
#define PFLAGS_TEST_FSTRANS()           (current->flags & PF_FSTRANS)

#define PFLAGS_SET_NOIO() do {		\
	current->flags |= PF_NOIO;	\
} while (0)

#define PFLAGS_CLEAR_NOIO() do {	\
	current->flags &= ~PF_NOIO;	\
} while (0)

/* these could be nested, so we save state */
#define PFLAGS_SET_FSTRANS(STATEP) do {	\
	*(STATEP) = current->flags;	\
	current->flags |= PF_FSTRANS;	\
} while (0)

#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
	*(STATEP) = current->flags;	\
	current->flags &= ~PF_FSTRANS;	\
} while (0)

/* Restore the PF_FSTRANS state to what was saved in STATEP */
#define PFLAGS_RESTORE_FSTRANS(STATEP) do {     		\
	current->flags = ((current->flags & ~PF_FSTRANS) |	\
			  (*(STATEP) & PF_FSTRANS));		\
} while (0)

#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
	*(NSTATEP) = *(OSTATEP);	\
} while (0)

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
/*
 * General memory allocation interfaces
 */

#define KM_SLEEP	0x0001u
#define KM_NOSLEEP	0x0002u
#define KM_NOFS		0x0004u
#define KM_MAYFAIL	0x0008u

/*
 * We use a special process flag to avoid recursive callbacks into
 * the filesystem during transactions.  We will also issue our own
 * warnings, so we explicitly skip any generic ones (silly of us).
 */
static inline gfp_t
kmem_flags_convert(unsigned int __nocast flags)
L
Linus Torvalds 已提交
77
{
78
	gfp_t	lflags;
L
Linus Torvalds 已提交
79

80
	BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL));
L
Linus Torvalds 已提交
81 82

	if (flags & KM_NOSLEEP) {
83
		lflags = GFP_ATOMIC | __GFP_NOWARN;
L
Linus Torvalds 已提交
84
	} else {
85
		lflags = GFP_KERNEL | __GFP_NOWARN;
L
Linus Torvalds 已提交
86 87 88
		if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
			lflags &= ~__GFP_FS;
	}
89
	return lflags;
L
Linus Torvalds 已提交
90 91
}

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
extern void *kmem_alloc(size_t, unsigned int __nocast);
extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
extern void *kmem_zalloc(size_t, unsigned int __nocast);
extern void  kmem_free(void *, size_t);

/*
 * Zone interfaces
 */

#define KM_ZONE_HWALIGN	SLAB_HWCACHE_ALIGN
#define KM_ZONE_RECLAIM	SLAB_RECLAIM_ACCOUNT
#define KM_ZONE_SPREAD	0

#define kmem_zone	kmem_cache
#define kmem_zone_t	struct kmem_cache

static inline kmem_zone_t *
L
Linus Torvalds 已提交
109 110 111 112 113
kmem_zone_init(int size, char *zone_name)
{
	return kmem_cache_create(zone_name, size, 0, 0, NULL, NULL);
}

114 115 116 117 118 119 120 121
static inline kmem_zone_t *
kmem_zone_init_flags(int size, char *zone_name, unsigned long flags,
		     void (*construct)(void *, kmem_zone_t *, unsigned long))
{
	return kmem_cache_create(zone_name, size, 0, flags, construct, NULL);
}

static inline void
L
Linus Torvalds 已提交
122 123 124 125 126
kmem_zone_free(kmem_zone_t *zone, void *ptr)
{
	kmem_cache_free(zone, ptr);
}

127
static inline void
L
Linus Torvalds 已提交
128 129 130 131 132 133
kmem_zone_destroy(kmem_zone_t *zone)
{
	if (zone && kmem_cache_destroy(zone))
		BUG();
}

134
extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
135
extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
L
Linus Torvalds 已提交
136

137 138 139
/*
 * Low memory cache shrinkers
 */
L
Linus Torvalds 已提交
140 141

typedef struct shrinker *kmem_shaker_t;
A
Al Viro 已提交
142
typedef int (*kmem_shake_func_t)(int, gfp_t);
L
Linus Torvalds 已提交
143

144
static inline kmem_shaker_t
L
Linus Torvalds 已提交
145 146 147 148 149
kmem_shake_register(kmem_shake_func_t sfunc)
{
	return set_shrinker(DEFAULT_SEEKS, sfunc);
}

150
static inline void
L
Linus Torvalds 已提交
151 152 153 154 155
kmem_shake_deregister(kmem_shaker_t shrinker)
{
	remove_shrinker(shrinker);
}

156
static inline int
A
Al Viro 已提交
157
kmem_shake_allow(gfp_t gfp_mask)
L
Linus Torvalds 已提交
158 159 160 161 162
{
	return (gfp_mask & __GFP_WAIT);
}

#endif /* __XFS_SUPPORT_KMEM_H__ */