Commit f4ddfd93 authored by Vikram Narayanan's avatar Vikram Narayanan

test_mods/nullnet: Fixes for SMP

parent 42b9e0c8
subdir-ccflags-y += -DNUM_LCDS="2"
subdir-ccflags-y += -DNUM_LCDS="4"
obj-$(LCD_CONFIG_BUILD_NULLNET_BOOT) += boot/
......
......@@ -102,9 +102,14 @@ netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
dstats->tx_bytes += skb->len;
u64_stats_update_end(&dstats->syncp);
#else
/* XXX: Touching global variable brings down the bandwidth
* Do not do it for now
*/
#if 0
g_dstats.tx_packets++;
g_dstats.tx_bytes += skb->len;
#endif
#endif
#ifdef SENDER_DISPATCH_LOOP
dev_kfree_skb(skb);
......
......@@ -677,7 +677,14 @@ int prep_xmit_channels_lcd(void)
LIBLCD_ERR("async channel creation failed\n");
#elif NUM_LCDS == 4
if ((current_lcd_id == 0) || (current_lcd_id == 1))
if (current_lcd_id < 2)
node_id = 0;
else
node_id = 1;
if (create_one_async_channel_on_node(node_id, &xmit, &tx[i], &rx[i]))
LIBLCD_ERR("async channel creation failed\n");
#elif NUM_LCDS == 6
if (current_lcd_id < 3)
node_id = 0;
else
node_id = 1;
......@@ -1470,6 +1477,7 @@ int ndo_start_xmit_noawe_callee(struct fipc_message *_request, struct thc_channe
return ret;
}
#define MARSHAL
/* xmit_callee for async. This function receives the IPC and
* sends back a response
*/
......@@ -1477,19 +1485,23 @@ int ndo_start_xmit_async_bare_callee(struct fipc_message *_request, struct thc_c
{
struct fipc_message *response;
unsigned int request_cookie;
#ifdef MARSHAL
struct lcd_sk_buff_container static_skb_c;
struct lcd_sk_buff_container *skb_c = &static_skb_c;
struct sk_buff *skb = &skb_c->skbuff;
#endif
#ifdef COPY
struct skbuff_members *skb_lcd;
#endif
#ifdef MARSHAL
unsigned long skbh_offset, skb_end;
__be16 proto;
u32 len;
cptr_t skb_ref;
#endif
request_cookie = thc_get_request_cookie(_request);
#ifdef MARSHAL
skb_ref = __cptr(fipc_get_reg2(_request));
skbh_offset = fipc_get_reg3(_request);
......@@ -1497,13 +1509,16 @@ int ndo_start_xmit_async_bare_callee(struct fipc_message *_request, struct thc_c
skb_end = fipc_get_reg4(_request);
proto = fipc_get_reg5(_request);
len = fipc_get_reg6(_request);
#endif
fipc_recv_msg_end(thc_channel_to_fipc(channel),
_request);
#ifdef MARSHAL
skb->head = (char*)data_pool + skbh_offset;
skb->end = skb_end;
skb->len = len;
skb->private = true;
#endif
#ifdef COPY
skb_lcd = SKB_LCD_MEMBERS(skb);
......@@ -1523,14 +1538,13 @@ int ndo_start_xmit_async_bare_callee(struct fipc_message *_request, struct thc_c
skb->data = skb->head + skb_lcd->head_data_off;
#endif
fipc_recv_msg_end(thc_channel_to_fipc(channel),
_request);
#ifdef MARSHAL
skb_c->chnl = channel;
skb_c->cookie = request_cookie;
dummy_xmit(skb, NULL);
#endif
if (async_msg_blocking_send_start(channel, &response)) {
LIBLCD_ERR("error getting response msg");
......
......@@ -27,7 +27,7 @@ bool tdiff_valid = false;
u64 tdiff_disp = 0ull;
TS_DECL(disp_loop);
/* LOOP ---------------------------------------- */
#define REPORT_LCD_LOAD
//#define REPORT_LCD_LOAD
void create_async_channel(void);
......@@ -125,7 +125,9 @@ static void main_and_loop(void)
if( !ret )
{
#ifdef REPORT_LCD_LOAD
start_disp = lcd_RDTSC_START();
#endif
/* message for us */
if (async_msg_get_fn_type(msg) == NDO_START_XMIT) {
......
......@@ -86,12 +86,19 @@ struct skbuff_members {
#if NUM_LCDS == 1
/* total LCD cores = 2 (lcds=1,klcd=1), free cores = 18 */
#define MAX_CHANNELS_PER_LCD 18
#define NUM_THREADS_ON_NODE0 8
#elif NUM_LCDS == 2
/* total LCD cores = 3 (lcds=2,klcd=1), free cores = 17 */
#define MAX_CHANNELS_PER_LCD 9
#define NUM_THREADS_ON_NODE0 8
#elif NUM_LCDS == 4
/* total LCD cores = 5 (lcds=4,klcd=1), free cores = 15 */
#define MAX_CHANNELS_PER_LCD 4
#define NUM_THREADS_ON_NODE0 7
#elif NUM_LCDS == 6
/* total LCD cores = 7 (lcds=6,klcd=1), free cores = 13 */
#define MAX_CHANNELS_PER_LCD 3
#define NUM_THREADS_ON_NODE0 6
#endif
#define MAX_CHNL_PAIRS MAX_CHANNELS_PER_LCD
......
......@@ -137,6 +137,8 @@ struct lcd_smp {
int ndo_start_xmit_async_landing(struct sk_buff *first, struct net_device *dev, struct trampoline_hidden_args *hidden_args);
int __ndo_start_xmit_dummy(struct sk_buff *skb, struct net_device *dev, struct trampoline_hidden_args *hidden_args);
int __ndo_start_xmit_bare_fipc_nomarshal(struct sk_buff *skb, struct net_device *dev, struct trampoline_hidden_args *hidden_args);
void skb_data_pool_init(void)
{
......@@ -799,6 +801,8 @@ int LCD_TRAMPOLINE_LINKAGE(ndo_start_xmit_trampoline)
struct trampoline_hidden_args *hidden_args;
LCD_TRAMPOLINE_PROLOGUE(hidden_args, ndo_start_xmit_trampoline);
ndo_start_xmit_fp = ndo_start_xmit_async_landing;
//ndo_start_xmit_fp = __ndo_start_xmit_dummy;
//ndo_start_xmit_fp = __ndo_start_xmit_bare_fipc_nomarshal;
return ndo_start_xmit_fp(skb, dev, hidden_args);
}
......@@ -1266,9 +1270,10 @@ struct rtnl_link_stats64 *ndo_get_stats64(struct net_device *dev, struct rtnl_li
ndo_get_stats64_user(dev, stats, hidden_args);
});*/
#if 0
stats->tx_packets = g_stats.tx_packets;
stats->tx_bytes = g_stats.tx_bytes;
#endif
return stats;
}
......@@ -2533,7 +2538,8 @@ int pick_channel(int lcd_id)
used_channels = lcd_metadata[lcd_id].used_channels;
if (used_channels < MAX_CHANNELS_PER_LCD) {
printk("%s, lcd_id:%d picking channel[%d]: %p\n", __func__,
printk("%s, %s:%d lcd_id:%d picking channel[%d]: %p\n", __func__,
current->comm, current->pid,
lcd_id, used_channels, lcd_metadata[lcd_id].xmit_channels[used_channels]);
current->ptstate->thc_chnl = lcd_metadata[lcd_id].xmit_channels[used_channels];
lcd_metadata[lcd_id].used_channels++;
......
......@@ -94,15 +94,15 @@ int setup_once(struct trampoline_hidden_args *hidden_args)
#if NUM_LCDS == 1
lcd_id = 0;
#elif NUM_LCDS == 2
if (smp_processor_id() < 8) {
if (smp_processor_id() < NUM_THREADS_ON_NODE0) {
lcd_id = 0;
} else {
lcd_id = 1;
}
#else
#elif NUM_LCDS == 4
spin_lock(&prep_lock);
lcd_id = count++ % NUM_LCDS;
if (smp_processor_id() <= 6) {
if (smp_processor_id() < NUM_THREADS_ON_NODE0) {
numa_count0++;
if (numa_count0 % 2)
lcd_id = 0;
......@@ -116,6 +116,16 @@ int setup_once(struct trampoline_hidden_args *hidden_args)
lcd_id = 3;
}
spin_unlock(&prep_lock);
#elif NUM_LCDS == 6
spin_lock(&prep_lock);
lcd_id = count++ % NUM_LCDS;
if (smp_processor_id() < NUM_THREADS_ON_NODE0) {
lcd_id = numa_count0++ % (NUM_LCDS >> 1);
} else {
lcd_id = numa_count1++ % (NUM_LCDS >> 1);
lcd_id += (NUM_LCDS >> 1);
}
spin_unlock(&prep_lock);
#endif
pick_channel(lcd_id);
#else
......@@ -255,9 +265,16 @@ fail_ipc:
int __ndo_start_xmit_bare_async(struct sk_buff *skb, struct net_device *dev, struct trampoline_hidden_args *hidden_args)
{
struct fipc_message *_request;
struct fipc_message *_response;
struct thc_channel *async_chnl = NULL;
xmit_type_t xmit_type;
_TS_DECL(xmit);
unsigned int request_cookie;
int ret;
#ifdef TIMESTAMP
u32 i;
_TS_DECL(xmit);
#endif
xmit_type = check_skb_range(skb);
......@@ -273,10 +290,12 @@ int __ndo_start_xmit_bare_async(struct sk_buff *skb, struct net_device *dev, str
goto free;
}
async_chnl = (struct thc_channel*) PTS()->thc_chnl;
/*
* doesn't free the packet NUM_TRANSACTIONS times
* frees the packet only once
*/
#ifdef TIMESTAMP
_TS_START(xmit);
for (i = 0; i < NUM_TRANSACTIONS; i++) {
int j;
......@@ -292,6 +311,35 @@ int __ndo_start_xmit_bare_async(struct sk_buff *skb, struct net_device *dev, str
printk("%s, do_finish{async()}; %d transactions took %llu\n", __func__,
NUM_TRANSACTIONS, _TS_DIFF(xmit)/NUM_TRANSACTIONS);
#endif
ret = fipc_test_blocking_send_start(
async_chnl, &_request);
if (unlikely(ret)) {
LIBLCD_ERR("failed to get a send slot");
goto fail_async;
}
async_msg_set_fn_type(_request, NDO_START_XMIT);
/* inform LCD that it is async */
fipc_set_reg0(_request, 1);
ret = thc_ipc_send_request(async_chnl, _request, &request_cookie);
ret = thc_ipc_recv_response_inline(async_chnl, request_cookie,
&_response);
awe_mapper_remove_id(request_cookie);
if (unlikely(ret)) {
LIBLCD_ERR("thc_ipc_call");
goto fail_ipc;
}
ret = fipc_get_reg1(_response);
fipc_recv_msg_end(thc_channel_to_fipc( async_chnl), _response);
fail_ipc:
fail_async:
free:
dev_kfree_skb(skb);
return NETDEV_TX_OK;
......@@ -307,6 +355,7 @@ int __ndo_start_xmit_bare_fipc_nomarshal(struct sk_buff *skb, struct net_device
xmit_type_t xmit_type;
struct thc_channel *async_chnl;
#ifdef TIMESTAMP
_TS_DECL(xmit);
_TS_START(xmit);
#endif
......@@ -447,6 +496,14 @@ int ndo_start_xmit_noasync(struct sk_buff *skb, struct net_device *dev, struct t
fipc_send_msg_end(thc_channel_to_fipc(
async_chnl), _request);
/*
* XXX: Touching global variable affects the bandwidth. Ideally, it
* should be a per-cpu thing. So, disable stats collection for now
*/
#if 0
g_stats.tx_packets += 1;
g_stats.tx_bytes += skb->len;
#endif
//printk("%s, msg sent on chnl %p\n", __func__, async_chnl);
#ifdef SENDER_DISPATCH_LOOP
/* to receive consume_skb */
......@@ -464,9 +521,17 @@ int ndo_start_xmit_noasync(struct sk_buff *skb, struct net_device *dev, struct t
*/
fipc_set_reg0(_request1, (uint64_t) skb);
if (async_msg_get_fn_type(_request1) != CONSUME_SKB) {
printk("%s Discard bogus message type= %d\n", __func__,
async_msg_get_fn_type(_request1));
fipc_recv_msg_end(thc_channel_to_fipc(async_chnl), _request1);
goto skip;
}
/* call consume_skb */
dispatch_async_loop(async_chnl, _request1, hidden_args->cspace,
hidden_args->sync_ep);
skip:
#endif
//printk("%s, waiting on chnl %p for real resp\n", __func__, async_chnl);
......@@ -483,8 +548,6 @@ free:
#ifndef SENDER_DISPATCH_LOOP
dev_kfree_skb(skb);
#endif
g_stats.tx_packets += 1;
g_stats.tx_bytes += skb->len;
return NETDEV_TX_OK;
}
......@@ -593,8 +656,14 @@ free:
#ifndef SENDER_DISPATCH_LOOP
dev_kfree_skb(skb);
#endif
/*
* XXX: Touching global variable affects the bandwidth. Ideally, it
* should be a per-cpu thing. So, disable stats collection for now
*/
#if 0
g_stats.tx_packets += 1;
g_stats.tx_bytes += skb->len;
#endif
fail_async:
fail_ipc:
......
Markdown is supported
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