Commit a07b6987 authored by Michael Quigley's avatar Michael Quigley
Browse files

Started integrating IPC with Async code. This is not functional yet. There is...

Started integrating IPC with Async code. This is not functional yet. There is a bug inside the Async code. It seems to be walking up the stack incorrectly and eventually dereferencing something that is not a valid pointer. Working on fixing it.
parents 5468ae3d 724861a8
......@@ -29,8 +29,6 @@ static unsigned int send_message = 0xBADBEEF;
static unsigned int rx_msg_avail = 0xBADBEEF;
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*) )
......@@ -98,16 +96,47 @@ static int wait_for_rx_slot(struct ipc_message *imsg, bool is_async)
}
struct task_struct *attach_thread_to_channel(struct ttd_ring_channel *chan,
int CPU_PIN,
int (*threadfn)(void *data)) {
struct cpumask cpu_core;
if (!chan)
return NULL;
if (CPU_PIN > num_online_cpus()) {
pr_err("Trying to pin on cpu > than avail # cpus\n");
return NULL;
}
chan->thread = kthread_create(threadfn, (void *)chan,
"AsyncIPC.%u", CPU_PIN);
if (IS_ERR(chan->thread)) {
pr_err("Error while creating kernel thread\n");
return NULL;
}
get_task_struct(chan->thread);
cpumask_clear(&cpu_core);
cpumask_set_cpu(CPU_PIN , &cpu_core);
set_cpus_allowed_ptr(chan->thread, &cpu_core);
return chan->thread;
}
/*
Create a channel with a ring-buffer of size pages
Create a communication thread on CPU
*/
* Create a channel with a ring-buffer of size pages
*/
struct ttd_ring_channel *create_channel(unsigned long size_pages, unsigned CPU)
struct ttd_ring_channel *create_channel(unsigned long size_pages)
{
int i,ret;
struct cpumask cpu_core;
struct ttd_ring_channel *channel;
......@@ -142,25 +171,6 @@ struct ttd_ring_channel *create_channel(unsigned long size_pages, unsigned CPU)
for (i = 0; i < (size_pages * PAGE_SIZE)/sizeof(int); i++)
*((int *)channel->tx.recs+i) = tx_slot_avail;
channel->thread = kthread_create(&dispatch, (void *)channel,
"betaIPC.%u", CPU);
if (IS_ERR(channel->thread)) {
ttd_ring_channel_free(channel);
kfree(channel);
pr_err("Error while creating kernel thread\n");
return NULL;
}
get_task_struct(channel->thread);
cpumask_clear(&cpu_core);
cpumask_set_cpu(CPU,&cpu_core);
set_cpus_allowed_ptr(channel->thread, &cpu_core);
return channel;
}
EXPORT_SYMBOL(create_channel);
......
......@@ -28,8 +28,10 @@ struct ipc_message{
volatile uint32_t msg_status;
}__attribute__((packed));
struct ttd_ring_channel *create_channel(unsigned long size_pages, unsigned CPU);
struct ttd_ring_channel *create_channel(unsigned long size_pages);
struct task_struct *attach_thread_to_channel(struct ttd_ring_channel *chan,
int CPU_PIN,
int (*threadfn)(void *data));
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);
......
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
......@@ -82,10 +82,8 @@ static unsigned long add_nums(unsigned long trans, unsigned long res1)
static unsigned long add_nums_async(unsigned long trans, unsigned long res1, awe_t* awe)
{
THCYield();
struct ipc_message *msg;
int i = 0;
//int i = 0;
unsigned long result;
unsigned long msg_id = (unsigned long)awe;
......@@ -96,8 +94,8 @@ static unsigned long add_nums_async(unsigned long trans, unsigned long res1, awe
msg->reg2 = res1;
msg->msg_id = msg_id;
send(channel,msg);
msg = recv(channel);
//msg = async_recv(channel, msg_id);
//msg = recv(channel);
msg = async_recv(channel, msg_id);
result = msg->reg1;
transaction_complete(msg);
......@@ -191,7 +189,7 @@ static unsigned long add_6_nums(unsigned long trans, unsigned long res1,
static void test_async_ipc(struct ttd_ring_channel *chan)
static void test_async_ipc(void* chan)
{
unsigned long num_transactions = 0;
unsigned long res1, res2, res3, res4, res5, res6;
......@@ -209,7 +207,7 @@ static void test_async_ipc(struct ttd_ring_channel *chan)
res4 = res3 + res2;
res5 = res4 + res3;
DO_FINISH(
// while (num_transactions < TRANSACTIONS) {
// while (num_transactions < ASYNC_TRANSACTIONS) {
// start = RDTSC_START();
ASYNC(add_nums_async(num_transactions, res1, awe););
// printk(KERN_ERR "middle of async");
......@@ -225,7 +223,7 @@ static void test_async_ipc(struct ttd_ring_channel *chan)
kfree(current->ptstate);
}
static void test_sync_ipc(struct ttd_ring_channel *chan)
static void test_sync_ipc(void* chan)
{
unsigned long num_transactions = 0;
unsigned long res1, res2, res3, res4, res5, res6;
......@@ -255,6 +253,7 @@ static void test_sync_ipc(struct ttd_ring_channel *chan)
num_transactions++;
}
pr_err("Complete\n");
return 1;
}
void foo3(void);
......@@ -279,11 +278,11 @@ noinline void foo4(void) {
void callee(struct ttd_ring_channel *chan)
void callee(void *chan)
{
test_async_ipc(chan);
// test_async_ipc(chan);
// test_sync_ipc(chan);
test_sync_ipc(chan);
/*
current->ptstate = kzalloc(sizeof(struct ptstate_t), GFP_KERNEL);
thc_latch_init(&(current->ptstate->latch));
......
......@@ -46,11 +46,12 @@ static unsigned long add_6_nums(unsigned long trans, unsigned long res1,
void caller(struct ttd_ring_channel *chan)
int caller(void *channel)
{
unsigned long num_transactions = 0;
unsigned long temp_res = 0;
struct ttd_ring_channel *chan = channel;
struct ipc_message *msg;
while (num_transactions < TRANSACTIONS) {
msg = recv(chan);
......@@ -118,4 +119,5 @@ void caller(struct ttd_ring_channel *chan)
}
num_transactions++;
}
return 1;
}
kernel//users/mquigley/fast-ipc-module/current/tests/rpc/rpc_testing.ko
......@@ -6,8 +6,8 @@ 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 1 //12000
#define TRANSACTIONS 12000
void callee(struct ttd_ring_channel *chan);
void caller(struct ttd_ring_channel *chan);
int callee(void *chan);
int caller(void *chan);
#include "rpc.h"
#include <linux/spinlock.h>
static volatile int migrate;
static spinlock_t lock = __SPIN_LOCK_UNLOCKED();
int dispatch(void *data)
{
/*
* Normally one person doesn't create both threads
* This means they both wont call the same dispatch function
* but since I've created two threads we need to seperate them
* into calle and callers.
* that is what this code below is doing
*/
spin_lock(&lock);
if(migrate == 0) {
migrate = 1;
spin_unlock(&lock);
callee(data);
free_channel(data);
return 1;
}
spin_unlock(&lock);
caller(data);
free_channel(data);
return 1;
}
......@@ -20,6 +20,10 @@
#include "rpc.h"
#define CHAN1_CPU 1
#define CHAN2_CPU 3
#define CHAN_NUM_PAGES 4
static struct ttd_ring_channel *chan1;
static struct ttd_ring_channel *chan2;
......@@ -27,18 +31,31 @@ MODULE_LICENSE("GPL");
static void setup_tests(void)
{
chan1 = create_channel(4,0);
chan1 = create_channel(CHAN_NUM_PAGES);
if (!chan1) {
pr_err("Failed to create channel 1");
return;
}
chan2 = create_channel(4,3);
chan2 = create_channel(CHAN_NUM_PAGES);
if (!chan2) {
pr_err("Failed to create channel 2");
free_channel(chan1);
return;
}
connect_channels(chan1,chan2);
connect_channels(chan1, chan2);
/* Create a thread for each channel to utilize, pin it to a core.
* Pass a function pointer to call on wakeup.
*/
if (attach_thread_to_channel(chan1, CHAN1_CPU, callee) == NULL ||
attach_thread_to_channel(chan2, CHAN2_CPU, caller) == NULL ) {
ttd_ring_channel_free(chan1);
ttd_ring_channel_free(chan2);
kfree(chan1);
kfree(chan2);
return;
}
ipc_start_thread(chan1);
ipc_start_thread(chan2);
//callee(NULL);
......
#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
{ 0x6f3cc8d6, __VMLINUX_SYMBOL_STR(module_layout) },
{ 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[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
MODULE_INFO(srcversion, "2328F1CEE67854C5E38D6AA");
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment