All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 822739b4 authored by Scotty Bauer's avatar Scotty Bauer

RPC Calls 90 Percent done

I need to work out a few synchronization bugs
Signed-off-by: Scotty Bauer's avatarScotty Bauer <sbauer@eng.utah.edu>
parent 55a0190d
obj-m := test.o
#CFLAGS_test.o = -DDEBUG -DDEBUG_MWAIT_RETRY -DTIMING -g -Wall
#CFLAGS_betaModule2.o = -DDEBUG -DDEBUG_MWAIT_RETRY -DTIMING -g -Wall
#CFLAGS_ring-channel.o = -DDEBUG -DDEBUG_MWAIT_RETRY -DTIMING -g -Wall
CFLAGS_test.o = -O2 -DPOLL -DUSE_FLOOD #-DDEBUG_MWAIT_RETRY #-DDEBUG
CFLAGS_betaModule_RPC2.o = -O2 -DPOLL -DUSE_FLOOD #-DDEBUG_MWAIT_RETRY #-DDEBUG
CFLAGS_ring-channel.o = -O2
CFLAGS_functions.o = -O0
test-objs := ./ring-chan/ring-channel.o ./betaModule_RPC2.o ./functions.o
KDIR := /lib/modules/`uname -r`/build
default:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
This diff is collapsed.
#include "../betaModule.h"
static unsigned long foo(unsigned long a, unsigned long b, unsigned long c)
{
/* just some random math, doesnt mean anything just meant to take cycles */
return (((a << 20) + a) - ((b >> 20) + b) + c)<<4;
}
unsigned long foo_dispatch(struct ipc_message *msg)
{
return foo(msg->reg1, msg->reg6, msg->reg4);
}
unsigned long bar_dispatch(void)
{
return 10;
}
unsigned long baz_dispatch(void)
{
return 11;
}
/*
* Ring channels provide a general producer-consumer interface for relaying
* data from to the LCD components. Specifically ring channels are used for
* establishing a high-performance communication channels between LCD components
*
* Authors: Anton Burtsev, Scotty Bauer
* Date: October 2011, Feburary 2015
*
*/
#include <asm-generic/getorder.h>
#include <linux/mm.h>
#include <linux/gfp.h>
#include "ring-channel.h"
static inline unsigned long bsrl(unsigned long x)
{
unsigned long ret;
asm("bsr %1,%0" : "=r"(ret) : "r"(x));
return ret;
}
static inline unsigned long lower_power_of_two(unsigned long x)
{
return 0x80000000000000UL >> (__builtin_clzl(x)-1);
}
/* Stolen from xen/mm.h */
static inline int get_order_from_pages(unsigned long nr_pages)
{
int order;
nr_pages--;
for ( order = 0; nr_pages; order++ )
nr_pages >>= 1;
return order;
}
int ttd_ring_channel_alloc(struct ttd_ring_channel *ring_channel,
unsigned long size_in_pages,
unsigned long size_of_a_rec) {
return ttd_ring_channel_alloc_with_metadata(ring_channel,
size_in_pages, size_of_a_rec, 0);
}
void ttd_ring_channel_free(struct ttd_ring_channel *ring_channel) {
if (ring_channel->recs) {
free_pages((unsigned long) ring_channel->recs,
ring_channel->buf_order);
ring_channel->recs = NULL;
}
if (ring_channel->buf) {
free_pages((unsigned long) ring_channel->buf,
ring_channel->header_order);
ring_channel->buf = NULL;
}
}
int ttd_ring_channel_alloc_with_metadata(struct ttd_ring_channel *ring_channel,
unsigned long size_in_pages,
unsigned long size_of_a_rec,
unsigned long priv_metadata_size)
{
int ret;
unsigned long order, header_order;
unsigned long size_of_header_in_pages;
pr_debug("Allocating ring channel\n");
ttd_ring_channel_init(ring_channel);
/* number of pages required for this */
header_order = get_order(priv_metadata_size +
sizeof(struct ttd_buf));
if ( (ring_channel->buf = (void *) __get_free_pages(GFP_KERNEL, header_order)) == NULL ) {
pr_err("Xen deterministic time-travel buffers: memory allocation failed\n");
return -EINVAL;
}
size_of_header_in_pages = 1 << header_order;
pr_debug("Allocating ring channel: header area size:%lu, in pages:%lu\n",
priv_metadata_size + sizeof(struct ttd_buf), size_of_header_in_pages);
order = get_order_from_pages(size_in_pages);
if ( (ring_channel->recs = (char *) __get_free_pages(GFP_KERNEL, order)) == NULL ) {
pr_err("Xen deterministic time-travel buffers: memory allocationcd failed, "
"size in pages:%lu, order:%lu\n", size_in_pages, order);
ret = -EINVAL; goto cleanup;
}
ring_channel->priv_metadata = (char *) (ring_channel->buf + 1);
ring_channel->buf->cons = ring_channel->buf->prod = 0;
ttd_ring_channel_reinit_stats(ring_channel->buf);
ring_channel->size_of_a_rec = size_of_a_rec;
pr_debug("Size of a rec is %lu\n", size_of_a_rec);
/* ring_channel->size_in_recs = (lower_power_of_two(size_in_pages * PAGE_SIZE))
/ ring_channel->size_of_a_rec;
*/
ring_channel->size_in_recs = (size_in_pages * PAGE_SIZE) /
ring_channel->size_of_a_rec;
pr_debug("size in recs is %lu lower_power_of_two returned %lu and in hex %lxwith input %lu and hex %lx\n",
ring_channel->size_in_recs,
lower_power_of_two(size_in_pages * PAGE_SIZE),
lower_power_of_two(size_in_pages * PAGE_SIZE),
(size_in_pages * PAGE_SIZE), (size_in_pages * PAGE_SIZE));
if (ring_channel->size_in_recs == 0) {
pr_err(" Size_in_recs was incorrectly 0\n");
ret = -EINVAL; goto cleanup;
}
/* Init shared buffer structures */
ring_channel->buf->payload_buffer_mfn =
(unsigned long) ring_channel->recs; /*NOTE*/
ring_channel->buf->payload_buffer_size = size_in_pages * PAGE_SIZE;
ring_channel->buf->size_of_a_rec = ring_channel->size_of_a_rec;
ring_channel->buf->size_in_recs = ring_channel->size_in_recs;
//ring_channel->highwater = ring_channel->size_in_recs >> 2; /* 25% high water */
ring_channel->highwater = ring_channel->size_in_recs >> 1; /* 50% high water */
ring_channel->emergency_margin = ring_channel->size_in_recs >> 4; /* 5% we are very close */
pr_debug("New ring channel: payload area {requested:%lu, allocated:%lu, wasted on allocation:%lu (order:%lu), \n"
"metadata area {size:%lu, buffer size: %lu, full header: %lu, "
"allocated:%lu, wasted on allocation:%lu (order:%lu)} \n"
"rec: {requested size:%lu, size ^2:%lu, rownded down size in recs:%lu, "
"possible size in recs:%lu, wasted:%lu} "
"highwater: %lu, emergency margin: %lu\n",
size_in_pages * PAGE_SIZE,
((unsigned long)1 << order) * PAGE_SIZE,
((1 << order) * PAGE_SIZE) - size_in_pages * PAGE_SIZE, order,
priv_metadata_size, (unsigned long) sizeof(struct ttd_buf),
priv_metadata_size + sizeof(struct ttd_buf),
((unsigned long)1 << header_order) * PAGE_SIZE,
((1 << header_order)* PAGE_SIZE) - priv_metadata_size - sizeof(struct ttd_buf),
header_order, size_of_a_rec,
ttd_ring_channel_size_of_a_rec(ring_channel),
ttd_ring_channel_size_in_recs(ring_channel),
(size_in_pages * PAGE_SIZE)/ring_channel->size_of_a_rec,
(size_in_pages * PAGE_SIZE)/ring_channel->size_of_a_rec - ttd_ring_channel_size_in_recs(ring_channel),
ttd_ring_channel_highwater(ring_channel),
ttd_ring_channel_emergency_margin(ring_channel));
ring_channel->header_order = header_order;
ring_channel->buf_order = order;
return 0;
cleanup:
ttd_ring_channel_free(ring_channel);
return ret;
}
/*
* common/ring-channel.c
*
* This file is part of the Flux deterministic time-travel infrastructure.
* Ring channels provide a general producer-consumer interface for relaying
* data from to the guest components. Specifically ring channels are used for
* establishing a high-performance communication channels between Xen microkernel
* and loggin, replay, and devd daemons.
*
* Authors: Anton Burtsev Scotty Bauer
* Date: October 2011 Feburary 2015
*
*/
#ifndef __XEN_RING_CHANNEL_H__
#define __XEN_RING_CHANNEL_H__
#include <linux/string.h>
/*
* This structure contains the metadata for a single trace buffer. The head
* field, indexes into an array of struct t_rec's.
*/
struct ttd_buf {
unsigned long cons; /* Next item to be consumed by control tools. */
unsigned long prod; /* Next item to be produced by Xen. */
/* Shape of the buffer */
unsigned long payload_buffer_mfn;
unsigned long payload_buffer_size;
unsigned long size_of_a_rec; /* size of a single record */
unsigned long size_in_recs; /* size of the buffer in recs */
/* Stats for the buffer */
unsigned long long avg_queue_size; /* average size of the request queue in the buffer */
unsigned long long msgs_sent; /* total number of messages sent */
unsigned long msgs_by_type[128]; /* count how many messages of individual type we record */
unsigned long long tx_notifications; /* total number of TX notifications */
unsigned long long tx_hit_emergency_margin; /* total number of times the channel gets emergently full */
unsigned long long rx_notifications; /* total number of RX notifications */
unsigned long long msgs_with_extra_reg_space; /* total number of messages which asked for extra space in registers */
unsigned long msgs_with_extra_reg_space_by_type[128]; /* count how many times an individual event type asks for more space */
unsigned long long msgs_with_extra_data_space; /* total number of messages which asked for extra space for data */
unsigned long msgs_with_extra_data_space_by_type[128]; /* count how many times an individual event type asks for more space */
/* 'ttd_nr_recs' records follow immediately after the meta-data header. */
};
struct ttd_ring_channel {
struct ttd_buf *buf; /* pointer to the buffer metadata */
unsigned long buf_mfn;
unsigned long buf_order;
void *priv_metadata; /* pointer to the private buffer metadata */
unsigned long priv_metadata_size; /* size of the private buffer metadata */
unsigned long header_order; /* size of the private buffer metadata */
char *recs; /* pointer to buffer data areas */
unsigned long size_of_a_rec; /* size of a single record */
unsigned long size_in_recs; /* size of the buffer in recs */
unsigned long highwater; /* buffer is quite full, time to notify other end */
unsigned long emergency_margin; /* buffer is nearly full, time to freeze everything */
};
static inline void ttd_ring_channel_reinit_stats(struct ttd_buf *buf)
{
buf->avg_queue_size = 0;
buf->msgs_sent = 0;
buf->tx_notifications = 0;
buf->rx_notifications = 0;
buf->tx_hit_emergency_margin = 0;
buf->msgs_with_extra_reg_space = 0;
buf->msgs_with_extra_data_space = 0;
memset(buf->msgs_by_type, 0,
sizeof(buf->msgs_by_type));
memset(buf->msgs_with_extra_reg_space_by_type, 0,
sizeof(buf->msgs_with_extra_reg_space_by_type));
memset(buf->msgs_with_extra_data_space_by_type, 0,
sizeof(buf->msgs_with_extra_data_space_by_type));
}
static inline void ttd_ring_channel_init(struct ttd_ring_channel *ring_channel)
{
memset(ring_channel, 0, sizeof(*ring_channel));
return;
}
static inline void ttd_ring_channel_buf_init(struct ttd_buf *buf)
{
memset(buf, 0, sizeof(*buf));
return;
}
int ttd_ring_channel_alloc(struct ttd_ring_channel *ring_channel,
unsigned long size_in_pages,
unsigned long size_of_a_rec);
int ttd_ring_channel_alloc_with_metadata(struct ttd_ring_channel *ring_channel,
unsigned long size_in_pages,
unsigned long size_of_a_rec,
unsigned long priv_metadata_size);
void ttd_ring_channel_free(struct ttd_ring_channel *ring_channel);
static inline void
*ttd_ring_channel_get_priv_metadata(struct ttd_ring_channel *ring_channel)
{
return ring_channel->priv_metadata;
}
static inline unsigned long
ttd_ring_channel_get_prod(struct ttd_ring_channel *ring_channel) {
return ring_channel->buf->prod;
};
static inline unsigned long
ttd_ring_channel_inc_prod(struct ttd_ring_channel *ring_channel) {
return (ring_channel->buf->prod++);
};
static inline void
ttd_ring_channel_set_prod(struct ttd_ring_channel *ring_channel, unsigned long prod) {
ring_channel->buf->prod = prod;
return;
};
static inline unsigned long
ttd_ring_channel_get_cons(struct ttd_ring_channel *ring_channel) {
return ring_channel->buf->cons;
};
static inline unsigned long
ttd_ring_channel_inc_cons(struct ttd_ring_channel *ring_channel) {
return (ring_channel->buf->cons++);
};
static inline void ttd_ring_channel_set_cons(struct ttd_ring_channel *ring_channel,
unsigned long cons) {
ring_channel->buf->cons = cons;
return;
};
static inline char *ttd_ring_channel_get_rec_slow(struct ttd_ring_channel *ring_channel,
unsigned long cons) {
return (ring_channel->recs + (cons % 1024) * 64);
//return (ring_channel->recs
// + (cons % ring_channel->size_in_recs)
// * ring_channel->size_of_a_rec);*/
};
static inline unsigned long ttd_ring_channel_get_index_mod_slow(struct ttd_ring_channel *ring_channel, unsigned long index) {
return (index % ring_channel->size_in_recs);
}
static inline unsigned long ttd_ring_channel_size_in_recs(struct ttd_ring_channel *ring_channel) {
return ring_channel->size_in_recs;
}
static inline unsigned long ttd_ring_channel_size_of_a_rec(struct ttd_ring_channel *ring_channel) {
return ring_channel->size_of_a_rec;
}
static inline unsigned long ttd_ring_channel_size(struct ttd_ring_channel *ring_channel) {
return ring_channel->size_in_recs * ring_channel->size_of_a_rec;
}
static inline unsigned long ttd_ring_channel_highwater(struct ttd_ring_channel *ring_channel) {
return ring_channel->highwater;
}
static inline unsigned long ttd_ring_channel_emergency_margin(struct ttd_ring_channel *ring_channel) {
return ring_channel->emergency_margin;
}
#endif
obj-m := betaModule_RPC1.o
#CFLAGS_betaModule1.o = -DDEBUG -DDEBUG_MWAIT_RETRY -DTIMING -g -Wall
#CFLAGS_betaModule.o = -DDEBUG -DDEBUG_MWAIT_RETRY -DTIMING -g -Wall
#CFLAGS_ring-channel.o = -DDEBUG -DDEBUG_MWAIT_RETRY -DTIMING -g -Wall
CFLAGS_betaModule_RPC1.o = -g -O2 -DPOLL -DTIMING -DUSE_FLOOD #-DDEBUG #-DDEBUG_MWAIT_RETRY
CFLAGS_betaModule_RPC.o = -g -O2 -DPOLL -DTIMING -DUSE_FLOOD #-DDEBUG #-DDEBUG_MWAIT_RETRY #-DDEBUG
CFLAGS_ring-channel.o = -g -O2
#CFLAGS_functions.o = -O2
betaModule_RPC1-objs := ./ring-chan/ring-channel.o ./betaModule_RPC.o ./functions.o
KDIR := /lib/modules/`uname -r`/build
default:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
#ifndef _INCL_GUARD
#define _INCL_GUARD
#include <linux/types.h>
typedef enum { FOO, BAR, BAZ } ftype;
#if defined(USE_MWAIT)
unsigned long ecx = 1; /*break of interrupt flag */
unsigned long cstate_wait = 0x0; /* 4 states, 0x0, 0x1 0x10 0x20 */
#endif
struct ipc_container{
struct task_struct *thread;
struct ttd_ring_channel *channel_tx;
struct ttd_ring_channel *channel_rx;
};
/*Don't let gcc do anything cute, we need this to be 128 bytes */
/* TODO CONFIRM ALIGNMENT REQUIREMENTS FOR ULONG! */
struct ipc_message{
ftype type; /* 4 */
unsigned long reg1;
unsigned long reg2;
unsigned long reg3;
unsigned long reg4;
unsigned long reg5;
unsigned long reg6;
unsigned long reg7;
volatile uint32_t msg_status;
}__attribute__((packed));
#define BETA_GET_CPU_AFFINITY 1<<1
#define BETA_CONNECT_SHARED_MEM 1<<2
#define BETA_UNPARK_THREAD 1<<3
#define BETA_ALLOC_MEM 1<<4
#define BETA_GET_MEM 1<<5
#define BETA_DUMP_TIME 1<<6
#endif
This diff is collapsed.
#include "betaModule.h"
static struct ttd_ring_channel *prod_channel;
static struct ttd_ring_channel *cons_channel;
extern unsigned int recv_ack;
extern unsigned int send_slot_avail;
extern unsigned int send_message;
extern unsigned int recv_message;
extern unsigned long send_slot;
extern unsigned long recv_slot;
extern struct ipc_message *get_next_available_slot(struct ttd_ring_channel*, unsigned long);
extern int wait_for_producer_slot(struct ipc_message*, unsigned int);
extern void send(struct ipc_message *);
extern struct ipc_message *recv(struct ttd_ring_channel *);
void register_chans(struct ttd_ring_channel *prod, struct ttd_ring_channel *cons)
{
prod_channel = prod;
cons_channel = cons;
}
unsigned long foo(unsigned long a, unsigned long b, unsigned long c)
{
struct ipc_message *send_msg, *recv_msg;
unsigned long ret;
send_msg = get_next_available_slot(prod_channel, send_slot);
wait_for_producer_slot(prod_channel, send_slot_avail);
send_msg->type = FOO;
send_msg->reg1 = a;
send_msg->reg6 = b;
send_msg->reg4 = c;
send(send_msg);
recv_msg = recv(cons_channel);
ret = recv_msg->reg1;
recv_msg->msg_status = recv_ack;
return ret;
}
int CHAN_NUM_PAGES = 16;
int BUF_SIZE = 60;
int NUM_LOOPS = 10000;
int FLOOD_SIZE = 1;
/*
* Ring channels provide a general producer-consumer interface for relaying
* data from to the LCD components. Specifically ring channels are used for
* establishing a high-performance communication channels between LCD components
*
* Authors: Anton Burtsev, Scotty Bauer
* Date: October 2011, Feburary 2015
*
*/
#include <asm-generic/getorder.h>
#include <linux/mm.h>
#include <linux/gfp.h>
#include "ring-channel.h"
static inline unsigned long bsrl(unsigned long x)
{
unsigned long ret;
asm("bsr %1,%0" : "=r"(ret) : "r"(x));
return ret;
}
static inline unsigned long lower_power_of_two(unsigned long x)
{
return 0x80000000000000UL >> (__builtin_clzl(x)-1);
}
/* Stolen from xen/mm.h */
static inline int get_order_from_pages(unsigned long nr_pages)
{
int order;
nr_pages--;
for ( order = 0; nr_pages; order++ )
nr_pages >>= 1;
return order;
}
int ttd_ring_channel_alloc(struct ttd_ring_channel *ring_channel,
unsigned long size_in_pages,
unsigned long size_of_a_rec) {
return ttd_ring_channel_alloc_with_metadata(ring_channel,
size_in_pages, size_of_a_rec, 0);
}
void ttd_ring_channel_free(struct ttd_ring_channel *ring_channel) {
if (ring_channel->recs) {
free_pages((unsigned long) ring_channel->recs,
ring_channel->buf_order);
ring_channel->recs = NULL;
}
if (ring_channel->buf) {
free_pages((unsigned long) ring_channel->buf,
ring_channel->header_order);
ring_channel->buf = NULL;
}
}
int ttd_ring_channel_alloc_with_metadata(struct ttd_ring_channel *ring_channel,
unsigned long size_in_pages,
unsigned long size_of_a_rec,
unsigned long priv_metadata_size)
{
int ret;
unsigned long order, header_order;
unsigned long size_of_header_in_pages;
pr_debug("Allocating ring channel\n");
ttd_ring_channel_init(ring_channel);
/* number of pages required for this */
header_order = get_order(priv_metadata_size +
sizeof(struct ttd_buf));
if ( (ring_channel->buf = (void *) __get_free_pages(GFP_KERNEL, header_order)) == NULL ) {
pr_err("Xen deterministic time-travel buffers: memory allocation failed\n");
return -EINVAL;
}
size_of_header_in_pages = 1 << header_order;
pr_debug("Allocating ring channel: header area size:%lu, in pages:%lu\n",
priv_metadata_size + sizeof(struct ttd_buf), size_of_header_in_pages);
order = get_order_from_pages(size_in_pages);
if ( (ring_channel->recs = (char *) __get_free_pages(GFP_KERNEL, order)) == NULL ) {
pr_err("Xen deterministic time-travel buffers: memory allocationcd failed, "
"size in pages:%lu, order:%lu\n", size_in_pages, order);
ret = -EINVAL; goto cleanup;
}
ring_channel->priv_metadata = (char *) (ring_channel->buf + 1);
ring_channel->buf->cons = ring_channel->buf->prod = 0;
ttd_ring_channel_reinit_stats(ring_channel->buf);