mirror of
https://github.com/schoebel/mars
synced 2025-04-08 02:21:31 +00:00
brick_mem: add /proc/sys/mars/mem_allow_freelist
This commit is contained in:
parent
4abb584aad
commit
7f8bf6c29a
@ -15,7 +15,6 @@
|
|||||||
#include "lamport.h"
|
#include "lamport.h"
|
||||||
|
|
||||||
#define USE_KERNEL_PAGES // currently mandatory (vmalloc does not work)
|
#define USE_KERNEL_PAGES // currently mandatory (vmalloc does not work)
|
||||||
#define ALLOW_DYNAMIC_RAISE 4096
|
|
||||||
|
|
||||||
#define MAGIC_BLOCK (int)0x8B395D7B
|
#define MAGIC_BLOCK (int)0x8B395D7B
|
||||||
#define MAGIC_BEND (int)0x8B395D7C
|
#define MAGIC_BEND (int)0x8B395D7C
|
||||||
@ -321,6 +320,16 @@ int len2order(int len)
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
|
static atomic_t _alloc_count[BRICK_MAX_ORDER+1] = {};
|
||||||
|
int brick_mem_alloc_count[BRICK_MAX_ORDER+1] = {};
|
||||||
|
EXPORT_SYMBOL_GPL(brick_mem_alloc_count);
|
||||||
|
int brick_mem_alloc_max[BRICK_MAX_ORDER+1] = {};
|
||||||
|
EXPORT_SYMBOL_GPL(brick_mem_alloc_max);
|
||||||
|
int brick_mem_freelist_max[BRICK_MAX_ORDER+1] = {};
|
||||||
|
EXPORT_SYMBOL_GPL(brick_mem_freelist_max);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BRICK_DEBUG_MEM
|
#ifdef BRICK_DEBUG_MEM
|
||||||
static atomic_t phys_block_alloc = ATOMIC_INIT(0);
|
static atomic_t phys_block_alloc = ATOMIC_INIT(0);
|
||||||
// indexed by line
|
// indexed by line
|
||||||
@ -330,8 +339,6 @@ static int block_len[BRICK_DEBUG_MEM] = {};
|
|||||||
// indexed by order
|
// indexed by order
|
||||||
static atomic_t op_count[BRICK_MAX_ORDER+1] = {};
|
static atomic_t op_count[BRICK_MAX_ORDER+1] = {};
|
||||||
static atomic_t raw_count[BRICK_MAX_ORDER+1] = {};
|
static atomic_t raw_count[BRICK_MAX_ORDER+1] = {};
|
||||||
static atomic_t alloc_count[BRICK_MAX_ORDER+1] = {};
|
|
||||||
static int alloc_max[BRICK_MAX_ORDER+1] = {};
|
|
||||||
static int alloc_line[BRICK_MAX_ORDER+1] = {};
|
static int alloc_line[BRICK_MAX_ORDER+1] = {};
|
||||||
static int alloc_len[BRICK_MAX_ORDER+1] = {};
|
static int alloc_len[BRICK_MAX_ORDER+1] = {};
|
||||||
#endif
|
#endif
|
||||||
@ -381,10 +388,13 @@ void __brick_block_free(void *data, int order)
|
|||||||
atomic64_sub((PAGE_SIZE/1024) << order, &brick_global_block_used);
|
atomic64_sub((PAGE_SIZE/1024) << order, &brick_global_block_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool brick_allow_freelist = true;
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
|
int brick_allow_freelist = 1;
|
||||||
EXPORT_SYMBOL_GPL(brick_allow_freelist);
|
EXPORT_SYMBOL_GPL(brick_allow_freelist);
|
||||||
|
|
||||||
#ifdef CONFIG_MARS_MEM_PREALLOC
|
int brick_pre_reserve[BRICK_MAX_ORDER+1] = {};
|
||||||
|
EXPORT_SYMBOL_GPL(brick_pre_reserve);
|
||||||
|
|
||||||
/* Note: we have no separate lists per CPU.
|
/* Note: we have no separate lists per CPU.
|
||||||
* This should not hurt because the freelists are only used
|
* This should not hurt because the freelists are only used
|
||||||
* for higher-order pages which should be rather low-frequency.
|
* for higher-order pages which should be rather low-frequency.
|
||||||
@ -392,7 +402,6 @@ EXPORT_SYMBOL_GPL(brick_allow_freelist);
|
|||||||
static spinlock_t freelist_lock[BRICK_MAX_ORDER+1];
|
static spinlock_t freelist_lock[BRICK_MAX_ORDER+1];
|
||||||
static void *brick_freelist[BRICK_MAX_ORDER+1] = {};
|
static void *brick_freelist[BRICK_MAX_ORDER+1] = {};
|
||||||
static atomic_t freelist_count[BRICK_MAX_ORDER+1] = {};
|
static atomic_t freelist_count[BRICK_MAX_ORDER+1] = {};
|
||||||
static int freelist_max[BRICK_MAX_ORDER+1] = {};
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void *_get_free(int order)
|
void *_get_free(int order)
|
||||||
@ -458,18 +467,18 @@ void _free_all(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int brick_mem_reserve(struct mem_reservation *r)
|
int brick_mem_reserve(void)
|
||||||
{
|
{
|
||||||
int order;
|
int order;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
for (order = BRICK_MAX_ORDER; order >= 0; order--) {
|
for (order = BRICK_MAX_ORDER; order >= 0; order--) {
|
||||||
int max = r->amount[order];
|
int max = brick_pre_reserve[order];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
freelist_max[order] += max;
|
brick_mem_freelist_max[order] += max;
|
||||||
BRICK_INF("preallocating %d at order %d (new maxlevel = %d)\n", max, order, freelist_max[order]);
|
BRICK_INF("preallocating %d at order %d (new maxlevel = %d)\n", max, order, brick_mem_freelist_max[order]);
|
||||||
|
|
||||||
max = freelist_max[order] - atomic_read(&freelist_count[order]);
|
max = brick_mem_freelist_max[order] - atomic_read(&freelist_count[order]);
|
||||||
if (max >= 0) {
|
if (max >= 0) {
|
||||||
for (i = 0; i < max; i++) {
|
for (i = 0; i < max; i++) {
|
||||||
void *data = __brick_block_alloc(GFP_KERNEL, order);
|
void *data = __brick_block_alloc(GFP_KERNEL, order);
|
||||||
@ -502,8 +511,8 @@ EXPORT_SYMBOL_GPL(brick_mem_reserve);
|
|||||||
void *_brick_block_alloc(loff_t pos, int len, int line)
|
void *_brick_block_alloc(loff_t pos, int len, int line)
|
||||||
{
|
{
|
||||||
void *data;
|
void *data;
|
||||||
#ifdef BRICK_DEBUG_MEM
|
|
||||||
int count;
|
int count;
|
||||||
|
#ifdef BRICK_DEBUG_MEM
|
||||||
#ifdef BRICK_DEBUG_ORDER0
|
#ifdef BRICK_DEBUG_ORDER0
|
||||||
const int plus0 = PAGE_SIZE;
|
const int plus0 = PAGE_SIZE;
|
||||||
#else
|
#else
|
||||||
@ -524,24 +533,27 @@ void *_brick_block_alloc(loff_t pos, int len, int line)
|
|||||||
might_sleep();
|
might_sleep();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
|
count = atomic_add_return(1, &_alloc_count[order]);
|
||||||
|
brick_mem_alloc_count[order] = count;
|
||||||
|
if (count > brick_mem_alloc_max[order])
|
||||||
|
brick_mem_alloc_max[order] = count;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BRICK_DEBUG_MEM
|
#ifdef BRICK_DEBUG_MEM
|
||||||
atomic_inc(&op_count[order]);
|
atomic_inc(&op_count[order]);
|
||||||
atomic_inc(&alloc_count[order]);
|
|
||||||
count = atomic_read(&alloc_count[order]);
|
|
||||||
// statistics
|
// statistics
|
||||||
alloc_line[order] = line;
|
alloc_line[order] = line;
|
||||||
alloc_len[order] = len;
|
alloc_len[order] = len;
|
||||||
if (count > alloc_max[order])
|
#endif
|
||||||
alloc_max[order] = count;
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
/* Dynamic increase of limits, in order to reduce
|
/* Dynamic increase of limits, in order to reduce
|
||||||
* fragmentation on higher-order pages.
|
* fragmentation on higher-order pages.
|
||||||
* This comes on cost of higher memory usage.
|
* This comes on cost of higher memory usage.
|
||||||
*/
|
*/
|
||||||
#if defined(ALLOW_DYNAMIC_RAISE) && defined(CONFIG_MARS_MEM_PREALLOC)
|
if (order > 0 && count > brick_mem_freelist_max[order])
|
||||||
if (order > 0 && count > freelist_max[order] && count <= ALLOW_DYNAMIC_RAISE)
|
brick_mem_freelist_max[order] = count;
|
||||||
freelist_max[order] = count;
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MARS_MEM_PREALLOC
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
@ -649,14 +661,14 @@ void _brick_block_free(void *data, int len, int cline)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_MARS_MEM_PREALLOC
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
if (order > 0 && brick_allow_freelist && atomic_read(&freelist_count[order]) <= freelist_max[order]) {
|
if (order > 0 && brick_allow_freelist && atomic_read(&freelist_count[order]) <= brick_mem_freelist_max[order]) {
|
||||||
_put_free(data, order);
|
_put_free(data, order);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
__brick_block_free(data, order);
|
__brick_block_free(data, order);
|
||||||
|
|
||||||
#ifdef BRICK_DEBUG_MEM
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
atomic_dec(&alloc_count[order]);
|
brick_mem_alloc_count[order] = atomic_dec_return(&_alloc_count[order]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(_brick_block_free);
|
EXPORT_SYMBOL_GPL(_brick_block_free);
|
||||||
@ -703,12 +715,12 @@ void brick_mem_statistics(void)
|
|||||||
i,
|
i,
|
||||||
atomic_read(&op_count[i]),
|
atomic_read(&op_count[i]),
|
||||||
atomic_read(&freelist_count[i]),
|
atomic_read(&freelist_count[i]),
|
||||||
freelist_max[i],
|
brick_mem_freelist_max[i],
|
||||||
atomic_read(&raw_count[i]),
|
atomic_read(&raw_count[i]),
|
||||||
atomic_read(&alloc_count[i]),
|
brick_mem_alloc_count[i],
|
||||||
alloc_len[i],
|
alloc_len[i],
|
||||||
alloc_line[i],
|
alloc_line[i],
|
||||||
alloc_max[i]);
|
brick_mem_alloc_max[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < BRICK_DEBUG_MEM; i++) {
|
for (i = 0; i < BRICK_DEBUG_MEM; i++) {
|
||||||
|
@ -183,13 +183,17 @@ extern void _brick_block_free(void *data, int len, int cline);
|
|||||||
|
|
||||||
#define BRICK_MAX_ORDER 11
|
#define BRICK_MAX_ORDER 11
|
||||||
|
|
||||||
extern bool brick_allow_freelist;
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
|
extern int brick_allow_freelist;
|
||||||
|
|
||||||
struct mem_reservation {
|
extern int brick_pre_reserve[BRICK_MAX_ORDER+1];
|
||||||
int amount[BRICK_MAX_ORDER+1];
|
extern int brick_mem_freelist_max[BRICK_MAX_ORDER+1];
|
||||||
};
|
extern int brick_mem_alloc_count[BRICK_MAX_ORDER+1];
|
||||||
|
extern int brick_mem_alloc_max[BRICK_MAX_ORDER+1];
|
||||||
|
|
||||||
extern int brick_mem_reserve(struct mem_reservation *r);
|
extern int brick_mem_reserve(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void brick_mem_statistics(void);
|
extern void brick_mem_statistics(void);
|
||||||
|
|
||||||
|
@ -4533,12 +4533,6 @@ char *_mars_info(void)
|
|||||||
return txt;
|
return txt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mem_reservation global_reserve = {
|
|
||||||
.amount = {
|
|
||||||
[5] = 64,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_MARS_HAVE_BIGMODULE
|
#ifdef CONFIG_MARS_HAVE_BIGMODULE
|
||||||
#define INIT_MAX 32
|
#define INIT_MAX 32
|
||||||
static char *exit_names[INIT_MAX] = {};
|
static char *exit_names[INIT_MAX] = {};
|
||||||
@ -4571,7 +4565,6 @@ static void __exit exit_light(void)
|
|||||||
|
|
||||||
mars_info = NULL;
|
mars_info = NULL;
|
||||||
_mars_remote_trigger = NULL;
|
_mars_remote_trigger = NULL;
|
||||||
brick_allow_freelist = false;
|
|
||||||
|
|
||||||
#ifdef CONFIG_MARS_HAVE_BIGMODULE
|
#ifdef CONFIG_MARS_HAVE_BIGMODULE
|
||||||
while (exit_fn_nr > 0) {
|
while (exit_fn_nr > 0) {
|
||||||
@ -4635,7 +4628,10 @@ static int __init init_light(void)
|
|||||||
DO_INIT(mars_proc);
|
DO_INIT(mars_proc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
brick_mem_reserve(&global_reserve);
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
|
brick_pre_reserve[5] = 64;
|
||||||
|
brick_mem_reserve();
|
||||||
|
#endif
|
||||||
|
|
||||||
status = compute_emergency_mode();
|
status = compute_emergency_mode();
|
||||||
if (unlikely(status < 0)) {
|
if (unlikely(status < 0)) {
|
||||||
|
@ -153,17 +153,20 @@ EXPORT_SYMBOL_GPL(mars_max_loadavg);
|
|||||||
#define _CTL_STRATEGY(handler) /*empty*/
|
#define _CTL_STRATEGY(handler) /*empty*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INT_ENTRY(NAME,VAR,MODE) \
|
#define VEC_ENTRY(NAME,VAR,MODE,COUNT) \
|
||||||
{ \
|
{ \
|
||||||
_CTL_NAME \
|
_CTL_NAME \
|
||||||
.procname = NAME, \
|
.procname = NAME, \
|
||||||
.data = &(VAR), \
|
.data = &(VAR), \
|
||||||
.maxlen = sizeof(int), \
|
.maxlen = sizeof(int) * (COUNT),\
|
||||||
.mode = MODE, \
|
.mode = MODE, \
|
||||||
.proc_handler = &proc_dointvec, \
|
.proc_handler = &proc_dointvec, \
|
||||||
_CTL_STRATEGY(sysctl_intvec) \
|
_CTL_STRATEGY(sysctl_intvec) \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INT_ENTRY(NAME,VAR,MODE) \
|
||||||
|
VEC_ENTRY(NAME, VAR, MODE, 1)
|
||||||
|
|
||||||
#define LIMITER_ENTRIES(VAR, PREFIX, SUFFIX) \
|
#define LIMITER_ENTRIES(VAR, PREFIX, SUFFIX) \
|
||||||
INT_ENTRY(PREFIX "_limit_" SUFFIX, (VAR)->lim_max_rate, 0600), \
|
INT_ENTRY(PREFIX "_limit_" SUFFIX, (VAR)->lim_max_rate, 0600), \
|
||||||
INT_ENTRY(PREFIX "_rate_" SUFFIX, (VAR)->lim_rate, 0400) \
|
INT_ENTRY(PREFIX "_rate_" SUFFIX, (VAR)->lim_rate, 0400) \
|
||||||
@ -230,6 +233,12 @@ ctl_table mars_table[] = {
|
|||||||
INT_ENTRY("mem_limit_percent", mars_mem_percent, 0600),
|
INT_ENTRY("mem_limit_percent", mars_mem_percent, 0600),
|
||||||
INT_ENTRY("logger_mem_used_kb", trans_logger_mem_usage, 0400),
|
INT_ENTRY("logger_mem_used_kb", trans_logger_mem_usage, 0400),
|
||||||
INT_ENTRY("mem_used_raw_kb", brick_global_block_used,0400),
|
INT_ENTRY("mem_used_raw_kb", brick_global_block_used,0400),
|
||||||
|
#ifdef CONFIG_MARS_MEM_PREALLOC
|
||||||
|
INT_ENTRY("mem_allow_freelist", brick_allow_freelist, 0600),
|
||||||
|
VEC_ENTRY("mem_freelist_max", brick_mem_freelist_max, 0600, BRICK_MAX_ORDER+1),
|
||||||
|
VEC_ENTRY("mem_alloc_count", brick_mem_alloc_count, 0400, BRICK_MAX_ORDER+1),
|
||||||
|
VEC_ENTRY("mem_alloc_max", brick_mem_alloc_count, 0600, BRICK_MAX_ORDER+1),
|
||||||
|
#endif
|
||||||
INT_ENTRY("io_flying_count", mars_global_io_flying, 0400),
|
INT_ENTRY("io_flying_count", mars_global_io_flying, 0400),
|
||||||
INT_ENTRY("copy_overlap", mars_copy_overlap, 0600),
|
INT_ENTRY("copy_overlap", mars_copy_overlap, 0600),
|
||||||
INT_ENTRY("copy_read_prio", mars_copy_read_prio, 0600),
|
INT_ENTRY("copy_read_prio", mars_copy_read_prio, 0600),
|
||||||
|
Loading…
Reference in New Issue
Block a user