fixed memory allocation, improved IO debugging

This commit is contained in:
Thomas Schoebel-Theuer 2011-10-12 16:57:53 +02:00 committed by Thomas Schoebel-Theuer
parent ab3f9f6a00
commit cb5f6e4d37
8 changed files with 98 additions and 31 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);