import mars-20.tgz

This commit is contained in:
Thomas Schoebel-Theuer 2010-08-03 17:03:32 +01:00
parent 807cd30eb9
commit 251ccafdb1
9 changed files with 470 additions and 99 deletions

View File

@ -2,7 +2,7 @@
# Makefile for MARS
#
obj-$(CONFIG_MARS) += brick.o mars_generic.o
obj-$(CONFIG_MARS) += brick.o mars_generic.o mars_check.o
obj-$(CONFIG_MARS_DUMMY) += mars_dummy.o
obj-$(CONFIG_MARS_IF_DEVICE) += mars_if_device.o
obj-$(CONFIG_MARS_DEVICE_SIO) += mars_device_sio.o

1
mars.h
View File

@ -52,6 +52,7 @@ struct mars_io_object_layout {
GENERIC_OBJECT(PREFIX); \
struct bio *orig_bio; \
int (*mars_endio)(struct mars_io_object *mio, int error); \
void *cb_private; \
struct mars_io_object {
MARS_IO_OBJECT(mars_io);

View File

@ -230,6 +230,7 @@ static int buf_buf_get(struct buf_output *output, struct mars_buf_object *mbuf)
unsigned long flags;
int status = -EILSEQ;
might_sleep();
buf_count = atomic_read(&mbuf->buf_count);
if (unlikely(buf_count != 0)) {
@ -239,7 +240,7 @@ static int buf_buf_get(struct buf_output *output, struct mars_buf_object *mbuf)
mbuf_a = buf_mars_buf_get_aspect(output, mbuf);
if (unlikely(!mbuf_a))
goto err_free;
goto done;
base_pos = mbuf->buf_pos & ~(loff_t)(brick->backing_size - 1);
base_offset = (mbuf->buf_pos - base_pos);
@ -264,11 +265,11 @@ static int buf_buf_get(struct buf_output *output, struct mars_buf_object *mbuf)
status = -ENOMEM;
bf = kzalloc(sizeof(struct buf_head), GFP_KERNEL);
if (!bf)
goto err_free;
goto done;
bf->bf_data = (void*)__get_free_pages(GFP_KERNEL, brick->backing_order);
if (!bf->bf_data)
goto err_free2;
goto err_free;
bf->bf_brick = brick;
atomic_set(&bf->bf_bio_count, 0);
@ -279,6 +280,7 @@ static int buf_buf_get(struct buf_output *output, struct mars_buf_object *mbuf)
INIT_LIST_HEAD(&bf->bf_again_write_pending_anchor);
traced_lock(&brick->buf_lock, flags);
brick->alloc_count++;
/* during the open lock, somebody might have raced
* against us at the same base_pos...
@ -313,9 +315,9 @@ static int buf_buf_get(struct buf_output *output, struct mars_buf_object *mbuf)
return mbuf->buf_len;
err_free2:
kfree(bf);
err_free:
kfree(bf);
done:
return status;
}
@ -341,12 +343,20 @@ static void _buf_buf_put(struct buf_head *bf)
* So this race is ok.
*/
bf_count = atomic_read(&bf->bf_count);
if (bf_count <= 0) {
if (likely(bf_count <= 0)) {
struct list_head *where = &brick->lru_anchor;
if (unlikely(bf_count < 0)) {
atomic_set(&bf->bf_count, 0);
MARS_ERR("bf_count UNDERRUN %d\n", bf_count);
}
#if 1
if (unlikely(!list_empty(&bf->bf_io_pending_anchor))) {
MARS_ERR("bf_io_pending_anchor is not empty!\n");
}
if (unlikely(!list_empty(&bf->bf_again_write_pending_anchor))) {
MARS_ERR("bf_again_write_pending_anchor is not empty!\n");
}
#endif
if (unlikely(!(bf->bf_flags & MARS_BUF_UPTODATE))) {
list_del_init(&bf->bf_hash_head);
brick->current_count--;
@ -354,7 +364,7 @@ static void _buf_buf_put(struct buf_head *bf)
}
list_del(&bf->bf_lru_head);
list_add(&bf->bf_lru_head, where);
}
} // else no harm can happen
// lru freeing (this is completeley independent from bf)
__lru_free(brick);
@ -503,6 +513,8 @@ static int _buf_make_bios(struct buf_brick *brick, struct buf_head *bf, void *st
continue;
}
/* Remember the number of bios we are submitting.
*/
atomic_inc(&bf->bf_bio_count);
MARS_DBG("starting buf IO mio=%p bio=%p bf=%p bf_count=%d bf_bio_count=%d\n", mio, mio->orig_bio, bf, atomic_read(&bf->bf_count), atomic_read(&bf->bf_bio_count));
@ -541,6 +553,9 @@ static void _buf_bio_callback(struct bio *bio, int code)
int old_flags;
unsigned long flags;
LIST_HEAD(tmp);
#if 1
int count = 0;
#endif
mio_a = bio->bi_private;
bf = mio_a->mia_bf;
@ -603,6 +618,11 @@ static void _buf_bio_callback(struct bio *bio, int code)
if (mbuf_a->bfa_bf != bf) {
MARS_ERR("bad pointers %p != %p\n", mbuf_a->bfa_bf, bf);
}
#if 1
if (!(++count % 100)) {
MARS_ERR("endless loop 1\n");
}
#endif
list_del_init(&mbuf_a->bfc_pending_head);
list_add_tail(&mbuf_a->bfc_pending_head, &bf->bf_io_pending_anchor);
@ -638,6 +658,11 @@ static void _buf_bio_callback(struct bio *bio, int code)
if (mbuf_a->bfa_bf != bf) {
MARS_ERR("bad pointers %p != %p\n", mbuf_a->bfa_bf, bf);
}
#if 1
if (!(++count % 100)) {
MARS_ERR("endless loop 2\n");
}
#endif
buf_count = atomic_read(&mbuf->buf_count);
if (buf_count <= 0) {
MARS_ERR("bad buf_count %d\n", buf_count);
@ -648,7 +673,6 @@ static void _buf_bio_callback(struct bio *bio, int code)
mbuf->buf_flags = bf->bf_flags;
mbuf->cb_error = bf->bf_bio_status;
mbuf_a->nr_io_pending--;
//traced_unlock(&brick->buf_lock, flags);
mbuf->cb_buf_endio(mbuf);
@ -657,21 +681,12 @@ static void _buf_bio_callback(struct bio *bio, int code)
_buf_buf_put(bf);
buf_free_mars_buf(mbuf);
}
//traced_lock(&brick->buf_lock, flags);
}
if (start_len) {
MARS_DBG("ATTENTION %d\n", start_len);
_buf_make_bios(brick, bf, start_data, start_pos, start_len, WRITE);
}
#if 0
// drop extra refcounts for pending IO
if (old_flags & MARS_BUF_READING)
_buf_buf_put(bf);
if (old_flags & MARS_BUF_WRITING)
_buf_buf_put(bf);
#endif
// drop the extra reference from above
_buf_buf_put(bf);
}
@ -764,7 +779,7 @@ static void buf_buf_io(struct buf_output *output, struct mars_buf_object *mbuf,
bf->bf_flags |= MARS_BUF_READING;
bf->bf_bio_status = 0;
// always read the whole buffer
// always read the whole buffer.
start_data = (void*)((unsigned long)mbuf->buf_data & ~(unsigned long)(brick->backing_size - 1));
start_pos = mbuf->buf_pos & ~(loff_t)(brick->backing_size - 1);
start_len = brick->backing_size;
@ -775,20 +790,23 @@ static void buf_buf_io(struct buf_output *output, struct mars_buf_object *mbuf,
mbuf->buf_flags = bf->bf_flags;
mbuf->cb_error = bf->bf_bio_status;
// grab an extra reference.
/* Grab an extra reference.
* This will be released later in _buf_bio_callback() after
* calling the callbacks.
*/
atomic_inc(&mbuf->buf_count);
traced_unlock(&brick->buf_lock, flags);
if (!start_len) {
// nothing to start
// nothing to start, IO is already started.
return;
}
status = _buf_make_bios(brick, bf, start_data, start_pos, start_len, rw);
if (likely(status >= 0)) {
/* no callback, this time.
* they will be called from _buf_bio_callback().
/* No immediate callback, this time.
* Callbacks will be called later from _buf_bio_callback().
*/
return;
}

302
mars_check.c Normal file
View File

@ -0,0 +1,302 @@
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
/* Check brick
* checks various semantic properties, uses watchdog to find lost callbacks.
*/
//#define BRICK_DEBUGGING
//#define MARS_DEBUGGING
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/kthread.h>
#include "mars.h"
///////////////////////// own type definitions ////////////////////////
#include "mars_check.h"
///////////////////////// own helper functions ////////////////////////
static int check_mars_endio(struct mars_io_object *mio, int error)
{
struct check_output *output = mio->cb_private;
struct check_mars_io_aspect *mio_a = NULL;
int status;
unsigned long flags;
if (!output) {
MARS_ERR("bad private on mio %p\n", mio);
goto regenerate;
}
mio_a = check_mars_io_get_aspect(output, mio);
traced_lock(&output->lock, flags);
if (list_empty(&mio_a->mio_head)) {
MARS_ERR("mio callback called twice on %p\n", mio);
}
list_del_init(&mio_a->mio_head);
//mio->cb_private = mio_a->old_private;
traced_unlock(&output->lock, flags);
mio_a->last_jiffies = jiffies;
regenerate:
status = mio_a->old_mars_endio(mio, error);
mio->cb_private = output;
return status;
}
static void check_buf_endio(struct mars_buf_object *mbuf)
{
struct check_output *output = mbuf->cb_private;
struct check_mars_buf_aspect *mbuf_a = check_mars_buf_get_aspect(output, mbuf);
unsigned long flags;
traced_lock(&output->lock, flags);
if (list_empty(&mbuf_a->mbuf_head)) {
MARS_ERR("mbuf callback called twice on %p\n", mbuf);
}
list_del_init(&mbuf_a->mbuf_head);
traced_unlock(&output->lock, flags);
mbuf->cb_private = mbuf_a->old_private;
mbuf_a->last_jiffies = jiffies;
mbuf_a->old_buf_endio(mbuf);
mbuf->cb_private = output;
}
static int check_watchdog(void *data)
{
struct check_output *output = data;
MARS_INF("watchdog has started.\n");
while (!kthread_should_stop()) {
struct list_head *h;
unsigned long flags;
unsigned long now;
msleep_interruptible(5000);
traced_lock(&output->lock, flags);
now = jiffies;
for (h = output->mio_anchor.next; h != &output->mio_anchor; h = h->next) {
struct check_mars_io_aspect *mio_a;
struct mars_io_object *mio;
unsigned long elapsed;
mio_a = container_of(h, struct check_mars_io_aspect, mio_head);
mio = mio_a->object;
elapsed = now - mio_a->last_jiffies;
if (elapsed > 10 * HZ) {
mio_a->last_jiffies = now;
MARS_ERR("instance %d: mio %p callback is missing for more than 10 seconds.\n", output->instance_nr, mio);
}
}
for (h = output->mbuf_anchor.next; h != &output->mbuf_anchor; h = h->next) {
struct check_mars_buf_aspect *mbuf_a;
struct mars_buf_object *mbuf;
unsigned long elapsed;
mbuf_a = container_of(h, struct check_mars_buf_aspect, mbuf_head);
mbuf = mbuf_a->object;
elapsed = now - mbuf_a->last_jiffies;
if (elapsed > 10 * HZ) {
mbuf_a->last_jiffies = now;
MARS_ERR("instance %d: mbuf %p callback is missing for more than 10 seconds.\n", output->instance_nr, mbuf);
}
}
traced_unlock(&output->lock, flags);
}
return 0;
}
////////////////// own brick / input / output operations //////////////////
static int check_io(struct check_output *output, struct mars_io_object *mio)
{
struct check_input *input = output->brick->inputs[0];
int status;
#if 0
struct check_mars_io_aspect *mio_a = check_mars_io_get_aspect(output, mio);
unsigned long flags;
traced_lock(&output->lock, flags);
if (!list_empty(&mio_a->mio_head)) {
MARS_ERR("multiple mars_endio() in parallel on %p\n", mio);
}
list_add_tail(&mio_a->mio_head, &output->mio_anchor);
if (mio->mars_endio != check_mars_endio) {
mio_a->old_mars_endio = mio->mars_endio;
mio->mars_endio = check_mars_endio;
}
mio_a->old_private = mio->cb_private;
mio->cb_private = output;
mio_a->last_jiffies = jiffies;
traced_unlock(&output->lock, flags);
#endif
status = GENERIC_INPUT_CALL(input, mars_io, mio);
#if 0
if (status < 0) { // revert. TODO: change semantics to callback _always_
traced_lock(&output->lock, flags);
list_del_init(&mio_a->mio_head);
traced_unlock(&output->lock, flags);
}
#endif
//mio->cb_private = mio_a->old_private;
return status;
}
static int check_get_info(struct check_output *output, struct mars_info *info)
{
struct check_input *input = output->brick->inputs[0];
return GENERIC_INPUT_CALL(input, mars_get_info, info);
}
static int check_buf_get(struct check_output *output, struct mars_buf_object *mbuf)
{
struct check_input *input = output->brick->inputs[0];
return GENERIC_INPUT_CALL(input, mars_buf_get, mbuf);
}
static void check_buf_put(struct check_output *output, struct mars_buf_object *mbuf)
{
struct check_input *input = output->brick->inputs[0];
GENERIC_INPUT_CALL(input, mars_buf_put, mbuf);
}
static void check_buf_io(struct check_output *output, struct mars_buf_object *mbuf, int rw)
{
struct check_input *input = output->brick->inputs[0];
struct check_mars_buf_aspect *mbuf_a = check_mars_buf_get_aspect(output, mbuf);
unsigned long flags;
traced_lock(&output->lock, flags);
if (!list_empty(&mbuf_a->mbuf_head)) {
MARS_ERR("instance %d: multiple buf_endio() in parallel on %p\n", output->instance_nr, mbuf);
}
list_add_tail(&mbuf_a->mbuf_head, &output->mbuf_anchor);
if (mbuf->cb_buf_endio != check_buf_endio) {
mbuf_a->old_buf_endio = mbuf->cb_buf_endio;
mbuf->cb_buf_endio = check_buf_endio;
mbuf_a->old_private = mbuf->cb_private;
mbuf->cb_private = output;
}
mbuf_a->last_jiffies = jiffies;
traced_unlock(&output->lock, flags);
GENERIC_INPUT_CALL(input, mars_buf_io, mbuf, rw);
}
//////////////// object / aspect constructors / destructors ///////////////
static int check_mars_io_aspect_init_fn(struct generic_aspect *_ini, void *_init_data)
{
struct check_mars_io_aspect *ini = (void*)_ini;
INIT_LIST_HEAD(&ini->mio_head);
return 0;
}
static int check_mars_buf_aspect_init_fn(struct generic_aspect *_ini, void *_init_data)
{
struct check_mars_buf_aspect *ini = (void*)_ini;
INIT_LIST_HEAD(&ini->mbuf_head);
return 0;
}
MARS_MAKE_STATICS(check);
////////////////////// brick constructors / destructors ////////////////////
static int check_brick_construct(struct check_brick *brick)
{
return 0;
}
static int check_output_construct(struct check_output *output)
{
static int count = 0;
struct task_struct *watchdog;
spin_lock_init(&output->lock);
INIT_LIST_HEAD(&output->mio_anchor);
INIT_LIST_HEAD(&output->mbuf_anchor);
output->instance_nr = ++count;
watchdog = kthread_create(check_watchdog, output, "check_watchdog%d", output->instance_nr);
if (!IS_ERR(watchdog)) {
output->watchdog = watchdog;
wake_up_process(watchdog);
}
return 0;
}
///////////////////////// static structs ////////////////////////
static struct check_brick_ops check_brick_ops = {
};
static struct check_output_ops check_output_ops = {
.make_object_layout = check_make_object_layout,
.mars_io = check_io,
.mars_get_info = check_get_info,
.mars_buf_get = check_buf_get,
.mars_buf_put = check_buf_put,
.mars_buf_io = check_buf_io,
};
static const struct check_input_type check_input_type = {
.type_name = "check_input",
.input_size = sizeof(struct check_input),
};
static const struct check_input_type *check_input_types[] = {
&check_input_type,
};
static const struct check_output_type check_output_type = {
.type_name = "check_output",
.output_size = sizeof(struct check_output),
.master_ops = &check_output_ops,
.output_construct = &check_output_construct,
.aspect_types = check_aspect_types,
.layout_code = {
[BRICK_OBJ_MARS_IO] = LAYOUT_ALL,
[BRICK_OBJ_MARS_BUF] = LAYOUT_ALL,
}
};
static const struct check_output_type *check_output_types[] = {
&check_output_type,
};
const struct check_brick_type check_brick_type = {
.type_name = "check_brick",
.brick_size = sizeof(struct check_brick),
.max_inputs = 1,
.max_outputs = 1,
.master_ops = &check_brick_ops,
.default_input_types = check_input_types,
.default_output_types = check_output_types,
.brick_construct = &check_brick_construct,
};
EXPORT_SYMBOL_GPL(check_brick_type);
////////////////// module init stuff /////////////////////////
static int __init init_check(void)
{
printk(MARS_INFO "init_check()\n");
return check_register_brick_type();
}
static void __exit exit_check(void)
{
printk(MARS_INFO "exit_check()\n");
check_unregister_brick_type();
}
MODULE_DESCRIPTION("MARS check brick");
MODULE_AUTHOR("Thomas Schoebel-Theuer <tst@1und1.de>");
MODULE_LICENSE("GPL");
module_init(init_check);
module_exit(exit_check);

40
mars_check.h Normal file
View File

@ -0,0 +1,40 @@
// (c) 2010 Thomas Schoebel-Theuer / 1&1 Internet AG
#ifndef MARS_CHECK_H
#define MARS_CHECK_H
struct check_mars_io_aspect {
GENERIC_ASPECT(mars_io);
struct list_head mio_head;
int (*old_mars_endio)(struct mars_io_object *mio, int error);
void *old_private;
unsigned long last_jiffies;
};
struct check_mars_buf_aspect {
GENERIC_ASPECT(mars_buf);
struct list_head mbuf_head;
void (*old_buf_endio)(struct mars_buf_object *mbuf);
void *old_private;
unsigned long last_jiffies;
};
struct check_brick {
MARS_BRICK(check);
};
struct check_input {
MARS_INPUT(check);
};
struct check_output {
MARS_OUTPUT(check);
spinlock_t lock;
int instance_nr;
struct task_struct *watchdog;
struct list_head mio_anchor;
struct list_head mbuf_anchor;
};
MARS_TYPES(check);
#endif

View File

@ -265,17 +265,10 @@ static int device_sio_mars_io(struct device_sio_output *output, struct mars_io_o
}
done:
if (!ret) {
bio->bi_size = 0;
if (direction == WRITE && barrier) {
sync_file(output);
}
}
mio->mars_endio(mio, ret);
return ret;
}
#ifdef WITH_THREAD
static int device_sio_mars_queue(struct device_sio_output *output, struct mars_io_object *mio)
{
int index = 0;
@ -311,23 +304,30 @@ static int device_sio_thread(void *data)
//set_user_nice(current, -20);
while (!kthread_should_stop()) {
struct list_head *tmp;
struct list_head *tmp = NULL;
struct device_sio_mars_io_aspect *aspect;
struct mars_io_object *mio;
unsigned long flags;
wait_event_interruptible(tinfo->event,
!list_empty(&tinfo->mio_list) ||
kthread_should_stop());
wait_event_interruptible_timeout(
tinfo->event,
!list_empty(&tinfo->mio_list) || kthread_should_stop(),
HZ);
if (list_empty(&tinfo->mio_list))
continue;
tinfo->last_jiffies = jiffies;
traced_lock(&tinfo->lock, flags);
tmp = tinfo->mio_list.next;
list_del_init(tmp);
if (!list_empty(&tinfo->mio_list)) {
tmp = tinfo->mio_list.next;
list_del_init(tmp);
}
traced_unlock(&tinfo->lock, flags);
if (!tmp)
continue;
aspect = container_of(tmp, struct device_sio_mars_io_aspect, io_head);
mio = aspect->object;
MARS_DBG("got %p %p\n", aspect, mio);
@ -337,7 +337,28 @@ static int device_sio_thread(void *data)
MARS_INF("kthread has stopped.\n");
return 0;
}
#endif
static int device_sio_watchdog(void *data)
{
struct device_sio_output *output = data;
MARS_INF("watchdog has started.\n");
while (!kthread_should_stop()) {
int i;
msleep_interruptible(5000);
for (i = 0; i <= WITH_THREAD; i++) {
struct sio_threadinfo *tinfo = &output->tinfo[i];
unsigned long now = jiffies;
unsigned long elapsed = now - tinfo->last_jiffies;
if (elapsed > 10 * HZ) {
tinfo->last_jiffies = now;
MARS_ERR("thread %d is dead for more than 10 seconds.\n", i);
}
}
}
return 0;
}
static int device_sio_get_info(struct device_sio_output *output, struct mars_info *info)
{
@ -365,22 +386,6 @@ static int device_sio_mars_buf_aspect_init_fn(struct generic_aspect *_ini, void
MARS_MAKE_STATICS(device_sio);
#if 0
static int device_sio_make_object_layout(struct device_sio_output *output, struct generic_object_layout *object_layout)
{
const struct generic_object_type *object_type = object_layout->object_type;
int slot;
if (object_type != &mars_io_type)
return 0;
slot = device_sio_mars_io_add_aspect(output, object_layout, &device_sio_mars_io_aspect_type);
if (slot < 0)
return slot;
return sizeof(struct device_sio_mars_io_aspect);
}
#endif
////////////////////// brick constructors / destructors ////////////////////
static int device_sio_brick_construct(struct device_sio_brick *brick)
@ -394,6 +399,7 @@ static int device_sio_output_construct(struct device_sio_output *output)
int flags = O_CREAT | O_RDWR | O_LARGEFILE;
int prot = 0600;
char *path = "/tmp/testfile.img";
struct task_struct *watchdog;
int index;
oldfs = get_fs();
@ -416,7 +422,6 @@ static int device_sio_output_construct(struct device_sio_output *output)
}
#endif
#ifdef WITH_THREAD
spin_lock_init(&output->g_lock);
output->index = 0;
for (index = 0; index <= WITH_THREAD; index++) {
@ -425,6 +430,7 @@ static int device_sio_output_construct(struct device_sio_output *output)
spin_lock_init(&tinfo->lock);
init_waitqueue_head(&tinfo->event);
INIT_LIST_HEAD(&tinfo->mio_list);
tinfo->last_jiffies = jiffies;
tinfo->thread = kthread_create(device_sio_thread, tinfo, "mars_sio%d", index);
if (IS_ERR(tinfo->thread)) {
int error = PTR_ERR(tinfo->thread);
@ -434,20 +440,22 @@ static int device_sio_output_construct(struct device_sio_output *output)
}
wake_up_process(tinfo->thread);
}
#endif
watchdog = kthread_create(device_sio_watchdog, output, "mars_watchdog%d", 0);
if (!IS_ERR(watchdog)) {
wake_up_process(watchdog);
}
return 0;
}
static int device_sio_output_destruct(struct device_sio_output *output)
{
#ifdef WITH_THREAD
int index;
for (index = 0; index <= WITH_THREAD; index++) {
kthread_stop(output->tinfo[index].thread);
output->tinfo[index].thread = NULL;
}
#endif
if (output->filp) {
filp_close(output->filp, NULL);
output->filp = NULL;
@ -463,11 +471,7 @@ static struct device_sio_brick_ops device_sio_brick_ops = {
static struct device_sio_output_ops device_sio_output_ops = {
.make_object_layout = device_sio_make_object_layout,
#ifdef WITH_THREAD
.mars_io = device_sio_mars_queue,
#else
.mars_io = device_sio_mars_io,
#endif
.mars_get_info = device_sio_get_info,
};

View File

@ -21,24 +21,21 @@ struct device_sio_input {
MARS_INPUT(device_sio);
};
#ifdef WITH_THREAD
struct sio_threadinfo {
struct device_sio_output *output;
struct list_head mio_list;
struct task_struct *thread;
wait_queue_head_t event;
spinlock_t lock;
unsigned long last_jiffies;
};
#endif
struct device_sio_output {
MARS_OUTPUT(device_sio);
struct file *filp;
#ifdef WITH_THREAD
struct sio_threadinfo tinfo[WITH_THREAD+1];
spinlock_t g_lock;
int index;
#endif
};
MARS_TYPES(device_sio);

View File

@ -15,22 +15,24 @@
#include "mars.h"
#include "mars_if_device.h"
#include "mars_dummy.h"
#include "mars_check.h"
#include "mars_device_sio.h"
#include "mars_buf.h"
#include "mars_usebuf.h"
GENERIC_MAKE_CONNECT(if_device, device_sio);
GENERIC_MAKE_CONNECT(if_device, buf);
GENERIC_MAKE_CONNECT(if_device, dummy);
GENERIC_MAKE_CONNECT(if_device, check);
GENERIC_MAKE_CONNECT(if_device, usebuf);
GENERIC_MAKE_CONNECT(usebuf, dummy);
GENERIC_MAKE_CONNECT(check, usebuf);
GENERIC_MAKE_CONNECT(usebuf, check);
GENERIC_MAKE_CONNECT(buf, device_sio);
GENERIC_MAKE_CONNECT(dummy, buf);
GENERIC_MAKE_CONNECT(check, buf);
static struct if_device_brick *if_brick = NULL;
static struct usebuf_brick *usebuf_brick = NULL;
static struct dummy_brick *dummy_brick = NULL;
static struct check_brick *check_brick = NULL;
static struct check_brick *check_brick0 = NULL;
static struct buf_brick *buf_brick = NULL;
static struct device_sio_brick *device_brick = NULL;
@ -47,14 +49,13 @@ void make_test_instance(void)
int status;
void *mem;
MARS_DBG("starting....\n");
mem = kzalloc(size, GFP_KERNEL);
if (!mem) {
MARS_ERR("cannot grab test memory\n");
return;
}
MARS_DBG("starting....\n");
status = device_sio_brick_init_full(mem, size, &device_sio_brick_type, NULL, NULL, names);
MARS_DBG("done (status=%d)\n", status);
if (status) {
@ -68,7 +69,6 @@ void make_test_instance(void)
MARS_ERR("cannot grab test memory\n");
return;
}
status = if_device_brick_init_full(mem, size, &if_device_brick_type, NULL, NULL, names);
MARS_DBG("done (status=%d)\n", status);
if (status) {
@ -82,14 +82,13 @@ void make_test_instance(void)
MARS_ERR("cannot grab test memory\n");
return;
}
status = dummy_brick_init_full(mem, size, &dummy_brick_type, NULL, NULL, names);
status = check_brick_init_full(mem, size, &check_brick_type, NULL, NULL, names);
MARS_DBG("done (status=%d)\n", status);
if (status) {
MARS_ERR("cannot init brick dummy\n");
MARS_ERR("cannot init brick check\n");
return;
}
dummy_brick = mem;
check_brick = mem;
#if 1 // usebuf zwischenschalten
mem = kzalloc(size, GFP_KERNEL);
@ -97,7 +96,6 @@ void make_test_instance(void)
MARS_ERR("cannot grab test memory\n");
return;
}
status = usebuf_brick_init_full(mem, size, &usebuf_brick_type, NULL, NULL, names);
MARS_DBG("done (status=%d)\n", status);
if (status) {
@ -106,13 +104,29 @@ void make_test_instance(void)
}
usebuf_brick = mem;
status = if_device_usebuf_connect(if_brick->inputs[0], usebuf_brick->outputs[0]);
mem = kzalloc(size, GFP_KERNEL);
if (!mem) {
MARS_ERR("cannot grab test memory\n");
return;
}
status = check_brick_init_full(mem, size, &check_brick_type, NULL, NULL, names);
MARS_DBG("done (status=%d)\n", status);
if (status) {
MARS_ERR("cannot init brick check\n");
return;
}
check_brick0 = mem;
status = if_device_check_connect(if_brick->inputs[0], check_brick0->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
status = usebuf_dummy_connect(usebuf_brick->inputs[0], dummy_brick->outputs[0]);
status = check_usebuf_connect(check_brick0->inputs[0], usebuf_brick->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
status = usebuf_check_connect(usebuf_brick->inputs[0], check_brick->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
#else
(void)usebuf_brick;
status = if_device_dummy_connect(if_brick->inputs[0], dummy_brick->outputs[0]);
status = if_device_check_connect(if_brick->inputs[0], check_brick->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
#endif
@ -130,14 +144,14 @@ void make_test_instance(void)
return;
}
buf_brick = mem;
buf_brick->backing_order = 0;
buf_brick->backing_order = 4;
buf_brick->backing_size = PAGE_SIZE << buf_brick->backing_order;
buf_brick->max_count = 512;
status = buf_device_sio_connect(buf_brick->inputs[0], device_brick->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
status = dummy_buf_connect(dummy_brick->inputs[0], buf_brick->outputs[0]);
status = check_buf_connect(check_brick->inputs[0], buf_brick->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
if (true) {
@ -166,7 +180,7 @@ void make_test_instance(void)
}
#else
status = dummy_device_sio_connect(dummy_brick->inputs[0], device_brick->outputs[0]);
status = check_device_sio_connect(check_brick->inputs[0], device_brick->outputs[0]);
MARS_DBG("connect (status=%d)\n", status);
#endif

View File

@ -29,14 +29,12 @@ static void _usebuf_copy(struct usebuf_mars_buf_aspect *mbuf_a, int rw)
void *bio_data = bio_base + mbuf_a->bvec_offset;
int len = mbuf_a->bvec_len;
#if 1
if (rw == READ) {
memcpy(bio_data, buf_data, len);
//memset(bio_data, 0, len);
} else {
memcpy(buf_data, bio_data, len);
}
#endif
kunmap_atomic(bio_base, KM_USER0);
}
@ -47,7 +45,7 @@ static int _usebuf_mio_endio(struct usebuf_output *output, struct mars_io_object
mio_a = usebuf_mars_io_get_aspect(output, mio);
if (unlikely(!mio_a)) {
MARS_ERR("cannot get mio_a\n");
MARS_FAT("cannot get mio_a from mio %p\n", mio);
goto out;
}
@ -89,17 +87,17 @@ static void _usebuf_mbuf_endio(struct mars_buf_object *mbuf)
output = mbuf->cb_private;
if (unlikely(!output)) {
MARS_ERR("bad argument output\n");
goto out_err2;
goto out_err;
}
mbuf_a = usebuf_mars_buf_get_aspect(output, mbuf);
if (unlikely(!mbuf_a)) {
MARS_ERR("cannot get aspect\n");
goto out_err2;
goto out_err;
}
mio = mbuf_a->mio;
if (unlikely(!mio)) {
MARS_ERR("cannot get mio\n");
goto out_err1;
goto out_err;
}
MARS_DBG("mio=%p\n", mio);
mio_a = usebuf_mars_io_get_aspect(output, mio);
@ -158,8 +156,7 @@ out_nocheck:
if (!status)
status = ignore;
out_err1:
out_err2:
out_err:
mbuf->cb_error = status;
}
@ -294,9 +291,7 @@ static int usebuf_io(struct usebuf_output *output, struct mars_io_object *mio)
done_drop:
// drop initial refcount
if (!status) {
(void)_usebuf_mio_endio(output, mio, 0);
}
(void)_usebuf_mio_endio(output, mio, status);
done:
MARS_DBG("status=%d\n", status);