Commit 1690dc51 authored by Vikram Narayanan's avatar Vikram Narayanan

test_mods: Fix cpu pinning when run under SMP lcds

parent 97cc35ce
......@@ -237,6 +237,117 @@ fail1:
}
#endif
static int setup_async_channel_on_node(int node_id, cptr_t *buf1_cptr_out, cptr_t *buf2_cptr_out,
struct thc_channel **chnl_out)
{
int ret;
cptr_t buf1_cptr, buf2_cptr;
gva_t buf1_addr, buf2_addr;
struct fipc_ring_channel *fchnl;
struct thc_channel *chnl;
unsigned int pg_order = PMFS_ASYNC_RPC_BUFFER_ORDER - PAGE_SHIFT;
LIBLCD_MSG("%s\n",__func__);
/*
* Allocate buffers
*
* (We use the lower level alloc. If we used the heap, even though
* we may alloc only 1 - 2 pages, we would end up sharing around
* 4 MB chunks of memory, since the heap uses coarse microkernel
* allocations.)
*/
printk("%s, allocate pages for lcd:%d on node: %d\n", __func__, current_lcd_id,
node_id);
ret = _lcd_alloc_pages_exact_node(node_id, GFP_KERNEL, pg_order, &buf1_cptr);
if (ret) {
LIBLCD_ERR("buf1 alloc");
goto fail1;
}
ret = _lcd_alloc_pages_exact_node(node_id, GFP_KERNEL, pg_order, &buf2_cptr);
if (ret) {
LIBLCD_ERR("buf2 alloc");
goto fail2;
}
/*
* Map them somewhere
*/
ret = lcd_map_virt(buf1_cptr, pg_order, &buf1_addr);
if (ret) {
LIBLCD_ERR("error mapping buf1");
goto fail3;
}
ret = lcd_map_virt(buf2_cptr, pg_order, &buf2_addr);
if (ret) {
LIBLCD_ERR("error mapping buf2");
goto fail4;
}
/*
* Prep buffers for rpc
*/
ret = fipc_prep_buffers(PMFS_ASYNC_RPC_BUFFER_ORDER,
(void *)gva_val(buf1_addr),
(void *)gva_val(buf2_addr));
if (ret) {
LIBLCD_ERR("prep buffers");
goto fail5;
}
LIBLCD_MSG("==> Prep buffers");
/*
* Alloc and init channel header
*/
fchnl = kmalloc(sizeof(*fchnl), GFP_KERNEL);
if (!fchnl) {
ret = -ENOMEM;
LIBLCD_ERR("chnl alloc");
goto fail6;
}
ret = fipc_ring_channel_init(fchnl, PMFS_ASYNC_RPC_BUFFER_ORDER,
(void *)gva_val(buf1_addr),
(void *)gva_val(buf2_addr));
if (ret) {
LIBLCD_ERR("ring chnl init");
goto fail7;
}
/*
* Install async channel in async dispatch loop
*/
chnl = kzalloc(sizeof(*chnl), GFP_KERNEL);
if (!chnl) {
ret = -ENOMEM;
LIBLCD_ERR("alloc failed");
goto fail8;
}
ret = thc_channel_init(chnl, fchnl);
if (ret) {
LIBLCD_ERR("error init'ing async channel group item");
goto fail9;
}
*buf1_cptr_out = buf1_cptr;
*buf2_cptr_out = buf2_cptr;
*chnl_out = chnl;
return 0;
fail9:
kfree(chnl);
fail8:
fail7:
kfree(fchnl);
fail6:
fail5:
lcd_unmap_virt(buf1_addr, pg_order);
fail4:
lcd_unmap_virt(buf1_addr, pg_order);
fail3:
lcd_cap_delete(buf2_cptr);
fail2:
lcd_cap_delete(buf1_cptr);
fail1:
return ret;
}
static int setup_async_channel(cptr_t *buf1_cptr_out, cptr_t *buf2_cptr_out,
struct thc_channel **chnl_out)
{
......@@ -481,6 +592,34 @@ fail1:
struct thc_channel_group_item *ptrs[NUM_LCDS][32];
static int idx[NUM_LCDS] = {0};
int create_one_async_channel_on_node(int node_id, struct thc_channel **chnl, cptr_t *tx, cptr_t *rx)
{
int ret;
struct thc_channel_group_item *xmit_ch_item;
ret = setup_async_channel_on_node(node_id, tx, rx, chnl);
if (ret) {
LIBLCD_ERR("async xmit chnl setup failed");
return -1;
}
xmit_ch_item = kzalloc(sizeof(*xmit_ch_item), GFP_KERNEL);
thc_channel_group_item_init(xmit_ch_item, *chnl, NULL);
xmit_ch_item->xmit_channel = true;
thc_channel_group_item_add(&ch_grp[current_lcd_id], xmit_ch_item);
printk("%s:%d adding chnl: %p to group: %p", __func__, current_lcd_id,
xmit_ch_item->channel, &ch_grp[current_lcd_id]);
ptrs[current_lcd_id][idx[current_lcd_id]++%32] = xmit_ch_item;
return 0;
}
int create_one_async_channel(struct thc_channel **chnl, cptr_t *tx, cptr_t *rx)
{
int ret;
......@@ -517,10 +656,34 @@ int prep_xmit_channels_lcd(void)
cptr_t tx[MAX_CHNL_PAIRS], rx[MAX_CHNL_PAIRS];
struct thc_channel *xmit;
int i, j;
int node_id;
for (i = 0; i < MAX_CHNL_PAIRS; i++) {
if (create_one_async_channel(&xmit, &tx[i], &rx[i]))
#if NUM_LCDS == 1
if (i >= 8) {
node_id = 1;
} else {
node_id = 0;
}
/* create half of the channel pairs on numa node 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 == 2
if (current_lcd_id == 0)
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 == 4
if ((current_lcd_id == 0) || (current_lcd_id == 1))
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");
#endif
}
for (i = 0, j = 5; i < MAX_CHNL_PAIRS && j < LCD_NUM_REGS; i++) {
......
......@@ -19,32 +19,32 @@
#include <liblcd/sync_ipc_poll.h>
enum dispatch_t {
REGISTER_NETDEVICE = 0,
UNREGISTER_NETDEVICE = 1,
ETHER_SETUP = 2,
ETH_MAC_ADDR =3,
ETH_VALIDATE_ADDR = 4,
FREE_NETDEV= 5,
NETIF_CARRIER_OFF=6,
REGISTER_NETDEVICE = 1,
UNREGISTER_NETDEVICE,
ETHER_SETUP,
ETH_MAC_ADDR,
ETH_VALIDATE_ADDR = 5,
FREE_NETDEV,
NETIF_CARRIER_OFF,
NETIF_CARRIER_ON,
__RTNL_LINK_REGISTER = 8,
__RTNL_LINK_UNREGISTER,
__RTNL_LINK_REGISTER,
__RTNL_LINK_UNREGISTER = 10,
RTNL_LINK_UNREGISTER,
ALLOC_NETDEV_MQS,
CONSUME_SKB = 12,
CONSUME_SKB,
NDO_INIT,
NDO_UNINIT,
NDO_UNINIT = 15,
NDO_START_XMIT,
NDO_VALIDATE_ADDR = 16,
NDO_VALIDATE_ADDR,
NDO_SET_RX_MODE,
NDO_SET_MAC_ADDRESS,
NDO_GET_STATS64,
NDO_CHANGE_CARRIER = 20,
VALIDATE = 21,
SETUP = 22,
TRIGGER_EXIT =23,
TRIGGER_CLEAN,
PREP_CHANNEL=25,
NDO_GET_STATS64 = 20,
NDO_CHANGE_CARRIER,
VALIDATE,
SETUP,
TRIGGER_EXIT,
TRIGGER_CLEAN = 25,
PREP_CHANNEL,
};
typedef enum {
......@@ -83,7 +83,17 @@ struct skbuff_members {
#define SENDER_DISPATCH_LOOP
#define CONFIG_PREALLOC_XMIT_CHANNELS
#define MAX_CHANNELS_PER_LCD 10
#if NUM_LCDS == 1
/* total LCD cores = 2 (lcds=1,klcd=1), free cores = 18 */
#define MAX_CHANNELS_PER_LCD 18
#elif NUM_LCDS == 2
/* total LCD cores = 3 (lcds=2,klcd=1), free cores = 17 */
#define MAX_CHANNELS_PER_LCD 9
#elif NUM_LCDS == 4
/* total LCD cores = 5 (lcds=4,klcd=1), free cores = 15 */
#define MAX_CHANNELS_PER_LCD 4
#endif
#define MAX_CHNL_PAIRS MAX_CHANNELS_PER_LCD
//#define NO_AWE
......
......@@ -36,9 +36,8 @@ extern struct ptstate_t *ptrs[NUM_THREADS];
extern struct rtnl_link_stats64 g_stats;
extern struct thc_channel *xmit_chnl;
extern priv_pool_t *skb_pool;
#ifndef CONFIG_PREALLOC_XMIT_CHANNELS
DEFINE_SPINLOCK(prep_lock);
#endif
/*
* setup a new channel for the first time when an application thread
* wishes to send a packet through this interface
......@@ -46,10 +45,15 @@ DEFINE_SPINLOCK(prep_lock);
int setup_once(struct trampoline_hidden_args *hidden_args)
{
int lcd_id;
#if NUM_LCDS == 1
#elif NUM_LCDS == 2
#else
static int count = 0;
printk("%s, %s:%d lcdenter \n", __func__,
current->comm, current->pid);
static int numa_count1 = 0;
static int numa_count0 = 0;
#endif
printk("%s, %s:%d lcdenter on cpu: %d\n", __func__,
current->comm, current->pid, smp_processor_id());
/* step 1. create lcd env */
lcd_enter();
......@@ -87,11 +91,37 @@ int setup_once(struct trampoline_hidden_args *hidden_args)
strlen("lt-iperf3"))) {
#ifdef CONFIG_PREALLOC_XMIT_CHANNELS
#if NUM_LCDS == 1
lcd_id = 0;
#elif NUM_LCDS == 2
if (smp_processor_id() < 8) {
lcd_id = 0;
} else {
lcd_id = 1;
}
#else
spin_lock(&prep_lock);
lcd_id = count++ % NUM_LCDS;
if (smp_processor_id() <= 6) {
numa_count0++;
if (numa_count0 % 2)
lcd_id = 0;
else
lcd_id = 1;
} else {
numa_count1++;
if (numa_count1 % 2)
lcd_id = 2;
else
lcd_id = 3;
}
spin_unlock(&prep_lock);
#endif
pick_channel(lcd_id);
#else
spin_lock(&prep_lock);
lcd_id = count++ % NUM_LCDS;
prep_channel(hidden_args, lcd_id);
spin_unlock(&prep_lock);
#endif
......
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