Commit 5468ae3d authored by Michael Quigley's avatar Michael Quigley
Browse files

commit before merge

parent 90fccedb
......@@ -19,6 +19,7 @@
#include <asm/tsc.h>
#include <lcd-domains/thc.h>
#include <lcd-domains/thcinternal.h>
#include "../ring-chan/ring-channel.h"
#include "ipc.h"
......@@ -30,6 +31,13 @@ static unsigned int trans_complete = 0xC1346BAD;
extern int dispatch(void *data);
awe_t* get_awe_from_msg_id(unsigned long msg_id)
{
if( sizeof(unsigned long) != sizeof(awe_t*) )
printk(KERN_WARNING "mismatched sizes in get_awe_from_msg_id\n");
return (awe_t*)msg_id;
}
static inline void monitor_mwait(unsigned long rcx, volatile uint32_t *rax,
unsigned long wait_type)
......@@ -69,22 +77,22 @@ static int wait_for_tx_slot(struct ipc_message *imsg)
return 0;
}
static int wait_for_rx_slot(struct ipc_message *imsg)//, bool is_async)
static int wait_for_rx_slot(struct ipc_message *imsg, bool is_async)
{
while (check_rx_slot_available(imsg)) { //while a slot is not available
// if( is_async )
// {
// THCYield();
// }
// else
// {
if( is_async )
{
THCYield();
}
else
{
#if defined(USE_MWAIT)
monitor_mwait(ecx, &imsg->msg_status, cstate_wait);
#endif//usemwait
#if defined(POLL)
cpu_relax();
#endif
// }
}
}
return 0;
}
......@@ -181,19 +189,40 @@ struct ipc_message *recv(struct ttd_ring_channel *rx)
recv_msg = get_rx_rec(rx, sizeof(struct ipc_message));
inc_rx_slot(rx);
// wait_for_rx_slot(recv_msg, false);
wait_for_rx_slot(recv_msg, false);
return recv_msg;
}
EXPORT_SYMBOL(recv);
struct ipc_message *async_recv(struct ttd_ring_channel *rx, unsigned long msg_id)
noinline struct ipc_message *async_recv(struct ttd_ring_channel *rx, unsigned long msg_id)
{
struct ipc_message *recv_msg;
recv_msg = get_rx_rec(rx, sizeof(struct ipc_message));
while( true )
{
recv_msg = get_rx_rec(rx, sizeof(struct ipc_message));
if( !check_rx_slot_available(recv_msg) ) //if slot is available
{
if( recv_msg->msg_id == msg_id )
{
break;
}
else
{
awe_t* other_awe = get_awe_from_msg_id(msg_id);
THCYield(); //THCYieldTo(other_awe);
}
}
else
{
THCYield();
}
}
inc_rx_slot(rx);
// wait_for_rx_slot(recv_msg, true);
return recv_msg;
}
EXPORT_SYMBOL(async_recv);
......
......@@ -24,15 +24,16 @@ struct ipc_message{
unsigned long reg4;
unsigned long reg5;
unsigned long reg6;
void* msg_id;
unsigned long msg_id;
volatile uint32_t msg_status;
}__attribute__((packed));
struct ttd_ring_channel *create_channel(unsigned long size_pages, unsigned CPU);
void free_channel(struct ttd_ring_channel *channel);
void send(struct ttd_ring_channel *tx, struct ipc_message *trans);
struct ipc_message *recv(struct ttd_ring_channel *rx);
struct ipc_message *async_recv(struct ttd_ring_channel *rx);
struct ipc_message *async_recv(struct ttd_ring_channel *rx, unsigned long msg_id);
struct ipc_message *get_send_slot(struct ttd_ring_channel *tx);
void transaction_complete(struct ipc_message *msg);
int ipc_start_thread(struct ttd_ring_channel *chan);
......
......@@ -3,7 +3,7 @@ obj-m := rpc_testing.o
#ccflags-y += -O2 -I/users/mquigley/fast-ipc-module/current/IPC
ccflags-y += -O2 -I/users/sbauer/ipc/ramstore/fast-ipc-module/current/IPC -I/local/sda4/async/xcap-capability-linux/include
ccflags-y += -O2 -I/users/mquigley/fast-ipc-module/current/IPC -I/local/sda4/async/xcap-capability-linux/include
INC_DIR = ../../IPC
......@@ -11,8 +11,8 @@ CFLAGS_ipc.o = -O2 -DPOLL
CFLAGS_ring-channel.o = -I$(INC_DIR)
DEPS= $(INC_DIR)/ipc.h
rpc_testing-objs := ../../IPC/ipc.o ../../ring-chan/ring-channel.o callee.o caller.o rpc_setup.o rpc_test.o
#thc_objs := ../../../../../../local/sda4/async/xcap-capability-linux/drivers/thc/thc.o ../../../../../../local/sda4/async/xcap-capability-linux/drivers/thc/thcsync.o
rpc_testing-objs := ../../IPC/ipc.o ../../ring-chan/ring-channel.o callee.o caller.o rpc_setup.o rpc_test.o $(thc_objs)
KDIR := /lib/modules/`uname -r`/build
......
0x0b523c9e connect_channels /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x92b3fe1c get_send_slot /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x8845f183 free_channel /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x71bf823f create_channel /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x976ec4b2 send /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x113b0f31 ipc_start_thread /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x34e50186 transaction_complete /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x359192d7 async_recv /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0xd0da8d85 recv /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x1ee09005 connect_channels /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x5c36a119 get_send_slot /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0xe645d1eb free_channel /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0xceb54f4a create_channel /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0xeb904c91 send /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0xe64f92c0 ipc_start_thread /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x95ef1acc transaction_complete /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x32ce0958 async_recv /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
0x4262f6a8 recv /users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing EXPORT_SYMBOL
#include <linux/random.h>
#include <linux/slab.h>
#include "rpc.h"
#include <lcd-domains/thc.h>
#include <lcd-domains/thcinternal.h>
static struct ttd_ring_channel *channel;
......@@ -77,6 +80,30 @@ static unsigned long add_nums(unsigned long trans, unsigned long res1)
return result;
}
static unsigned long add_nums_async(unsigned long trans, unsigned long res1, awe_t* awe)
{
THCYield();
struct ipc_message *msg;
int i = 0;
unsigned long result;
unsigned long msg_id = (unsigned long)awe;
pr_err("msg id = %lx\n", msg_id);
msg = get_send_slot(channel);
msg->fn_type = ADD_NUMS;
msg->reg1 = trans;
msg->reg2 = res1;
msg->msg_id = msg_id;
send(channel,msg);
msg = recv(channel);
//msg = async_recv(channel, msg_id);
result = msg->reg1;
transaction_complete(msg);
return result;
}
static unsigned long add_3_nums(unsigned long trans, unsigned long res1,
unsigned long res2)
{
......@@ -162,7 +189,43 @@ static unsigned long add_6_nums(unsigned long trans, unsigned long res1,
return result;
}
void callee(struct ttd_ring_channel *chan)
static void test_async_ipc(struct ttd_ring_channel *chan)
{
unsigned long num_transactions = 0;
unsigned long res1, res2, res3, res4, res5, res6;
unsigned long start,end;
channel = chan;
current->ptstate = kzalloc(sizeof(struct ptstate_t), GFP_KERNEL);
thc_latch_init(&(current->ptstate->latch));
thc_init();
get_random_bytes(&res1, sizeof(res1));
res2 = res1+res1;
res3 = res1 + res2;
res4 = res3 + res2;
res5 = res4 + res3;
DO_FINISH(
// while (num_transactions < TRANSACTIONS) {
// start = RDTSC_START();
ASYNC(add_nums_async(num_transactions, res1, awe););
// printk(KERN_ERR "middle of async");
// ASYNC(add_nums_async(num_transactions + 1, res1, awe););
// end = RDTSCP();
// pr_err("%lu\n", end-start);
// num_transactions++;
// });
);
pr_err("Complete\n");
printk(KERN_ERR "lcd async exiting module and deleting ptstate");
thc_done();
kfree(current->ptstate);
}
static void test_sync_ipc(struct ttd_ring_channel *chan)
{
unsigned long num_transactions = 0;
unsigned long res1, res2, res3, res4, res5, res6;
......@@ -178,13 +241,12 @@ void callee(struct ttd_ring_channel *chan)
while (num_transactions < TRANSACTIONS/2) {
start = RDTSC_START();
null_invocation();
//res6 = add_6_nums(num_transactions,res1,res2,res3,res4,res5);
end = RDTSCP();
pr_err("%lu\n", end-start);
num_transactions++;
//pr_err("res6 is %lu\n on iteration, %lu",res6, num_transactions);
}
pr_err("6 regis\n");
while (num_transactions < TRANSACTIONS) {
start = RDTSC_START();
res6 = add_6_nums(num_transactions,res1,res2,res3,res4,res5);
......@@ -194,3 +256,43 @@ void callee(struct ttd_ring_channel *chan)
}
pr_err("Complete\n");
}
void foo3(void);
void foo4(void);
noinline void foo3(void) {
printk(KERN_ERR "lcd async entering foo1\n");
printk(KERN_ERR "lcd async yielding to foo2\n");
int count = 0;
while (count < 2) {
printk(KERN_ERR "lcd async Yielding\n");
THCYield();
count++;
}
printk(KERN_ERR "lcd async foo3 complete\n");
}
noinline void foo4(void) {
printk(KERN_ERR "lcd async entering foo2\n");
printk(KERN_ERR "lcd async foo2 Complete\n");
}
void callee(struct ttd_ring_channel *chan)
{
test_async_ipc(chan);
// test_sync_ipc(chan);
/*
current->ptstate = kzalloc(sizeof(struct ptstate_t), GFP_KERNEL);
thc_latch_init(&(current->ptstate->latch));
thc_init();
//assert((PTS() == NULL) && "PTS already initialized");
printk(KERN_ERR "lcd async entering module ptstate allocated");
DO_FINISH(ASYNC(foo3();); printk(KERN_ERR "lcd async apit_init coming back\n"); ASYNC(foo4();););
printk(KERN_ERR "lcd async end of DO_FINISH");
printk(KERN_ERR "lcd async exiting module and deleting ptstate");
thc_done();
kfree(current->ptstate);*/
}
......@@ -44,6 +44,8 @@ static unsigned long add_6_nums(unsigned long trans, unsigned long res1,
return add_3_nums(trans,res1,res2) + add_3_nums(res3,res4,res5);
}
void caller(struct ttd_ring_channel *chan)
{
......
......@@ -6,7 +6,7 @@ typedef enum {NULL_INVOCATION, ADD_CONSTANT, ADD_NUMS, ADD_3_NUMS,
ADD_4_NUMS, ADD_5_NUMS, ADD_6_NUMS} fn_types;
/* must be divisible by 6... because I call 6 functions in the Callee.c */
#define TRANSACTIONS 12000
#define TRANSACTIONS 1 //12000
void callee(struct ttd_ring_channel *chan);
......
......@@ -41,6 +41,7 @@ static void setup_tests(void)
connect_channels(chan1,chan2);
ipc_start_thread(chan1);
ipc_start_thread(chan2);
//callee(NULL);
}
static int __init rpc_init(void)
......
......@@ -21,17 +21,27 @@ __attribute__((section("__versions"))) = {
{ 0x4cd715f4, __VMLINUX_SYMBOL_STR(kmalloc_caches) },
{ 0x34083a97, __VMLINUX_SYMBOL_STR(_raw_spin_unlock) },
{ 0x79aa04a2, __VMLINUX_SYMBOL_STR(get_random_bytes) },
{ 0xb738e26c, __VMLINUX_SYMBOL_STR(thc_init) },
{ 0x920f13e1, __VMLINUX_SYMBOL_STR(_thc_pendingfree) },
{ 0x846f59a, __VMLINUX_SYMBOL_STR(cpu_info) },
{ 0x3ff3952e, __VMLINUX_SYMBOL_STR(kthread_create_on_node) },
{ 0xf4804989, __VMLINUX_SYMBOL_STR(_thc_lazy_awe_marker) },
{ 0x21942b31, __VMLINUX_SYMBOL_STR(current_task) },
{ 0x27e1a049, __VMLINUX_SYMBOL_STR(printk) },
{ 0x8693c29f, __VMLINUX_SYMBOL_STR(set_cpus_allowed_ptr) },
{ 0x7e192dff, __VMLINUX_SYMBOL_STR(_thc_endasync) },
{ 0xe221aa2a, __VMLINUX_SYMBOL_STR(_thc_endfinishblock) },
{ 0xb6029609, __VMLINUX_SYMBOL_STR(kmem_cache_alloc) },
{ 0x93fca811, __VMLINUX_SYMBOL_STR(__get_free_pages) },
{ 0x3c30ace4, __VMLINUX_SYMBOL_STR(wake_up_process) },
{ 0x58bec661, __VMLINUX_SYMBOL_STR(_raw_spin_lock) },
{ 0x2084cb51, __VMLINUX_SYMBOL_STR(THCYield) },
{ 0x4302d0eb, __VMLINUX_SYMBOL_STR(free_pages) },
{ 0xe4a7ae79, __VMLINUX_SYMBOL_STR(thc_latch_init) },
{ 0x37a0cba, __VMLINUX_SYMBOL_STR(kfree) },
{ 0x141b2c50, __VMLINUX_SYMBOL_STR(__put_task_struct) },
{ 0x407cc815, __VMLINUX_SYMBOL_STR(_thc_startfinishblock) },
{ 0xc6b4b936, __VMLINUX_SYMBOL_STR(thc_done) },
};
static const char __module_depends[]
......@@ -40,4 +50,4 @@ __attribute__((section(".modinfo"))) =
"depends=";
MODULE_INFO(srcversion, "008C0F0599B0C1F40356D4B");
MODULE_INFO(srcversion, "2328F1CEE67854C5E38D6AA");
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/irqflags.h>
#include <linux/kthread.h>
#include <linux/cpumask.h>
#include <linux/preempt.h>
#include <asm/uaccess.h>
#include <asm/mwait.h>
#include <asm/page_types.h>
#include <asm/cpufeature.h>
#include <linux/ktime.h>
#include <linux/sort.h>
#include <asm/tsc.h>
#include "ring-chan/ring-channel.h"
#include "betaModule.h"
MODULE_LICENSE("GPL");
static int CPU_NUM;
static unsigned int pTok = 0xC1346BAD;
static unsigned int cTok = 0xBADBEEF;
/* 124 byte message */
#if 0
static char *msg = "12345678123456781234567812345678123456781234567812345678" \
"1234567";
#endif
static unsigned long start;
static unsigned long end;
static volatile int should_stop;
#if defined(TIMING)
static u64 *timekeeper;
#endif
#if 0
/* Stolen and slightly modified from http://rosettacode.org/wiki/Rot-13 */
static char *rot13(char *s, int amount)
{
char *p = s;
int upper;
int count = 0;
while (*p && count < amount) {
upper = *p;
if ((upper >= 'a' && upper <= 'm') ||
(upper >= 'A' && upper <= 'M'))
*p += 13;
else if ((upper >= 'n' && upper <= 'z') ||
(upper >= 'A' && upper <= 'Z'))
*p -= 13;
++p;
count++;
}
return s;
}
#endif
#if defined(DEBUG_ASSERT_EXPECT)
static void assert_expect_and_zero(struct ipc_message *i_msg, int need_rot)
{
if (need_rot)
rot13(i_msg->message, BUF_SIZE);
if (strncmp(i_msg->message, msg, BUF_SIZE) != 0)
pr_err("STRINGS DIFFERED IN CPU %d\n", CPU_NUM);
i_msg->monitor = 0;
}
#endif
#if defined(USE_MWAIT)
static unsigned int find_target_mwait(void)
{
unsigned int eax, ebx, ecx, edx;
unsigned int highest_cstate = 0;
unsigned int highest_subcstate = 0;
int i;
if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
return 0;
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
!(ecx & CPUID5_ECX_INTERRUPT_BREAK))
return 0;
edx >>= MWAIT_SUBSTATE_SIZE;
for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
if (edx & MWAIT_SUBSTATE_MASK) {
highest_cstate = i;
highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
printk(KERN_DEBUG "Found cstate at %d and highest_subcstate %d\n",
i, highest_subcstate);
printk(KERN_DEBUG "IF WE WERE TO RETURN NOW IT WOUDL LOOK LIKE %x\n", (highest_cstate << MWAIT_SUBSTATE_SIZE) | (highest_subcstate -1));
}
}
return (highest_cstate << MWAIT_SUBSTATE_SIZE) |
(highest_subcstate - 1);
}
static inline void monitor_mwait(unsigned long rcx, volatile uint32_t *rax,
unsigned long wait_type)
{
__monitor((void *)rax, 0, 0);
/* TODO comment for memory barrier, why is this necessary? */
mb();
__mwait(wait_type, rcx);
}
#endif
//unsigned long flags;
//int cpu;
/* smp is supposed to be used under "lock", however one can use it if
* you have pegged your thread to a CPU, which we have.
*/
/* we know we're noot ona buggy cpu when we release we'll re-enable this */
/*cpu = smp_processor_id();
if (cpu_has_bug(&cpu_data(cpu), X86_BUG_CLFLUSH_MONITOR)) {
mb();
clflush(rax);
mb();
}*/
// local_irq_save(flags);
// local_irq_restore(flags);
static inline int check_cons_slot_available(struct ipc_message *loc, unsigned int token)
{
return (likely(loc->monitor != token));
}
static inline int check_prod_slot_available(struct ipc_message *loc, unsigned int token)
{
return (unlikely(loc->monitor != token));
}
static struct ipc_message * get_next_available_slot(struct ttd_ring_channel *chan,
unsigned long bucket)
{
return (struct ipc_message *) ttd_ring_channel_get_rec_slow(chan,bucket);
}
static int wait_for_producer_slot(struct ipc_message *imsg, unsigned int token)
{
while (check_prod_slot_available(imsg, token)) {
#if defined(USE_MWAIT)
cpu_relax();
monitor_mwait(ecx, &imsg->monitor, cstate_wait);
#endif//usemwait
#if defined(POLL)
cpu_relax();
// asm volatile("pause" ::: "memory");
//__builting_ia32_pause();
#endif
}
return 0;
}
static int wait_for_consumer_slot(struct ipc_message *imsg, unsigned int token)
{
while (check_cons_slot_available(imsg, token)) {
#if defined(USE_MWAIT)
monitor_mwait(ecx, &imsg->monitor, cstate_wait);
#endif//usemwait
#if defined(POLL)
cpu_relax();
//asm volatile("pause" ::: "memory");
#endif
}
return 0;
}
static unsigned long RDTSC_START(void)
{
unsigned cycles_low, cycles_high;
asm volatile ("CPUID\n\t"
"RDTSC\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low)::
"%rax", "%rbx", "%rcx", "%rdx");
return ((unsigned long) cycles_high << 32) | cycles_low;
}
static unsigned long RDTSCP(void)
{
unsigned long tsc;
__asm__ __volatile__(
"rdtscp;"
"shl $32, %%rdx;"
"or %%rdx, %%rax"
: "=a"(tsc)
:
: "%rcx", "%rdx");
return tsc;
}
static int ipc_thread_func(void *input)
{
#if defined(USE_FLOOD)
int i;
#endif
struct file *filep = input;
struct ipc_container *container = NULL;
struct ttd_ring_channel *prod_channel;
struct ttd_ring_channel *cons_channel;
unsigned long flags, count = 0;
unsigned int local_prod, local_cons;
struct ipc_message *prod_msg, *cons_msg;
unsigned long start64, end64;
if (filep == NULL) {
pr_debug("Thread was sent a null filepointer!\n");
return -EINVAL;
}
container = filep->private_data;
if (container == NULL || container->channel_tx == NULL
|| container->channel_rx == NULL) {
pr_debug("container was null in thread!\n");
return -EINVAL;
}
prod_channel = container->channel_tx;
cons_channel = container->channel_rx;
local_prod = 1;
local_cons = 1;
ttd_ring_channel_set_prod(prod_channel, 1);
ttd_ring_channel_set_cons(prod_channel, 0);
prod_msg = get_next_available_slot(prod_channel, local_prod);
cons_msg = get_next_available_slot(cons_channel, local_cons);
local_irq_save(flags);
preempt_disable();
while (count < NUM_LOOPS) {