2010-08-08 20:51:20 +00:00
|
|
|
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
|
|
|
|
#ifndef MARS_TRANS_LOGGER_H
|
|
|
|
#define MARS_TRANS_LOGGER_H
|
|
|
|
|
|
|
|
#define REGION_SIZE_BITS 22
|
|
|
|
#define REGION_SIZE (1 << REGION_SIZE_BITS)
|
2011-04-01 11:18:32 +00:00
|
|
|
#define TRANS_HASH_MAX 512
|
2010-08-08 20:51:20 +00:00
|
|
|
|
2010-08-11 16:02:08 +00:00
|
|
|
#include <linux/time.h>
|
2011-04-18 09:23:04 +00:00
|
|
|
|
|
|
|
#include "lib_log.h"
|
|
|
|
#include "lib_pairing_heap.h"
|
2010-08-08 20:51:20 +00:00
|
|
|
|
2010-08-11 16:02:08 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2010-11-12 11:18:40 +00:00
|
|
|
_PAIRING_HEAP_TYPEDEF(mref,)
|
|
|
|
|
2010-08-11 16:02:08 +00:00
|
|
|
struct logger_queue {
|
2011-03-18 13:15:40 +00:00
|
|
|
struct logger_queue *q_dep;
|
2011-04-12 15:31:08 +00:00
|
|
|
atomic_t *q_dep_plus;
|
2011-03-18 13:15:40 +00:00
|
|
|
struct trans_logger_output *q_output;
|
2010-08-11 16:02:08 +00:00
|
|
|
struct list_head q_anchor;
|
2010-11-12 11:18:40 +00:00
|
|
|
struct pairing_heap_mref *heap_high;
|
|
|
|
struct pairing_heap_mref *heap_low;
|
2011-04-08 09:52:46 +00:00
|
|
|
loff_t heap_margin;
|
|
|
|
loff_t last_pos;
|
|
|
|
long long q_last_insert; // jiffies
|
2010-08-23 05:06:06 +00:00
|
|
|
spinlock_t q_lock;
|
|
|
|
atomic_t q_queued;
|
|
|
|
atomic_t q_flying;
|
2011-04-08 09:52:46 +00:00
|
|
|
atomic_t q_total;
|
2011-03-27 15:18:38 +00:00
|
|
|
const char *q_insert_info;
|
|
|
|
const char *q_pushback_info;
|
|
|
|
const char *q_fetch_info;
|
2010-11-12 11:18:40 +00:00
|
|
|
// tunables
|
2011-03-10 11:40:06 +00:00
|
|
|
int q_batchlen;
|
2010-12-15 11:58:22 +00:00
|
|
|
int q_max_queued;
|
2010-11-12 11:18:40 +00:00
|
|
|
int q_max_flying;
|
2010-12-15 11:58:22 +00:00
|
|
|
int q_max_jiffies;
|
2011-03-29 14:40:40 +00:00
|
|
|
int q_max_contention;
|
|
|
|
int q_over_pressure;
|
|
|
|
int q_io_prio;
|
2010-11-12 11:18:40 +00:00
|
|
|
bool q_ordering;
|
2010-08-08 20:51:20 +00:00
|
|
|
};
|
|
|
|
|
2010-08-11 16:02:08 +00:00
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
2010-08-08 20:51:20 +00:00
|
|
|
struct hash_anchor {
|
|
|
|
rwlock_t hash_lock;
|
|
|
|
struct list_head hash_anchor;
|
|
|
|
};
|
|
|
|
|
2011-04-08 09:52:46 +00:00
|
|
|
struct writeback_info {
|
2011-04-10 16:59:06 +00:00
|
|
|
struct trans_logger_output *w_output;
|
2011-04-08 09:52:46 +00:00
|
|
|
loff_t w_pos;
|
|
|
|
int w_len;
|
|
|
|
struct list_head w_collect_list; // list of collected orig requests
|
|
|
|
struct list_head w_sub_read_list; // for saving the old data before overwrite
|
|
|
|
struct list_head w_sub_write_list; // for overwriting
|
2011-04-10 16:59:06 +00:00
|
|
|
atomic_t w_sub_read_count;
|
|
|
|
atomic_t w_sub_write_count;
|
|
|
|
void (*read_endio)(struct generic_callback *cb);
|
|
|
|
void (*write_endio)(struct generic_callback *cb);
|
2011-04-08 09:52:46 +00:00
|
|
|
};
|
|
|
|
|
2010-12-15 12:13:18 +00:00
|
|
|
struct trans_logger_mref_aspect {
|
|
|
|
GENERIC_ASPECT(mref);
|
2010-12-15 11:58:22 +00:00
|
|
|
struct trans_logger_output *output;
|
2010-08-11 16:02:08 +00:00
|
|
|
struct list_head hash_head;
|
|
|
|
struct list_head q_head;
|
2011-03-20 17:38:08 +00:00
|
|
|
struct list_head pos_head;
|
2011-04-08 09:52:46 +00:00
|
|
|
struct list_head replay_head;
|
|
|
|
struct list_head collect_head;
|
2010-11-12 11:18:40 +00:00
|
|
|
struct pairing_heap_mref ph;
|
2010-12-15 12:13:18 +00:00
|
|
|
struct trans_logger_mref_aspect *shadow_ref;
|
2011-04-08 09:52:46 +00:00
|
|
|
void *shadow_data;
|
2011-04-01 11:18:32 +00:00
|
|
|
bool do_dealloc;
|
2011-04-08 09:52:46 +00:00
|
|
|
bool do_buffered;
|
2011-03-08 16:45:52 +00:00
|
|
|
bool is_hashed;
|
2011-04-08 09:52:46 +00:00
|
|
|
bool is_dirty;
|
2011-04-10 16:59:06 +00:00
|
|
|
bool is_collected;
|
2010-08-11 16:02:08 +00:00
|
|
|
struct timespec stamp;
|
2011-03-20 17:38:08 +00:00
|
|
|
loff_t log_pos;
|
2011-04-08 09:52:46 +00:00
|
|
|
loff_t fetch_margin;
|
2010-08-11 16:02:08 +00:00
|
|
|
struct generic_callback cb;
|
2010-12-15 12:13:18 +00:00
|
|
|
struct trans_logger_mref_aspect *orig_mref_a;
|
2011-04-10 16:59:06 +00:00
|
|
|
struct writeback_info *wb;
|
2011-04-08 09:52:46 +00:00
|
|
|
struct list_head sub_list;
|
|
|
|
struct list_head sub_head;
|
|
|
|
int total_sub_count;
|
|
|
|
atomic_t current_sub_count;
|
2010-08-11 16:02:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct trans_logger_brick {
|
|
|
|
MARS_BRICK(trans_logger);
|
2010-08-23 05:06:06 +00:00
|
|
|
// parameters
|
2011-02-23 20:48:06 +00:00
|
|
|
int sequence; // logfile sequence number
|
|
|
|
int limit_congest;// limit phase1 congestion.
|
2011-03-11 13:57:54 +00:00
|
|
|
int align_size; // alignment between requests
|
|
|
|
int chunk_size; // must be at least 8K (better 64k)
|
|
|
|
int flush_delay; // delayed firing of incomplete chunks
|
2011-02-23 20:48:06 +00:00
|
|
|
bool do_replay; // mode of operation
|
2011-04-08 09:52:46 +00:00
|
|
|
bool do_continuous_replay; // mode of operation
|
2011-02-23 20:48:06 +00:00
|
|
|
bool log_reads; // additionally log pre-images
|
2011-03-18 13:15:40 +00:00
|
|
|
bool debug_shortcut; // only for testing! never use in production!
|
2011-04-08 09:52:46 +00:00
|
|
|
loff_t replay_start_pos; // where to start replay
|
|
|
|
loff_t replay_end_pos; // end of replay
|
|
|
|
loff_t log_start_pos; // where to start logging
|
2011-02-23 20:48:06 +00:00
|
|
|
// readonly from outside
|
2011-04-08 09:52:46 +00:00
|
|
|
loff_t replay_pos; // current replay position (both in replay mode and in logging mode)
|
|
|
|
loff_t current_pos; // current logging position (usually ahead of replay_pos)
|
|
|
|
int replay_code; // replay errors (if any)
|
2011-03-20 17:38:08 +00:00
|
|
|
// private
|
2011-04-08 09:52:46 +00:00
|
|
|
loff_t old_margin;
|
2011-03-20 17:38:08 +00:00
|
|
|
struct log_status logst;
|
|
|
|
spinlock_t pos_lock;
|
2011-04-08 09:52:46 +00:00
|
|
|
spinlock_t replay_lock;
|
|
|
|
struct list_head pos_list;
|
|
|
|
struct list_head replay_list;
|
2010-08-11 16:02:08 +00:00
|
|
|
};
|
|
|
|
|
2010-08-08 20:51:20 +00:00
|
|
|
struct trans_logger_output {
|
|
|
|
MARS_OUTPUT(trans_logger);
|
2011-03-27 15:18:38 +00:00
|
|
|
atomic_t replay_count;
|
2010-08-26 17:12:30 +00:00
|
|
|
atomic_t fly_count;
|
2011-03-10 11:40:06 +00:00
|
|
|
atomic_t hash_count;
|
2011-03-08 16:45:52 +00:00
|
|
|
atomic_t mshadow_count;
|
|
|
|
atomic_t sshadow_count;
|
2011-03-10 11:40:06 +00:00
|
|
|
atomic_t outer_balance_count;
|
|
|
|
atomic_t inner_balance_count;
|
|
|
|
atomic_t sub_balance_count;
|
2011-04-10 16:59:06 +00:00
|
|
|
atomic_t wb_balance_count;
|
2011-03-18 13:15:40 +00:00
|
|
|
atomic_t total_read_count;
|
|
|
|
atomic_t total_write_count;
|
|
|
|
atomic_t total_writeback_count;
|
|
|
|
atomic_t total_shortcut_count;
|
2011-04-01 11:18:32 +00:00
|
|
|
atomic_t total_mshadow_count;
|
|
|
|
atomic_t total_sshadow_count;
|
2010-08-20 10:58:24 +00:00
|
|
|
struct task_struct *thread;
|
|
|
|
wait_queue_head_t event;
|
2011-04-11 13:40:06 +00:00
|
|
|
struct generic_object_layout writeback_layout;
|
2011-03-27 15:18:38 +00:00
|
|
|
struct generic_object_layout replay_layout;
|
2010-08-11 16:02:08 +00:00
|
|
|
// queues
|
|
|
|
struct logger_queue q_phase1;
|
|
|
|
struct logger_queue q_phase2;
|
|
|
|
struct logger_queue q_phase3;
|
2010-08-20 10:58:24 +00:00
|
|
|
struct logger_queue q_phase4;
|
2011-03-18 13:15:40 +00:00
|
|
|
bool did_pushback;
|
2011-03-10 11:40:06 +00:00
|
|
|
struct hash_anchor hash_table[TRANS_HASH_MAX];
|
2010-08-11 16:02:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct trans_logger_input {
|
|
|
|
MARS_INPUT(trans_logger);
|
2010-08-08 20:51:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
MARS_TYPES(trans_logger);
|
|
|
|
|
|
|
|
#endif
|