2010-06-14 14:27:40 +00:00
|
|
|
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
|
|
|
|
|
2010-07-23 11:55:18 +00:00
|
|
|
//#define BRICK_DEBUGGING
|
|
|
|
//#define MARS_DEBUGGING
|
|
|
|
|
2010-08-20 10:58:24 +00:00
|
|
|
#define DEFAULT_ORDER 0
|
2010-08-27 13:17:04 +00:00
|
|
|
//#define DEFAULT_BUFFERS (32768 / 2)
|
2010-11-26 13:45:10 +00:00
|
|
|
//#define DEFAULT_MEM (1024 / 4 * 1024)
|
|
|
|
#define DEFAULT_MEM (1024 / 4 * 1024 / 4)
|
2010-08-20 10:58:24 +00:00
|
|
|
|
2010-08-27 15:42:10 +00:00
|
|
|
#define TRANS_ORDER 4
|
2010-08-23 05:06:06 +00:00
|
|
|
#define TRANS_BUFFERS (32)
|
2010-08-20 10:58:24 +00:00
|
|
|
#define TRANS_MEM (1024 / 4)
|
|
|
|
|
2010-10-22 12:00:08 +00:00
|
|
|
//#define CONF_TEST // use intermediate mars_check bricks
|
2010-11-26 13:45:10 +00:00
|
|
|
|
|
|
|
#define CONF_AIO // use device_aio instead of device_sio
|
2010-12-10 17:40:20 +00:00
|
|
|
#define CONF_BUF
|
|
|
|
#define CONF_BUF_AHEAD // readahead optimization
|
|
|
|
#define CONF_USEBUF
|
2010-11-26 13:45:10 +00:00
|
|
|
//#define CONF_TRANS
|
2010-11-12 11:18:40 +00:00
|
|
|
//#define CONF_TRANS_FLYING 1
|
|
|
|
#define CONF_TRANS_SORT
|
2010-11-26 13:45:10 +00:00
|
|
|
//#define CONF_DIRECT // use O_DIRECT
|
|
|
|
#define CONF_FDSYNC // use additional aio_fdsync
|
|
|
|
|
|
|
|
#define DIRECT
|
2010-08-20 10:58:24 +00:00
|
|
|
|
2010-06-14 14:27:40 +00:00
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/string.h>
|
2010-12-10 17:40:20 +00:00
|
|
|
#include <linux/debug_locks.h>
|
2010-06-14 14:27:40 +00:00
|
|
|
|
|
|
|
#include <linux/major.h>
|
|
|
|
#include <linux/genhd.h>
|
|
|
|
#include <linux/blkdev.h>
|
|
|
|
|
|
|
|
#define _STRATEGY
|
|
|
|
#include "mars.h"
|
|
|
|
|
|
|
|
#include "mars_if_device.h"
|
2010-08-03 16:03:32 +00:00
|
|
|
#include "mars_check.h"
|
2010-06-15 18:31:06 +00:00
|
|
|
#include "mars_device_sio.h"
|
2010-11-26 13:45:10 +00:00
|
|
|
#include "mars_device_aio.h"
|
2010-07-23 11:55:18 +00:00
|
|
|
#include "mars_buf.h"
|
2010-07-30 05:46:22 +00:00
|
|
|
#include "mars_usebuf.h"
|
2010-08-20 10:58:24 +00:00
|
|
|
#include "mars_trans_logger.h"
|
2010-06-14 14:27:40 +00:00
|
|
|
|
2010-08-05 15:54:48 +00:00
|
|
|
GENERIC_ASPECT_FUNCTIONS(generic,mars_ref);
|
2010-08-04 22:38:48 +00:00
|
|
|
|
2010-11-26 13:45:10 +00:00
|
|
|
#ifdef CONF_AIO
|
|
|
|
#define device_sio_brick device_aio_brick
|
|
|
|
#define device_sio_brick_type device_aio_brick_type
|
|
|
|
#endif
|
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
static struct generic_brick *if_brick = NULL;
|
2010-08-10 17:39:30 +00:00
|
|
|
static struct if_device_brick *_if_brick = NULL;
|
2010-08-04 22:38:48 +00:00
|
|
|
static struct generic_brick *usebuf_brick = NULL;
|
2010-08-20 10:58:24 +00:00
|
|
|
|
|
|
|
static struct generic_brick *trans_brick = NULL;
|
2010-08-23 05:06:06 +00:00
|
|
|
static struct trans_logger_brick *_trans_brick = NULL;
|
2010-08-20 10:58:24 +00:00
|
|
|
static struct generic_brick *tbuf_brick = NULL;
|
|
|
|
static struct buf_brick *_tbuf_brick = NULL;
|
|
|
|
static struct generic_brick *tdevice_brick = NULL;
|
2010-10-22 12:00:08 +00:00
|
|
|
static struct device_sio_brick *_tdevice_brick = NULL;
|
2010-08-20 10:58:24 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
static struct generic_brick *buf_brick = NULL;
|
|
|
|
static struct buf_brick *_buf_brick = NULL;
|
|
|
|
static struct generic_brick *device_brick = NULL;
|
2010-10-22 12:00:08 +00:00
|
|
|
static struct device_sio_brick *_device_brick = NULL;
|
2010-06-14 14:27:40 +00:00
|
|
|
|
2010-08-08 14:02:54 +00:00
|
|
|
static void test_endio(struct generic_callback *cb)
|
2010-07-23 11:55:18 +00:00
|
|
|
{
|
2010-08-08 14:02:54 +00:00
|
|
|
MARS_DBG("test_endio() called! error=%d\n", cb->cb_error);
|
2010-07-23 11:55:18 +00:00
|
|
|
}
|
|
|
|
|
2010-06-14 14:27:40 +00:00
|
|
|
void make_test_instance(void)
|
|
|
|
{
|
|
|
|
static char *names[] = { "brick" };
|
2010-08-04 22:38:48 +00:00
|
|
|
struct generic_input *last = NULL;
|
|
|
|
|
|
|
|
void *brick(const void *_brick_type)
|
|
|
|
{
|
|
|
|
const struct generic_brick_type *brick_type = _brick_type;
|
2010-08-05 08:36:36 +00:00
|
|
|
const struct generic_input_type **input_types;
|
|
|
|
const struct generic_output_type **output_types;
|
|
|
|
void *mem;
|
|
|
|
int size;
|
|
|
|
int i;
|
2010-08-04 22:38:48 +00:00
|
|
|
int status;
|
2010-08-05 08:36:36 +00:00
|
|
|
|
|
|
|
size = brick_type->brick_size +
|
|
|
|
(brick_type->max_inputs + brick_type->max_outputs) * sizeof(void*);
|
|
|
|
input_types = brick_type->default_input_types;
|
|
|
|
for (i = 0; i < brick_type->max_inputs; i++) {
|
|
|
|
const struct generic_input_type *type = *input_types++;
|
|
|
|
size += type->input_size;
|
|
|
|
}
|
|
|
|
output_types = brick_type->default_output_types;
|
|
|
|
for (i = 0; i < brick_type->max_outputs; i++) {
|
|
|
|
const struct generic_output_type *type = *output_types++;
|
|
|
|
size += type->output_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
mem = kzalloc(size, GFP_MARS);
|
2010-08-04 22:38:48 +00:00
|
|
|
if (!mem) {
|
2010-08-05 08:36:36 +00:00
|
|
|
MARS_ERR("cannot grab test memory for %s\n", brick_type->type_name);
|
|
|
|
msleep(60000);
|
2010-08-04 22:38:48 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2010-08-05 08:36:36 +00:00
|
|
|
status = generic_brick_init_full(mem, size, brick_type, NULL, NULL, names);
|
2010-08-20 10:58:24 +00:00
|
|
|
MARS_INF("init '%s' (status=%d)\n", brick_type->type_name, status);
|
2010-08-04 22:38:48 +00:00
|
|
|
if (status) {
|
2010-08-05 08:36:36 +00:00
|
|
|
MARS_ERR("cannot init brick %s\n", brick_type->type_name);
|
|
|
|
msleep(60000);
|
2010-08-04 22:38:48 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return mem;
|
2010-07-23 11:55:18 +00:00
|
|
|
}
|
2010-06-14 14:27:40 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
void connect(struct generic_input *a, struct generic_output *b)
|
|
|
|
{
|
2010-08-05 08:36:36 +00:00
|
|
|
int status;
|
2010-08-20 10:58:24 +00:00
|
|
|
#ifdef CONF_TEST
|
2010-08-05 08:36:36 +00:00
|
|
|
struct generic_brick *tmp = brick(&check_brick_type);
|
|
|
|
|
|
|
|
status = generic_connect(a, tmp->outputs[0]);
|
|
|
|
MARS_DBG("connect (status=%d)\n", status);
|
|
|
|
if (status < 0)
|
|
|
|
msleep(60000);
|
|
|
|
|
|
|
|
status = generic_connect(tmp->inputs[0], b);
|
|
|
|
#else
|
|
|
|
status = generic_connect(a, b);
|
|
|
|
#endif
|
2010-08-04 22:38:48 +00:00
|
|
|
MARS_DBG("connect (status=%d)\n", status);
|
2010-08-05 08:36:36 +00:00
|
|
|
if (status < 0)
|
|
|
|
msleep(60000);
|
2010-06-14 14:27:40 +00:00
|
|
|
}
|
2010-07-23 11:55:18 +00:00
|
|
|
|
2010-07-30 05:46:22 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
MARS_DBG("starting....\n");
|
2010-07-30 05:46:22 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
device_brick = brick(&device_sio_brick_type);
|
2010-10-22 12:00:08 +00:00
|
|
|
_device_brick = (void*)device_brick;
|
2010-08-20 10:58:24 +00:00
|
|
|
device_brick->outputs[0]->output_name = "/tmp/testfile.img";
|
2010-10-22 12:00:08 +00:00
|
|
|
#ifdef CONF_DIRECT
|
|
|
|
_device_brick->outputs[0]->o_direct = true;
|
|
|
|
#endif
|
2010-11-26 13:45:10 +00:00
|
|
|
#ifdef CONF_FDSYNC
|
|
|
|
_device_brick->outputs[0]->o_fdsync = true;
|
2010-10-22 12:00:08 +00:00
|
|
|
#endif
|
2010-08-20 10:58:24 +00:00
|
|
|
device_brick->ops->brick_switch(device_brick, true);
|
2010-08-03 16:03:32 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
if_brick = brick(&if_device_brick_type);
|
2010-08-03 16:03:32 +00:00
|
|
|
|
2010-12-10 17:40:20 +00:00
|
|
|
#ifdef CONF_USEBUF // usebuf zwischenschalten
|
2010-08-04 22:38:48 +00:00
|
|
|
usebuf_brick = brick(&usebuf_brick_type);
|
|
|
|
|
|
|
|
connect(if_brick->inputs[0], usebuf_brick->outputs[0]);
|
|
|
|
last = usebuf_brick->inputs[0];
|
2010-07-30 05:46:22 +00:00
|
|
|
#else
|
|
|
|
(void)usebuf_brick;
|
2010-11-26 13:45:10 +00:00
|
|
|
(void)tdevice_brick;
|
|
|
|
(void)_tdevice_brick;
|
2010-08-04 22:38:48 +00:00
|
|
|
last = if_brick->inputs[0];
|
2010-07-30 05:46:22 +00:00
|
|
|
#endif
|
|
|
|
|
2010-08-20 10:58:24 +00:00
|
|
|
#ifdef CONF_BUF // Standard-buf zwischenschalten
|
2010-08-06 11:29:06 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
buf_brick = brick(&buf_brick_type);
|
|
|
|
_buf_brick = (void*)buf_brick;
|
2010-08-20 10:58:24 +00:00
|
|
|
_buf_brick->outputs[0]->output_name = "/tmp/testfile.img";
|
|
|
|
_buf_brick->backing_order = DEFAULT_ORDER;
|
2010-08-04 22:38:48 +00:00
|
|
|
_buf_brick->backing_size = PAGE_SIZE << _buf_brick->backing_order;
|
2010-08-20 10:58:24 +00:00
|
|
|
#ifdef DEFAULT_BUFFERS
|
|
|
|
_buf_brick->max_count = DEFAULT_BUFFERS;
|
2010-08-09 16:57:56 +00:00
|
|
|
#else
|
2010-08-20 10:58:24 +00:00
|
|
|
_buf_brick->max_count = DEFAULT_MEM >> _buf_brick->backing_order;
|
2010-08-09 16:57:56 +00:00
|
|
|
#endif
|
2010-12-10 17:40:20 +00:00
|
|
|
#ifdef CONF_BUF_AHEAD
|
|
|
|
_buf_brick->optimize_chains = true;
|
|
|
|
#endif
|
2010-07-23 11:55:18 +00:00
|
|
|
|
2010-08-04 22:38:48 +00:00
|
|
|
connect(buf_brick->inputs[0], device_brick->outputs[0]);
|
2010-07-23 11:55:18 +00:00
|
|
|
|
2010-08-20 10:58:24 +00:00
|
|
|
#ifdef CONF_TRANS // trans_logger plus Infrastruktur zwischenschalten
|
|
|
|
|
|
|
|
tdevice_brick = brick(&device_sio_brick_type);
|
2010-10-22 12:00:08 +00:00
|
|
|
_tdevice_brick = (void*)tdevice_brick;
|
2010-08-20 10:58:24 +00:00
|
|
|
tdevice_brick->outputs[0]->output_name = "/tmp/testfile.log";
|
2010-10-22 12:00:08 +00:00
|
|
|
#ifdef CONF_DIRECT
|
|
|
|
_tdevice_brick->outputs[0]->o_direct = true;
|
|
|
|
#endif
|
2010-11-26 13:45:10 +00:00
|
|
|
#ifdef CONF_FDSYNC
|
|
|
|
_tdevice_brick->outputs[0]->o_fdsync = true;
|
2010-10-22 12:00:08 +00:00
|
|
|
#endif
|
2010-08-20 10:58:24 +00:00
|
|
|
tdevice_brick->ops->brick_switch(tdevice_brick, true);
|
|
|
|
|
|
|
|
tbuf_brick = brick(&buf_brick_type);
|
|
|
|
_tbuf_brick = (void*)tbuf_brick;
|
|
|
|
_tbuf_brick->outputs[0]->output_name = "/tmp/testfile.log";
|
|
|
|
_tbuf_brick->backing_order = TRANS_ORDER;
|
|
|
|
_tbuf_brick->backing_size = PAGE_SIZE << _tbuf_brick->backing_order;
|
|
|
|
#ifdef TRANS_BUFFERS
|
|
|
|
_tbuf_brick->max_count = TRANS_BUFFERS;
|
|
|
|
#else
|
|
|
|
_tbuf_brick->max_count = TRANS_MEM >> _tbuf_brick->backing_order;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
connect(tbuf_brick->inputs[0], tdevice_brick->outputs[0]);
|
|
|
|
|
|
|
|
trans_brick = brick(&trans_logger_brick_type);
|
2010-08-23 05:06:06 +00:00
|
|
|
_trans_brick = (void*)trans_brick;
|
2010-08-23 15:52:42 +00:00
|
|
|
//_trans_brick->log_reads = true;
|
|
|
|
_trans_brick->log_reads = false;
|
|
|
|
_trans_brick->allow_reads_after = HZ;
|
2010-08-23 05:06:06 +00:00
|
|
|
_trans_brick->max_queue = 1000;
|
2010-11-12 11:18:40 +00:00
|
|
|
#ifdef CONF_TRANS_FLYING
|
|
|
|
_trans_brick->outputs[0]->q_phase2.q_max_flying = CONF_TRANS_FLYING;
|
|
|
|
_trans_brick->outputs[0]->q_phase4.q_max_flying = CONF_TRANS_FLYING;
|
|
|
|
#endif
|
|
|
|
#ifdef CONF_TRANS_SORT
|
|
|
|
_trans_brick->outputs[0]->q_phase2.q_ordering = true;
|
|
|
|
_trans_brick->outputs[0]->q_phase4.q_ordering = true;
|
|
|
|
#endif
|
2010-08-20 10:58:24 +00:00
|
|
|
|
|
|
|
connect(trans_brick->inputs[0], buf_brick->outputs[0]);
|
|
|
|
connect(trans_brick->inputs[1], tbuf_brick->outputs[0]);
|
|
|
|
|
|
|
|
connect(last, trans_brick->outputs[0]);
|
2010-11-26 13:45:10 +00:00
|
|
|
#else // CONF_TRANS
|
2010-08-20 10:58:24 +00:00
|
|
|
(void)trans_brick;
|
2010-08-27 07:20:26 +00:00
|
|
|
(void)_trans_brick;
|
2010-08-20 10:58:24 +00:00
|
|
|
(void)tbuf_brick;
|
|
|
|
(void)_tbuf_brick;
|
|
|
|
(void)tdevice_brick;
|
|
|
|
connect(last, buf_brick->outputs[0]);
|
2010-11-26 13:45:10 +00:00
|
|
|
#endif // CONF_TRANS
|
2010-08-20 10:58:24 +00:00
|
|
|
|
2010-08-05 15:54:48 +00:00
|
|
|
if (false) { // ref-counting no longer valid
|
2010-08-04 22:38:48 +00:00
|
|
|
struct buf_output *output = _buf_brick->outputs[0];
|
2010-08-05 15:54:48 +00:00
|
|
|
struct mars_ref_object *mref = NULL;
|
2010-08-01 20:21:18 +00:00
|
|
|
struct generic_object_layout ol = {};
|
2010-07-23 11:55:18 +00:00
|
|
|
|
2010-08-05 15:54:48 +00:00
|
|
|
mref = generic_alloc_mars_ref((struct generic_output*)output, &ol);
|
2010-07-23 11:55:18 +00:00
|
|
|
|
2010-08-05 15:54:48 +00:00
|
|
|
if (mref) {
|
2010-08-04 22:38:48 +00:00
|
|
|
int status;
|
2010-08-05 15:54:48 +00:00
|
|
|
mref->ref_pos = 0;
|
|
|
|
mref->ref_len = PAGE_SIZE;
|
|
|
|
mref->ref_may_write = READ;
|
2010-08-02 16:31:10 +00:00
|
|
|
|
2010-08-05 15:54:48 +00:00
|
|
|
status = GENERIC_OUTPUT_CALL(output, mars_ref_get, mref);
|
2010-08-02 16:31:10 +00:00
|
|
|
MARS_DBG("buf_get (status=%d)\n", status);
|
2010-07-23 11:55:18 +00:00
|
|
|
if (true) {
|
2010-08-08 14:02:54 +00:00
|
|
|
struct generic_callback cb = {
|
|
|
|
.cb_fn = test_endio,
|
|
|
|
};
|
|
|
|
mref->ref_cb = &cb;
|
2010-07-30 11:50:20 +00:00
|
|
|
|
2010-12-10 17:40:20 +00:00
|
|
|
GENERIC_OUTPUT_CALL(output, mars_ref_io, mref);
|
2010-08-08 14:02:54 +00:00
|
|
|
status = cb.cb_error;
|
2010-07-23 11:55:18 +00:00
|
|
|
MARS_DBG("buf_io (status=%d)\n", status);
|
|
|
|
}
|
2010-08-05 15:54:48 +00:00
|
|
|
GENERIC_OUTPUT_CALL(output, mars_ref_put, mref);
|
2010-07-23 11:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-26 13:45:10 +00:00
|
|
|
|
|
|
|
#else // CONF_BUF
|
|
|
|
|
|
|
|
(void)trans_brick;
|
|
|
|
(void)_trans_brick;
|
|
|
|
(void)buf_brick;
|
|
|
|
(void)_buf_brick;
|
|
|
|
(void)tbuf_brick;
|
|
|
|
(void)_tbuf_brick;
|
|
|
|
(void)tdevice_brick;
|
|
|
|
(void)_tdevice_brick;
|
2010-08-04 17:32:04 +00:00
|
|
|
(void)test_endio;
|
2010-08-04 22:38:48 +00:00
|
|
|
connect(last, device_brick->outputs[0]);
|
2010-11-26 13:45:10 +00:00
|
|
|
|
|
|
|
#endif // CONF_BUF
|
2010-08-10 17:39:30 +00:00
|
|
|
|
|
|
|
msleep(200);
|
|
|
|
|
|
|
|
MARS_INF("------------- END INIT --------------\n");
|
|
|
|
|
|
|
|
_if_brick = (void*)if_brick;
|
2010-08-27 07:20:26 +00:00
|
|
|
{
|
|
|
|
struct mars_info info = {};
|
|
|
|
int status = GENERIC_INPUT_CALL(_if_brick->inputs[0], mars_get_info, &info);
|
|
|
|
MARS_INF("INFO status=%d size=%lld transfer_order=%d transfer_size=%d %p\n", status, info.current_size, info.transfer_order, info.transfer_size, info.backing_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
MARS_INF("------------- START GATE --------------\n");
|
|
|
|
|
|
|
|
_if_brick->ops->brick_switch(_if_brick, true);
|
2010-08-26 17:12:30 +00:00
|
|
|
//_if_brick->is_active = true;
|
2010-08-10 17:39:30 +00:00
|
|
|
|
2010-08-07 07:59:34 +00:00
|
|
|
msleep(2000);
|
2010-08-05 08:36:36 +00:00
|
|
|
MARS_INF("------------- DONE --------------\n");
|
2010-11-26 13:45:10 +00:00
|
|
|
//msleep(1000 * 92);
|
|
|
|
// FIXME: this is never released!
|
|
|
|
atomic_inc(¤t->mm->mm_users);
|
2010-06-14 14:27:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void destroy_test_instance(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit exit_test(void)
|
|
|
|
{
|
|
|
|
MARS_DBG("destroy_test_instance()\n");
|
|
|
|
destroy_test_instance();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __init init_test(void)
|
|
|
|
{
|
|
|
|
MARS_DBG("make_test_instance()\n");
|
2010-12-10 17:40:20 +00:00
|
|
|
#if 0
|
|
|
|
debug_locks_off();
|
|
|
|
#endif
|
2010-06-14 14:27:40 +00:00
|
|
|
make_test_instance();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
MODULE_DESCRIPTION("MARS TEST");
|
|
|
|
MODULE_AUTHOR("Thomas Schoebel-Theuer <tst@1und1.de>");
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
|
|
|
module_init(init_test);
|
|
|
|
module_exit(exit_test);
|