diff --git a/brick.c b/brick.c index 7a9c53e3..6058f31f 100644 --- a/brick.c +++ b/brick.c @@ -364,21 +364,6 @@ int generic_brick_exit_recursively(struct generic_brick *brick, bool destroy_inp } EXPORT_SYMBOL_GPL(generic_brick_exit_recursively); -//////////////////////////////////////////////////////////////////////// - -// object_layout init stuff - -void init_generic_object_layout(struct generic_object_layout *lay, const struct generic_object_type *type) -{ -} -EXPORT_SYMBOL_GPL(init_generic_object_layout); - -void exit_generic_object_layout(struct generic_object_layout *lay) -{ -} -EXPORT_SYMBOL_GPL(exit_generic_object_layout); - - //////////////////////////////////////////////////////////////////////// // default implementations @@ -407,6 +392,7 @@ struct generic_object *generic_alloc(struct generic_brick *brick, struct generic goto err; atomic_inc(&object_layout->alloc_count); + atomic_inc(&object_layout->total_alloc_count); object = data; object->object_type = object_type; diff --git a/brick.h b/brick.h index feb00e0d..845cba32 100644 --- a/brick.h +++ b/brick.h @@ -89,18 +89,15 @@ struct generic_object_type { #define GENERIC_OBJECT_LAYOUT(OBJTYPE) \ int size_hint; \ atomic_t alloc_count; \ - atomic_t free_count; \ + atomic_t total_alloc_count; \ struct generic_object_layout { GENERIC_OBJECT_LAYOUT(generic); }; -extern void init_generic_object_layout(struct generic_object_layout *lay, const struct generic_object_type *type); -extern void exit_generic_object_layout(struct generic_object_layout *lay); - #define GENERIC_OBJECT(OBJTYPE) \ const struct generic_object_type *object_type; \ - struct OBJTYPE##_object_layout *object_layout; \ + struct generic_object_layout *object_layout; \ struct OBJTYPE##_aspect **aspects; \ int aspect_nr_max; \ int free_offset; \ @@ -530,9 +527,9 @@ extern struct generic_aspect *generic_get_aspect(struct generic_brick *brick, st #define DECLARE_ASPECT_FUNCTIONS(BRITYPE,OBJTYPE) \ \ -INLINE struct OBJTYPE##_object *BRITYPE##_alloc_##OBJTYPE(struct BRITYPE##_brick *brick, struct generic_object_layout *object_layout) \ +INLINE struct OBJTYPE##_object *BRITYPE##_alloc_##OBJTYPE(struct BRITYPE##_brick *brick) \ { \ - return (void*)generic_alloc((struct generic_brick*)brick, object_layout, &OBJTYPE##_type); \ + return (void*)generic_alloc((struct generic_brick*)brick, &brick->OBJTYPE##_object_layout, &OBJTYPE##_type); \ } \ \ INLINE void BRITYPE##_free_##OBJTYPE(struct OBJTYPE##_object *object) \ diff --git a/lib_log.c b/lib_log.c index 1cf3a981..b89bec1f 100644 --- a/lib_log.c +++ b/lib_log.c @@ -22,7 +22,6 @@ void exit_logst(struct log_status *logst) MARS_DBG("waiting for IO terminating..."); msleep(500); } - exit_generic_object_layout(&logst->ref_object_layout); } EXPORT_SYMBOL_GPL(exit_logst); @@ -189,7 +188,7 @@ void *log_reserve(struct log_status *logst, struct log_header *lh) sema_init(&cb_info->mutex, 1); atomic_set(&cb_info->refcount, 2); - mref = mars_alloc_mref(logst->brick, &logst->ref_object_layout); + mref = mars_alloc_mref(logst->brick); if (unlikely(!mref)) { MARS_ERR("no mref\n"); goto err; @@ -488,7 +487,7 @@ restart: logst->offset = 0; } - mref = mars_alloc_mref(logst->brick, &logst->ref_object_layout); + mref = mars_alloc_mref(logst->brick); if (unlikely(!mref)) { MARS_ERR("no mref\n"); goto done; diff --git a/lib_log.h b/lib_log.h index 1549aa10..70783d4a 100644 --- a/lib_log.h +++ b/lib_log.h @@ -100,7 +100,6 @@ struct log_status { // internal struct mars_input *input; struct mars_brick *brick; - struct generic_object_layout ref_object_layout; struct mars_info info; int offset; int validflag_offset; diff --git a/mars.h b/mars.h index b290627b..e0831172 100644 --- a/mars.h +++ b/mars.h @@ -74,14 +74,6 @@ extern const struct generic_object_type mref_type; -struct mref_aspect { - GENERIC_ASPECT(mref); -}; - -struct mref_object_layout { - GENERIC_OBJECT_LAYOUT(mref); -}; - #ifdef MARS_TRACING extern unsigned long long start_trace_clock; @@ -144,6 +136,7 @@ struct mars_info { #define MARS_BRICK(BRITYPE) \ GENERIC_BRICK(BRITYPE); \ + struct generic_object_layout mref_object_layout; \ struct list_head global_brick_link; \ struct list_head dent_brick_link; \ const char *brick_path; \ @@ -217,8 +210,6 @@ DECLARE_BRICK_FUNCTIONS(BRITYPE); \ \ _MARS_TYPES(BRITYPE) \ \ -struct BRITYPE##_object_layout; \ - \ DECLARE_ASPECT_FUNCTIONS(BRITYPE,mref); \ extern int init_mars_##BRITYPE(void); \ extern void exit_mars_##BRITYPE(void); diff --git a/mars_buf.c b/mars_buf.c index 074cfc5d..55579ed8 100644 --- a/mars_buf.c +++ b/mars_buf.c @@ -621,7 +621,7 @@ static int _buf_make_io(struct buf_brick *brick, struct buf_head *bf, void *star struct buf_mref_aspect *mref_a; int len; - mref = buf_alloc_mref(brick, &brick->mref_object_layout); + mref = buf_alloc_mref(brick); if (unlikely(!mref)) break; diff --git a/mars_buf.h b/mars_buf.h index e5d6f974..6bb25221 100644 --- a/mars_buf.h +++ b/mars_buf.h @@ -41,7 +41,6 @@ struct buf_brick { atomic_t hashed_count; atomic_t nr_io_pending; atomic_t nr_collisions; - struct generic_object_layout mref_object_layout; struct mars_info base_info; bool got_info; diff --git a/mars_check.c b/mars_check.c index 531bab7e..f6d11176 100644 --- a/mars_check.c +++ b/mars_check.c @@ -152,7 +152,7 @@ static int check_watchdog(void *data) mref_a->last_jiffies = now + 600 * HZ; MARS_INF("================================\n"); CHECK_ERR(output, "mref %p callback is missing for more than %d seconds.\n", mref, timeout); - object_layout = (void*)mref->object_layout; + object_layout = mref->object_layout; dump_mem(mref, object_layout->size_hint); MARS_INF("================================\n"); } diff --git a/mars_copy.c b/mars_copy.c index 75619eef..f895f14a 100644 --- a/mars_copy.c +++ b/mars_copy.c @@ -196,7 +196,7 @@ int _make_mref(struct copy_brick *brick, int index, int queue, void *data, loff_ if (brick->clash || !tmp_pos) goto done; - mref = copy_alloc_mref(brick, &brick->mref_object_layout); + mref = copy_alloc_mref(brick); status = -ENOMEM; if (unlikely(!mref)) goto done; diff --git a/mars_copy.h b/mars_copy.h index 0cd72087..4bfcc3c2 100644 --- a/mars_copy.h +++ b/mars_copy.h @@ -63,7 +63,6 @@ struct copy_brick { wait_queue_head_t event; struct semaphore mutex; struct task_struct *thread; - struct generic_object_layout mref_object_layout; struct copy_state st[MAX_COPY_PARA]; }; diff --git a/mars_if.c b/mars_if.c index ced3cc51..74fa37c7 100644 --- a/mars_if.c +++ b/mars_if.c @@ -380,7 +380,7 @@ static int if_make_request(struct request_queue *q, struct bio *bio) if (!mref) { int prefetch_len; error = -ENOMEM; - mref = if_alloc_mref(brick, &input->mref_object_layout); + mref = if_alloc_mref(brick); if (unlikely(!mref)) { up(&input->kick_sem); goto err; diff --git a/mars_if.h b/mars_if.h index c39e9963..4da3af13 100644 --- a/mars_if.h +++ b/mars_if.h @@ -61,7 +61,6 @@ struct if_input { atomic_t total_mref_write_count; spinlock_t req_lock; struct semaphore kick_sem; - struct generic_object_layout mref_object_layout; struct mars_info info; spinlock_t hash_lock[IF_HASH_MAX]; struct list_head hash_table[IF_HASH_MAX]; diff --git a/mars_server.c b/mars_server.c index 3674d06e..c238b26a 100644 --- a/mars_server.c +++ b/mars_server.c @@ -145,7 +145,7 @@ int server_io(struct server_brick *brick, struct mars_socket *sock) if (!brick->cb_running || !mars_socket_is_alive(sock)) goto done; - mref = server_alloc_mref(brick, &brick->mref_object_layout); + mref = server_alloc_mref(brick); status = -ENOMEM; if (!mref) goto done; diff --git a/mars_server.h b/mars_server.h index d8c8bab3..31df1fab 100644 --- a/mars_server.h +++ b/mars_server.h @@ -26,7 +26,6 @@ struct server_brick { struct task_struct *cb_thread; wait_queue_head_t startup_event; wait_queue_head_t cb_event; - struct generic_object_layout mref_object_layout; spinlock_t cb_lock; struct list_head cb_read_list; struct list_head cb_write_list; diff --git a/mars_trans_logger.c b/mars_trans_logger.c index b1651d9d..71b168b4 100644 --- a/mars_trans_logger.c +++ b/mars_trans_logger.c @@ -1040,7 +1040,7 @@ struct writeback_info *make_writeback(struct trans_logger_brick *brick, loff_t p int this_len; int status; - sub_mref = trans_logger_alloc_mref(brick, &read_input->sub_layout); + sub_mref = trans_logger_alloc_mref(brick); if (unlikely(!sub_mref)) { MARS_FAT("cannot alloc sub_mref\n"); goto err; @@ -1106,7 +1106,7 @@ struct writeback_info *make_writeback(struct trans_logger_brick *brick, loff_t p } data = orig_mref_a->shadow_data + diff; - sub_mref = trans_logger_alloc_mref(brick, &write_input->sub_layout); + sub_mref = trans_logger_alloc_mref(brick); if (unlikely(!sub_mref)) { MARS_FAT("cannot alloc sub_mref\n"); goto err; @@ -2257,7 +2257,7 @@ int apply_data(struct trans_logger_brick *brick, loff_t pos, void *buf, int len) struct trans_logger_mref_aspect *mref_a; status = -ENOMEM; - mref = trans_logger_alloc_mref(brick, &input->sub_layout); + mref = trans_logger_alloc_mref(brick); if (unlikely(!mref)) { MARS_ERR("no memory\n"); goto done; @@ -2497,13 +2497,14 @@ char *trans_logger_statistics(struct trans_logger_brick *brick, int verbose) if (!res) return NULL; - snprintf(res, 1023, "mode replay=%d continuous=%d replay_code=%d log_reads=%d | replay_start_pos = %lld replay_end_pos = %lld | new_input_nr = %d log_input_nr = %d (old = %d) replay_min_pos1 = %lld replay_max_pos1 = %lld replay_min_pos2 = %lld replay_max_pos2 = %lld | total replay=%d callbacks=%d reads=%d writes=%d flushes=%d (%d%%) wb_clusters=%d writebacks=%d (%d%%) shortcut=%d (%d%%) mshadow=%d sshadow=%d rounds=%d restarts=%d delays=%d phase1=%d phase2=%d phase3=%d phase4=%d | current shadow_mem_used=%ld/%lld replay=%d mshadow=%d/%d sshadow=%d hash_count=%d pos_count=%d balance=%d/%d/%d/%d fly=%d phase1=%d+%d phase2=%d+%d phase3=%d+%d phase4=%d+%d\n", + snprintf(res, 1023, "mode replay=%d continuous=%d replay_code=%d log_reads=%d | replay_start_pos = %lld replay_end_pos = %lld | new_input_nr = %d log_input_nr = %d (old = %d) replay_min_pos1 = %lld replay_max_pos1 = %lld replay_min_pos2 = %lld replay_max_pos2 = %lld | total replay=%d callbacks=%d reads=%d writes=%d flushes=%d (%d%%) wb_clusters=%d writebacks=%d (%d%%) shortcut=%d (%d%%) mshadow=%d sshadow=%d rounds=%d restarts=%d delays=%d phase1=%d phase2=%d phase3=%d phase4=%d | current #mrefs = %d shadow_mem_used=%ld/%lld replay=%d mshadow=%d/%d sshadow=%d hash_count=%d pos_count=%d balance=%d/%d/%d/%d fly=%d phase1=%d+%d phase2=%d+%d phase3=%d+%d phase4=%d+%d\n", brick->do_replay, brick->do_continuous_replay, brick->replay_code, brick->log_reads, brick->replay_start_pos, brick->replay_end_pos, brick->new_input_nr, brick->log_input_nr, brick->old_input_nr, brick->inputs[TL_INPUT_LOG1]->replay_min_pos, brick->inputs[TL_INPUT_LOG1]->replay_max_pos, brick->inputs[TL_INPUT_LOG2]->replay_min_pos, brick->inputs[TL_INPUT_LOG2]->replay_max_pos, atomic_read(&brick->total_replay_count), atomic_read(&brick->total_cb_count), atomic_read(&brick->total_read_count), atomic_read(&brick->total_write_count), atomic_read(&brick->total_flush_count), atomic_read(&brick->total_write_count) ? atomic_read(&brick->total_flush_count) * 100 / atomic_read(&brick->total_write_count) : 0, atomic_read(&brick->total_writeback_cluster_count), atomic_read(&brick->total_writeback_count), atomic_read(&brick->total_writeback_cluster_count) ? atomic_read(&brick->total_writeback_count) * 100 / atomic_read(&brick->total_writeback_cluster_count) : 0, atomic_read(&brick->total_shortcut_count), atomic_read(&brick->total_writeback_count) ? atomic_read(&brick->total_shortcut_count) * 100 / atomic_read(&brick->total_writeback_count) : 0, atomic_read(&brick->total_mshadow_count), atomic_read(&brick->total_sshadow_count), atomic_read(&brick->total_round_count), atomic_read(&brick->total_restart_count), atomic_read(&brick->total_delay_count), atomic_read(&brick->q_phase1.q_total), atomic_read(&brick->q_phase2.q_total), atomic_read(&brick->q_phase3.q_total), atomic_read(&brick->q_phase4.q_total), + atomic_read(&brick->mref_object_layout.alloc_count), atomic64_read(&brick->shadow_mem_used), brick_global_memlimit, atomic_read(&brick->replay_count), atomic_read(&brick->mshadow_count), brick->shadow_mem_limit, atomic_read(&brick->sshadow_count), atomic_read(&brick->hash_count), atomic_read(&brick->pos_count), atomic_read(&brick->sub_balance_count), atomic_read(&brick->inner_balance_count), atomic_read(&brick->outer_balance_count), atomic_read(&brick->wb_balance_count), atomic_read(&brick->fly_count), atomic_read(&brick->q_phase1.q_queued), atomic_read(&brick->q_phase1.q_flying), atomic_read(&brick->q_phase2.q_queued), atomic_read(&brick->q_phase2.q_flying), atomic_read(&brick->q_phase3.q_queued), atomic_read(&brick->q_phase3.q_flying), atomic_read(&brick->q_phase4.q_queued), atomic_read(&brick->q_phase4.q_flying)); return res; } diff --git a/mars_trans_logger.h b/mars_trans_logger.h index cef8ddd0..f7124f98 100644 --- a/mars_trans_logger.h +++ b/mars_trans_logger.h @@ -191,7 +191,6 @@ struct trans_logger_input { bool is_operating; // private - struct generic_object_layout sub_layout; struct log_status logst; spinlock_t pos_lock; struct list_head pos_list; diff --git a/mars_usebuf.c b/mars_usebuf.c index 4af3879b..bd357a88 100644 --- a/mars_usebuf.c +++ b/mars_usebuf.c @@ -130,7 +130,7 @@ static int usebuf_ref_get(struct usebuf_output *output, struct mref_object *mref sub_mref_a = mref_a->sub_mref_a; if (!sub_mref_a) { - sub_mref = usebuf_alloc_mref(output->brick, &output->mref_object_layout); + sub_mref = usebuf_alloc_mref(output->brick); if (unlikely(!sub_mref)) { MARS_FAT("cannot get sub_mref\n"); return -ENOMEM; diff --git a/mars_usebuf.h b/mars_usebuf.h index 03685ff5..1897024f 100644 --- a/mars_usebuf.h +++ b/mars_usebuf.h @@ -21,7 +21,6 @@ struct usebuf_input { struct usebuf_output { MARS_OUTPUT(usebuf); - struct generic_object_layout mref_object_layout; }; MARS_TYPES(usebuf); diff --git a/sy_old/sy_generic.c b/sy_old/sy_generic.c index 34c05598..2261e1d6 100644 --- a/sy_old/sy_generic.c +++ b/sy_old/sy_generic.c @@ -864,6 +864,7 @@ int mars_free_brick(struct mars_brick *brick) { struct mars_global *global; int i; + int count; int status; if (!brick) { @@ -873,7 +874,7 @@ int mars_free_brick(struct mars_brick *brick) } if (!brick->power.force_off || !brick->power.led_off) { - MARS_DBG("brick '%s' is not freeable\n", brick->brick_path); + MARS_WRN("brick '%s' is not freeable\n", brick->brick_path); status = -ETXTBSY; goto done; } @@ -882,12 +883,17 @@ int mars_free_brick(struct mars_brick *brick) for (i = 0; i < brick->type->max_outputs; i++) { struct mars_output *output = brick->outputs[i]; if (output && output->nr_connected > 0) { - MARS_DBG("brick '%s' not freeable, output %i is used\n", brick->brick_path, i); + MARS_WRN("brick '%s' not freeable, output %i is used\n", brick->brick_path, i); status = -EEXIST; goto done; } } + count = atomic_read(&brick->mref_object_layout.alloc_count); + if (count > 0) { + MARS_ERR("MEMLEAK: brick '%s' has %d mrefs allocated (total = %d)\n", brick->brick_path, count, atomic_read(&brick->mref_object_layout.total_alloc_count)); + } + MARS_DBG("===> freeing brick name = '%s' path = '%s'\n", brick->brick_name, brick->brick_path); global = brick->global; @@ -906,18 +912,14 @@ int mars_free_brick(struct mars_brick *brick) } } -#ifndef MEMLEAK // TODO: check whether crash remains possible MARS_DBG("deallocate name = '%s' path = '%s'\n", SAFE_STR(brick->brick_name), SAFE_STR(brick->brick_path)); brick_string_free(brick->brick_name); brick_string_free(brick->brick_path); -#endif status = generic_brick_exit_full((void*)brick); if (status >= 0) { -#ifndef MEMLEAK // TODO: check whether crash remains possible brick_mem_free(brick); -#endif mars_trigger(); } else { MARS_ERR("error freeing brick, status = %d\n", status);