mirror of
https://github.com/schoebel/mars
synced 2025-02-27 18:10:51 +00:00
fixed memory allocation, improved IO debugging
This commit is contained in:
parent
ab3f9f6a00
commit
cb5f6e4d37
2
brick.c
2
brick.c
@ -596,7 +596,7 @@ int default_init_object_layout(struct generic_brick *brick, struct generic_objec
|
||||
size = size0 + size1 + size2;
|
||||
data_ref = brick_zmem_alloc(size);
|
||||
if (unlikely(!data_ref)) {
|
||||
BRICK_ERR("alloc failed, size = %ld\n", size);
|
||||
BRICK_ERR("alloc failed, size = %d\n", size);
|
||||
goto done;
|
||||
}
|
||||
atomic_set(data_ref, 1);
|
||||
|
54
brick_mem.c
54
brick_mem.c
@ -11,9 +11,9 @@
|
||||
|
||||
#define BRICK_DEBUG_MEM 10000
|
||||
|
||||
#define MAGIC_MEM (int)0x8B395D7D
|
||||
#define MAGIC_END (int)0x8B395D7E
|
||||
#define MAGIC_STR (int)0x8B395D7F
|
||||
#define MAGIC_MEM (int)0x8B395D7D
|
||||
#define MAGIC_END (int)0x8B395D7E
|
||||
#define MAGIC_STR (int)0x8B395D7F
|
||||
|
||||
#define INT_ACCESS(ptr,offset) (*(int*)(((char*)(ptr)) + (offset)))
|
||||
|
||||
@ -113,25 +113,37 @@ static atomic_t string_free[BRICK_DEBUG_MEM] = {};
|
||||
char *_brick_string_alloc(int len, int line)
|
||||
{
|
||||
char *res;
|
||||
|
||||
#ifdef CONFIG_DEBUG_KERNEL
|
||||
might_sleep();
|
||||
#endif
|
||||
#ifdef FIXME
|
||||
if (len <= 0)
|
||||
|
||||
if (len <= 0) {
|
||||
len = BRICK_STRING_LEN;
|
||||
#else // provisionary
|
||||
len = BRICK_STRING_LEN;
|
||||
}
|
||||
|
||||
#ifdef BRICK_DEBUG_MEM
|
||||
len += sizeof(int) * 4;
|
||||
#endif
|
||||
res = kmalloc(len, GFP_BRICK);
|
||||
|
||||
#ifdef CONFIG_DEBUG_KERNEL
|
||||
res = kzalloc(len + 1024, GFP_BRICK);
|
||||
#else
|
||||
res = kzalloc(len, GFP_BRICK);
|
||||
#endif
|
||||
|
||||
#ifdef BRICK_DEBUG_MEM
|
||||
if (likely(res)) {
|
||||
if (unlikely(line < 0))
|
||||
line = 0;
|
||||
else if (unlikely(line >= BRICK_DEBUG_MEM))
|
||||
line = BRICK_DEBUG_MEM - 1;
|
||||
INT_ACCESS(res, len - PLUS_SIZE) = MAGIC_STR;
|
||||
INT_ACCESS(res, len - PLUS_SIZE + sizeof(int)) = line;
|
||||
INT_ACCESS(res, 0) = MAGIC_STR;
|
||||
INT_ACCESS(res, sizeof(int)) = len;
|
||||
INT_ACCESS(res, sizeof(int) * 2) = line;
|
||||
INT_ACCESS(res, len - sizeof(int)) = MAGIC_END;
|
||||
atomic_inc(&string_count[line]);
|
||||
res += sizeof(int) * 3;
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
@ -142,18 +154,28 @@ void _brick_string_free(const char *data, int cline)
|
||||
{
|
||||
if (data) {
|
||||
#ifdef BRICK_DEBUG_MEM
|
||||
int len = BRICK_STRING_LEN;
|
||||
int magic = INT_ACCESS(data, len - PLUS_SIZE);
|
||||
int line = INT_ACCESS(data, len - PLUS_SIZE + sizeof(int));
|
||||
int magic;
|
||||
int len;
|
||||
int line;
|
||||
|
||||
data -= sizeof(int) * 3;
|
||||
magic = INT_ACCESS(data, 0);
|
||||
if (unlikely(magic != MAGIC_STR)) {
|
||||
BRICK_ERR("line %d stringmem corruption: magix %08x != %08x\n", cline, magic, MAGIC_STR);
|
||||
BRICK_ERR("cline %d stringmem corruption: magix %08x != %08x\n", cline, magic, MAGIC_STR);
|
||||
return;
|
||||
}
|
||||
len = INT_ACCESS(data, sizeof(int));
|
||||
line = INT_ACCESS(data, sizeof(int) * 2);
|
||||
if (unlikely(line < 0 || line >= BRICK_DEBUG_MEM)) {
|
||||
BRICK_ERR("line %d stringmem corruption: line = %d\n", cline, line);
|
||||
BRICK_ERR("cline %d stringmem corruption: line = %d (len = %d)\n", cline, line, len);
|
||||
return;
|
||||
}
|
||||
INT_ACCESS(data, len - PLUS_SIZE) = 0xffffffff;
|
||||
magic = INT_ACCESS(data, len - sizeof(int));
|
||||
if (unlikely(magic != MAGIC_END)) {
|
||||
BRICK_ERR("cline %d stringmem corruption: end_magix %08x != %08x, line = %d len = %d\n", cline, magic, MAGIC_END, len, line);
|
||||
return;
|
||||
}
|
||||
INT_ACCESS(data, len - sizeof(int)) = 0xffffffff;
|
||||
atomic_dec(&string_count[line]);
|
||||
atomic_inc(&string_free[line]);
|
||||
#endif
|
||||
|
@ -26,7 +26,7 @@ extern void _brick_mem_free(void *data, int line);
|
||||
#define BRICK_STRING_LEN 1024 /* default value when len == 0 */
|
||||
|
||||
#define brick_string_alloc(_len_) _brick_string_alloc(_len_, __LINE__)
|
||||
#define brick_strdup(_orig_) ({ int _len_ = strlen(_orig_); char *_res_ = _brick_string_alloc(_len_ + 1, __LINE__); if (_res_) { strcpy(_res_, _orig_); } _res_; })
|
||||
#define brick_strdup(_orig_) ({ int _len_ = strlen(_orig_); char *_res_ = _brick_string_alloc(_len_ + 1, __LINE__); if (_res_) { strncpy(_res_, _orig_, _len_ + 1); } _res_; })
|
||||
extern char *_brick_string_alloc(int len, int line);
|
||||
#define brick_string_free(_data_) _brick_string_free(_data_, __LINE__)
|
||||
extern void _brick_string_free(const char *data, int line);
|
||||
|
@ -359,7 +359,7 @@ void aio_stop_thread(struct aio_output *output, int i, bool do_submit_dummy)
|
||||
|
||||
// workaround for waking up the receiver thread. TODO: check whether signal handlong could do better.
|
||||
if (do_submit_dummy) {
|
||||
MARS_INF("submitting dummy for wakeup...\n", i);
|
||||
MARS_INF("submitting dummy for wakeup %d...\n", i);
|
||||
aio_submit_dummy(output);
|
||||
}
|
||||
|
||||
|
19
mars_bio.c
19
mars_bio.c
@ -361,6 +361,9 @@ void bio_ref_io(struct bio_output *output, struct mref_object *mref)
|
||||
static int bio_thread(void *data)
|
||||
{
|
||||
struct bio_brick *brick = data;
|
||||
#ifdef IO_DEBUGGING
|
||||
int round = 0;
|
||||
#endif
|
||||
|
||||
MARS_INF("bio kthread has started on '%s'.\n", brick->brick_path);
|
||||
|
||||
@ -368,11 +371,16 @@ static int bio_thread(void *data)
|
||||
LIST_HEAD(tmp_list);
|
||||
unsigned long flags;
|
||||
|
||||
#ifdef IO_DEBUGGING
|
||||
round++;
|
||||
MARS_IO("%d sleeping...\n", round);
|
||||
#endif
|
||||
wait_event_interruptible_timeout(
|
||||
brick->event,
|
||||
atomic_read(&brick->completed_count) > 0 ||
|
||||
(atomic_read(&brick->background_count) > 0 && !atomic_read(&brick->fly_count)),
|
||||
12 * HZ);
|
||||
MARS_IO("%d woken up, completed_count = %d background_count = %d fly_count = %d\n", round, atomic_read(&brick->completed_count), atomic_read(&brick->background_count), atomic_read(&brick->fly_count));
|
||||
|
||||
spin_lock_irqsave(&brick->lock, flags);
|
||||
list_replace_init(&brick->completed_list, &tmp_list);
|
||||
@ -396,7 +404,10 @@ static int bio_thread(void *data)
|
||||
mref_a = container_of(tmp, struct bio_mref_aspect, io_head);
|
||||
|
||||
code = mref_a->status_code;
|
||||
MARS_IO("completed , status = %d\n", code);
|
||||
#ifdef IO_DEBUGGING
|
||||
round++;
|
||||
MARS_IO("%d completed , status = %d\n", round, code);
|
||||
#endif
|
||||
|
||||
mref = mref_a->object;
|
||||
|
||||
@ -409,10 +420,12 @@ static int bio_thread(void *data)
|
||||
}
|
||||
|
||||
SIMPLE_CALLBACK(mref, code);
|
||||
|
||||
MARS_IO("%d callback done.\n", round);
|
||||
|
||||
atomic_dec(&brick->fly_count);
|
||||
atomic_inc(&brick->total_completed_count);
|
||||
MARS_IO("fly = %d\n", atomic_read(&brick->fly_count));
|
||||
MARS_IO("%d completed_count = %d background_count = %d fly_count = %d\n", round, atomic_read(&brick->completed_count), atomic_read(&brick->background_count), atomic_read(&brick->fly_count));
|
||||
if (likely(mref_a->bio)) {
|
||||
bio_put(mref_a->bio);
|
||||
}
|
||||
@ -424,7 +437,9 @@ static int bio_thread(void *data)
|
||||
struct bio_mref_aspect *mref_a;
|
||||
struct mref_object *mref;
|
||||
|
||||
MARS_IO("%d pushing background to foreground, completed_count = %d background_count = %d fly_count = %d\n", round, atomic_read(&brick->completed_count), atomic_read(&brick->background_count), atomic_read(&brick->fly_count));
|
||||
atomic_dec(&brick->background_count);
|
||||
|
||||
spin_lock_irqsave(&brick->lock, flags);
|
||||
tmp = brick->background_list.next;
|
||||
list_del_init(tmp);
|
||||
|
44
mars_if.c
44
mars_if.c
@ -24,6 +24,7 @@
|
||||
|
||||
//#define USE_CONGESTED_FN
|
||||
#define USE_MERGE_BVEC
|
||||
//#define DENY_READA
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@ -68,6 +69,8 @@ void if_endio(struct generic_callback *cb)
|
||||
mars_trace(mref_a->object, "if_endio");
|
||||
mars_log_trace(mref_a->object);
|
||||
|
||||
MARS_IO("bio_count = %d\n", mref_a->bio_count);
|
||||
|
||||
for (k = 0; k < mref_a->bio_count; k++) {
|
||||
bio = mref_a->orig_bio[k];
|
||||
mref_a->orig_bio[k] = NULL;
|
||||
@ -100,6 +103,7 @@ void if_endio(struct generic_callback *cb)
|
||||
error = 0;
|
||||
bio->bi_size = 0;
|
||||
}
|
||||
MARS_IO("calling end_io() rw = %d error = %d\n", rw, error);
|
||||
bio_endio(bio, error);
|
||||
bio_put(bio);
|
||||
}
|
||||
@ -111,7 +115,16 @@ void if_endio(struct generic_callback *cb)
|
||||
} else {
|
||||
atomic_dec(&input->read_flying_count);
|
||||
}
|
||||
#ifdef IO_DEBUGGING
|
||||
{
|
||||
struct if_brick *brick = input->brick;
|
||||
char *txt = brick->ops->brick_statistics(brick, false);
|
||||
MARS_IO("%s", txt);
|
||||
brick_string_free(txt);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
MARS_IO("finished.\n");
|
||||
}
|
||||
|
||||
/* Kick off plugged mrefs
|
||||
@ -123,7 +136,9 @@ void _if_unplug(struct if_input *input)
|
||||
LIST_HEAD(tmp_list);
|
||||
unsigned long flags;
|
||||
|
||||
#ifdef CONFIG_DEBUG_KERNEL
|
||||
might_sleep();
|
||||
#endif
|
||||
|
||||
down(&input->kick_sem);
|
||||
traced_lock(&input->req_lock, flags);
|
||||
@ -171,6 +186,14 @@ void _if_unplug(struct if_input *input)
|
||||
GENERIC_INPUT_CALL(input, mref_io, mref);
|
||||
GENERIC_INPUT_CALL(input, mref_put, mref);
|
||||
}
|
||||
#ifdef IO_DEBUGGING
|
||||
{
|
||||
struct if_brick *brick = input->brick;
|
||||
char *txt = brick->ops->brick_statistics(brick, false);
|
||||
MARS_IO("%s", txt);
|
||||
brick_string_free(txt);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_TIMER
|
||||
@ -192,14 +215,14 @@ static int if_make_request(struct request_queue *q, struct bio *bio)
|
||||
struct bio_vec *bvec;
|
||||
int i;
|
||||
bool assigned = false;
|
||||
const bool unplug = bio_rw_flagged(bio, BIO_RW_UNPLUG);
|
||||
const bool unplug = bio_rw_flagged(bio, BIO_RW_UNPLUG) || bio_rw_flagged(bio, BIO_RW_SYNCIO);
|
||||
const bool barrier = ((bio->bi_rw & 1) != READ && bio_rw_flagged(bio, BIO_RW_BARRIER));
|
||||
loff_t pos = ((loff_t)bio->bi_sector) << 9; // TODO: make dynamic
|
||||
int rw = bio_data_dir(bio);
|
||||
int total_len = bio->bi_size;
|
||||
int error = -ENOSYS;
|
||||
|
||||
MARS_IO("bio %p size = %d\n", bio, bio->bi_size);
|
||||
MARS_IO("bio %p size = %d rw = %d unplug = %d barrier = %d\n", bio, bio->bi_size, rw, unplug, barrier);
|
||||
|
||||
might_sleep();
|
||||
|
||||
@ -220,7 +243,7 @@ static int if_make_request(struct request_queue *q, struct bio *bio)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 1 // provisinary -- we should introduce an equivalent of READA also to the MARS infrastructure
|
||||
#ifdef DENY_READA // provisinary -- we should introduce an equivalent of READA also to the MARS infrastructure
|
||||
if (bio_rw(bio) == READA) {
|
||||
atomic_inc(&input->total_reada_count);
|
||||
bio_endio(bio, -EWOULDBLOCK);
|
||||
@ -245,7 +268,7 @@ static int if_make_request(struct request_queue *q, struct bio *bio)
|
||||
/* FIXME: THIS IS PROVISIONARY (use event instead)
|
||||
*/
|
||||
while (unlikely(!brick->power.led_on)) {
|
||||
msleep(2 * HZ);
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
_CHECK_ATOMIC(&bio->bi_comp_cnt, !=, 0);
|
||||
@ -255,8 +278,7 @@ static int if_make_request(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
const unsigned short prio = bio_prio(bio);
|
||||
const bool sync = bio_rw_flagged(bio, BIO_RW_SYNCIO);
|
||||
const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK;
|
||||
MARS_IO("BIO rw = %lx len = %d prio = %d sync = %d unplug = %d ff = %d\n", bio->bi_rw, bio->bi_size, prio, sync, unplug, ff);
|
||||
MARS_IO("BIO raw_rw = 0x%016lx len = %d prio = %d sync = %d unplug = %d\n", bio->bi_rw, bio->bi_size, prio, sync, unplug);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -441,6 +463,14 @@ static int if_make_request(struct request_queue *q, struct bio *bio)
|
||||
|
||||
err:
|
||||
|
||||
#ifdef IO_DEBUGGING
|
||||
{
|
||||
char *txt = brick->ops->brick_statistics(brick, false);
|
||||
MARS_IO("%s", txt);
|
||||
brick_string_free(txt);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (error < 0) {
|
||||
MARS_ERR("cannot submit request from bio, status=%d\n", error);
|
||||
if (assigned) {
|
||||
@ -514,7 +544,7 @@ void if_unplug(struct request_queue *q)
|
||||
#else
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_PLUGGED, q);
|
||||
#endif
|
||||
MARS_IO("UNPLUG %d\n", was_plugged);
|
||||
MARS_IO("block layer called UNPLUG was_plugged = %d\n", was_plugged);
|
||||
if (true || was_plugged) {
|
||||
struct if_input *input = q->queuedata;
|
||||
_if_unplug(input);
|
||||
|
@ -427,7 +427,7 @@ static int server_switch(struct server_brick *brick)
|
||||
thread = kthread_create(cb_thread, brick, "mars_cb%d", version);
|
||||
if (IS_ERR(thread)) {
|
||||
status = PTR_ERR(thread);
|
||||
MARS_ERR("cannot create cb thread, status = %ld\n", status);
|
||||
MARS_ERR("cannot create cb thread, status = %d\n", status);
|
||||
goto err;
|
||||
}
|
||||
get_task_struct(thread);
|
||||
@ -437,7 +437,7 @@ static int server_switch(struct server_brick *brick)
|
||||
thread = kthread_create(handler_thread, brick, "mars_handler%d", version++);
|
||||
if (IS_ERR(thread)) {
|
||||
status = PTR_ERR(thread);
|
||||
MARS_ERR("cannot create handler thread, status = %ld\n", status);
|
||||
MARS_ERR("cannot create handler thread, status = %d\n", status);
|
||||
kthread_stop(brick->cb_thread);
|
||||
goto err;
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ int mars_filler(void *__buf, const char *name, int namlen, loff_t offset,
|
||||
return 0;
|
||||
|
||||
pathlen = cookie->pathlen;
|
||||
newpath = brick_string_alloc(pathlen + 1);
|
||||
newpath = brick_string_alloc(pathlen + namlen + 2);
|
||||
if (unlikely(!newpath))
|
||||
goto err_mem0;
|
||||
memcpy(newpath, cookie->path, pathlen);
|
||||
|
Loading…
Reference in New Issue
Block a user