Commit fbc8eb70 authored by Hejing Li's avatar Hejing Li
Browse files

Merge branch 'master' of https://github.com/FreakyPenguin/endhostsim-code into experiments

parents 73dbbf3f 98bdd3ad
...@@ -104,7 +104,7 @@ class Component(object): ...@@ -104,7 +104,7 @@ class Component(object):
self.proc.terminate() self.proc.terminate()
async def kill(self): async def kill(self):
self.proc.terminate() self.proc.kill()
async def int_term_kill(self, delay=5): async def int_term_kill(self, delay=5):
await self.interrupt() await self.interrupt()
......
...@@ -8,6 +8,7 @@ class NodeConfig(object): ...@@ -8,6 +8,7 @@ class NodeConfig(object):
prefix = 24 prefix = 24
cores = 1 cores = 1
memory = 512 memory = 512
disk_image = 'base'
app = None app = None
def config_str(self): def config_str(self):
...@@ -49,6 +50,7 @@ class NodeConfig(object): ...@@ -49,6 +50,7 @@ class NodeConfig(object):
def prepare_pre_cp(self): def prepare_pre_cp(self):
return [ return [
'set -x',
'export HOME=/root', 'export HOME=/root',
'export LANG=en_US', 'export LANG=en_US',
'export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:' + \ 'export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:' + \
...@@ -111,7 +113,9 @@ class CorundumLinuxNode(LinuxNode): ...@@ -111,7 +113,9 @@ class CorundumLinuxNode(LinuxNode):
class MtcpNode(NodeConfig): class MtcpNode(NodeConfig):
disk_image = 'mtcp'
pci_dev = '0000:00:02.0' pci_dev = '0000:00:02.0'
memory = 16 * 1024
num_hugepages = 4096 num_hugepages = 4096
def prepare_pre_cp(self): def prepare_pre_cp(self):
...@@ -121,7 +125,7 @@ class MtcpNode(NodeConfig): ...@@ -121,7 +125,7 @@ class MtcpNode(NodeConfig):
'mkdir -p /dev/hugepages', 'mkdir -p /dev/hugepages',
'mount -t hugetlbfs nodev /dev/hugepages', 'mount -t hugetlbfs nodev /dev/hugepages',
'mkdir -p /dev/shm', 'mkdir -p /dev/shm',
'mount -t tmpfs tmpfs /dev/shm' 'mount -t tmpfs tmpfs /dev/shm',
'echo ' + str(self.num_hugepages) + ' > /sys/devices/system/' + \ 'echo ' + str(self.num_hugepages) + ' > /sys/devices/system/' + \
'node/node0/hugepages/hugepages-2048kB/nr_hugepages', 'node/node0/hugepages/hugepages-2048kB/nr_hugepages',
] ]
...@@ -148,13 +152,17 @@ class MtcpNode(NodeConfig): ...@@ -148,13 +152,17 @@ class MtcpNode(NodeConfig):
"sndbuf = 8192\n" "sndbuf = 8192\n"
"tcp_timeout = 10\n" "tcp_timeout = 10\n"
"tcp_timewait = 0\n" "tcp_timewait = 0\n"
"stat_print = dpdk0\n")} "#stat_print = dpdk0\n")}
return {**m, **super().config_files()} return {**m, **super().config_files()}
class TASNode(NodeConfig): class TASNode(NodeConfig):
disk_image = 'tas'
pci_dev = '0000:00:02.0' pci_dev = '0000:00:02.0'
memory = 16 * 1024
num_hugepages = 4096 num_hugepages = 4096
fp_cores = 1
preload = True
def prepare_pre_cp(self): def prepare_pre_cp(self):
return super().prepare_pre_cp() + [ return super().prepare_pre_cp() + [
...@@ -163,22 +171,25 @@ class TASNode(NodeConfig): ...@@ -163,22 +171,25 @@ class TASNode(NodeConfig):
'mkdir -p /dev/hugepages', 'mkdir -p /dev/hugepages',
'mount -t hugetlbfs nodev /dev/hugepages', 'mount -t hugetlbfs nodev /dev/hugepages',
'mkdir -p /dev/shm', 'mkdir -p /dev/shm',
'mount -t tmpfs tmpfs /dev/shm' 'mount -t tmpfs tmpfs /dev/shm',
'echo ' + str(self.num_hugepages) + ' > /sys/devices/system/' + \ 'echo ' + str(self.num_hugepages) + ' > /sys/devices/system/' + \
'node/node0/hugepages/hugepages-2048kB/nr_hugepages', 'node/node0/hugepages/hugepages-2048kB/nr_hugepages',
] ]
def prepare_post_cp(self): def prepare_post_cp(self):
return super().prepare_post_cp() + [ cmds = super().prepare_post_cp() + [
'insmod /root/dpdk/lib/modules/5.4.46/extra/dpdk/igb_uio.ko', 'insmod /root/dpdk/lib/modules/5.4.46/extra/dpdk/igb_uio.ko',
'/root/mtcp/dpdk/usertools/dpdk-devbind.py -b igb_uio ' + '/root/dpdk/sbin/dpdk-devbind -b igb_uio ' + self.pci_dev,
self.pci_dev, 'cd /root/tas',
'insmod /root/mtcp/dpdk-iface-kmod/dpdk_iface.ko', 'tas/tas --ip-addr=%s/%d --fp-cores-max=%d --fp-no-ints &' % (
'/root/mtcp/dpdk-iface-kmod/dpdk_iface_main', self.ip, self.prefix, self.fp_cores),
'ip link set dev dpdk0 up', 'sleep 1'
'ip addr add %s/%d dev dpdk0' % (self.ip, self.prefix)
] ]
if self.preload:
cmds += ['export LD_PRELOAD=/root/tas/lib/libtas_interpose.so']
return cmds
class IperfTCPServer(AppConfig): class IperfTCPServer(AppConfig):
def run_cmds(self, node): def run_cmds(self, node):
...@@ -221,3 +232,39 @@ class NOPaxosClient(AppConfig): ...@@ -221,3 +232,39 @@ class NOPaxosClient(AppConfig):
class NOPaxosSequencer(AppConfig): class NOPaxosSequencer(AppConfig):
def run_cmds(self, node): def run_cmds(self, node):
return ['/root/nopaxos/sequencer/sequencer -c /root/sequencer.config'] return ['/root/nopaxos/sequencer/sequencer -c /root/sequencer.config']
class RPCServer(AppConfig):
port = 1234
threads = 1
max_flows = 1234
max_bytes = 1024
def run_cmds(self, node):
exe = 'echoserver_linux' if not isinstance(node, MtcpNode) else \
'echoserver_mtcp'
return ['cd /root/tasbench/micro_rpc',
'./%s %d %d /tmp/guest/mtcp.conf %d %d' % (exe, self.port,
self.threads, self.max_flows, self.max_bytes)]
class RPCClient(AppConfig):
server_ip = '10.0.0.1'
port = 1234
threads = 1
max_flows = 128
max_bytes = 1024
max_pending = 1
openall_delay = 2
max_msgs_conn = 0
max_pend_conns = 8
time = 25
def run_cmds(self, node):
exe = 'testclient_linux' if not isinstance(node, MtcpNode) else \
'testclient_mtcp'
return ['cd /root/tasbench/micro_rpc',
'./%s %s %d %d /tmp/guest/mtcp.conf %d %d %d %d %d %d &' % (exe,
self.server_ip, self.port, self.threads, self.max_bytes,
self.max_pending, self.max_flows, self.openall_delay,
self.max_msgs_conn, self.max_pend_conns),
'sleep %d' % (self.time)]
...@@ -15,7 +15,6 @@ class Simulator(object): ...@@ -15,7 +15,6 @@ class Simulator(object):
class HostSim(Simulator): class HostSim(Simulator):
node_config = None node_config = None
disk_image = 'base'
name = '' name = ''
wait = False wait = False
sleep = 0 sleep = 0
...@@ -61,8 +60,6 @@ class NetSim(Simulator): ...@@ -61,8 +60,6 @@ class NetSim(Simulator):
class QemuHost(HostSim): class QemuHost(HostSim):
mem = 16 * 1024 # 16G
def resreq_cores(self): def resreq_cores(self):
return self.node_config.cores + 1 return self.node_config.cores + 1
...@@ -72,7 +69,7 @@ class QemuHost(HostSim): ...@@ -72,7 +69,7 @@ class QemuHost(HostSim):
def prep_cmds(self, env): def prep_cmds(self, env):
to_path = env.hdcopy_path(self) to_path = env.hdcopy_path(self)
return [f'{env.qemu_img_path} create -f qcow2 -o ' return [f'{env.qemu_img_path} create -f qcow2 -o '
f'backing_file="{env.hd_path(self.disk_image)}" ' f'backing_file="{env.hd_path(self.node_config.disk_image)}" '
f'{env.hdcopy_path(self)}'] f'{env.hdcopy_path(self)}']
def run_cmd(self, env): def run_cmd(self, env):
...@@ -84,7 +81,7 @@ class QemuHost(HostSim): ...@@ -84,7 +81,7 @@ class QemuHost(HostSim):
'driver=raw ' 'driver=raw '
'-append "earlyprintk=ttyS0 console=ttyS0 root=/dev/sda1 ' '-append "earlyprintk=ttyS0 console=ttyS0 root=/dev/sda1 '
'init=/home/ubuntu/guestinit.sh rw" ' 'init=/home/ubuntu/guestinit.sh rw" '
f'-m {self.mem} -smp {self.node_config.cores} ') f'-m {self.node_config.memory} -smp {self.node_config.cores} ')
if len(self.nics) > 0: if len(self.nics) > 0:
assert len(self.nics) == 1 assert len(self.nics) == 1
cmd += f'-chardev socket,path={env.nic_pci_path(self.nics[0])},' cmd += f'-chardev socket,path={env.nic_pci_path(self.nics[0])},'
...@@ -93,7 +90,6 @@ class QemuHost(HostSim): ...@@ -93,7 +90,6 @@ class QemuHost(HostSim):
return cmd return cmd
class Gem5Host(HostSim): class Gem5Host(HostSim):
mem = 16 * 1024 # 16G
cpu_type_cp = 'X86KvmCPU' cpu_type_cp = 'X86KvmCPU'
cpu_type = 'TimingSimpleCPU' cpu_type = 'TimingSimpleCPU'
...@@ -121,9 +117,9 @@ class Gem5Host(HostSim): ...@@ -121,9 +117,9 @@ class Gem5Host(HostSim):
'--cacheline_size=64 --cpu-clock=3GHz ' '--cacheline_size=64 --cpu-clock=3GHz '
f'--checkpoint-dir={env.gem5_cpdir(self)} ' f'--checkpoint-dir={env.gem5_cpdir(self)} '
f'--kernel={env.gem5_kernel_path} ' f'--kernel={env.gem5_kernel_path} '
f'--disk-image={env.hd_raw_path(self.disk_image)} ' f'--disk-image={env.hd_raw_path(self.node_config.disk_image)} '
f'--disk-image={env.cfgtar_path(self)} ' f'--disk-image={env.cfgtar_path(self)} '
f'--cpu-type={cpu_type} --mem-size={self.mem}MB ' f'--cpu-type={cpu_type} --mem-size={self.node_config.memory}MB '
'--ddio-enabled --ddio-way-part=8 --mem-type=DDR4_2400_16x4 ') '--ddio-enabled --ddio-way-part=8 --mem-type=DDR4_2400_16x4 ')
if env.restore_cp: if env.restore_cp:
......
...@@ -6,18 +6,19 @@ e = exp.Experiment('qemu-nopaxos-ehseq') ...@@ -6,18 +6,19 @@ e = exp.Experiment('qemu-nopaxos-ehseq')
net = sim.NS3SequencerNet() net = sim.NS3SequencerNet()
e.add_network(net) e.add_network(net)
class NOPaxosHost(sim.QemuHost): class NOPaxosNode(node.CorundumLinuxNode):
disk_image = 'nopaxos' disk_image = 'nopaxos'
sequencer = sim.create_basic_hosts(e, 1, 'sequencer', net, sim.CorundumBMNIC, NOPaxosHost, sequencer = sim.create_basic_hosts(e, 1, 'sequencer', net, sim.CorundumBMNIC,
node.CorundumLinuxNode, node.NOPaxosSequencer, ip_start = 100) sim.QemuHost, NOPaxosNode, node.NOPaxosSequencer, ip_start = 100)
replicas = sim.create_basic_hosts(e, 3, 'replica', net, sim.CorundumBMNIC, NOPaxosHost, replicas = sim.create_basic_hosts(e, 3, 'replica', net, sim.CorundumBMNIC,
node.CorundumLinuxNode, node.NOPaxosReplica) sim.QemuHost, NOPaxosNode, node.NOPaxosReplica)
clients = sim.create_basic_hosts(e, 1, 'client', net, sim.CorundumBMNIC, NOPaxosHost, clients = sim.create_basic_hosts(e, 1, 'client', net, sim.CorundumBMNIC,
node.CorundumLinuxNode, node.NOPaxosClient, ip_start = 4) sim.QemuHost, NOPaxosNode, node.NOPaxosClient, ip_start = 4)
sequencer[0].sleep = 1 sequencer[0].sleep = 1
for i in range(len(replicas)): for i in range(len(replicas)):
replicas[i].node_config.app.index = i replicas[i].node_config.app.index = i
replicas[i].sleep = 1 replicas[i].sleep = 1
......
...@@ -9,10 +9,10 @@ e.add_network(net) ...@@ -9,10 +9,10 @@ e.add_network(net)
class NOPaxosHost(sim.QemuHost): class NOPaxosHost(sim.QemuHost):
disk_image = 'nopaxos' disk_image = 'nopaxos'
replicas = sim.create_basic_hosts(e, 3, 'replica', net, sim.CorundumBMNIC, NOPaxosHost, replicas = sim.create_basic_hosts(e, 3, 'replica', net, sim.CorundumBMNIC,
node.CorundumLinuxNode, node.NOPaxosReplica) sim.QemuHost, NOPaxosNode, node.NOPaxosReplica)
clients = sim.create_basic_hosts(e, 1, 'client', net, sim.CorundumBMNIC, NOPaxosHost, clients = sim.create_basic_hosts(e, 1, 'client', net, sim.CorundumBMNIC,
node.CorundumLinuxNode, node.NOPaxosClient, ip_start = 4) sim.QemuHost, node.CorundumLinuxNode, NOPaxosHost, ip_start = 4)
for i in range(len(replicas)): for i in range(len(replicas)):
replicas[i].node_config.app.index = i replicas[i].node_config.app.index = i
......
import modes.experiments as exp
import modes.simulators as sim
import modes.nodeconfig as node
msg_sizes = [64, 1024, 8092]
stacks = ['mtcp', 'tas', 'linux']
num_clients = 1
experiments = []
for msg_size in msg_sizes:
for stack in stacks:
e = exp.Experiment('qemu-ib-switch-rpc-%s-1t-1fpc-%db-0mpc' % (stack,msg_size))
net = sim.SwitchNet()
e.add_network(net)
if stack == 'tas':
n = node.TASNode
elif stack == 'mtcp':
n = node.MtcpNode
else:
n = node.I40eLinuxNode
servers = sim.create_basic_hosts(e, 1, 'server', net, sim.I40eNIC, sim.QemuHost,
n, node.RPCServer)
clients = sim.create_basic_hosts(e, num_clients, 'client', net, sim.I40eNIC,
sim.QemuHost, n, node.RPCClient, ip_start = 2)
for h in servers + clients:
h.node_config.cores = 1 if stack != 'tas' else 3
h.node_config.fp_cores = 1
h.node_config.app.threads = 1
h.node_config.app.max_bytes = msg_size
if stack == 'linux':
h.node_config.disk_image = 'tas'
servers[0].sleep = 5
for c in clients:
c.wait = True
c.node_config.app.server_ip = servers[0].node_config.ip
experiments.append(e)
...@@ -3,7 +3,8 @@ CPPFLAGS += -I../libnicbm/include/ ...@@ -3,7 +3,8 @@ CPPFLAGS += -I../libnicbm/include/
CXXFLAGS += -Wall -Wextra -Wno-unused-parameter -O3 -g CXXFLAGS += -Wall -Wextra -Wno-unused-parameter -O3 -g
LDFLGAS = -g LDFLGAS = -g
OBJS := i40e_bm.o i40e_queues.o i40e_adminq.o i40e_hmc.o i40e_lan.o xsums.o logger.o OBJS := i40e_bm.o i40e_queues.o i40e_adminq.o i40e_hmc.o i40e_lan.o xsums.o \
rss.o logger.o
all: i40e_bm all: i40e_bm
......
...@@ -155,6 +155,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) ...@@ -155,6 +155,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
addr <= I40E_QTX_TAIL(NUM_QUEUES - 1)) addr <= I40E_QTX_TAIL(NUM_QUEUES - 1))
{ {
val = regs.qtx_tail[(addr - I40E_QTX_TAIL(0)) / 4]; val = regs.qtx_tail[(addr - I40E_QTX_TAIL(0)) / 4];
} else if (addr >= I40E_QTX_CTL(0) &&
addr <= I40E_QTX_CTL(NUM_QUEUES - 1))
{
val = regs.qtx_ctl[(addr - I40E_QTX_CTL(0)) / 4];
} else if (addr >= I40E_QINT_RQCTL(0) && } else if (addr >= I40E_QINT_RQCTL(0) &&
addr <= I40E_QINT_RQCTL(NUM_QUEUES - 1)) addr <= I40E_QINT_RQCTL(NUM_QUEUES - 1))
{ {
...@@ -183,10 +187,14 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) ...@@ -183,10 +187,14 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
addr <= I40E_GLHMC_LANRXCNT(I40E_GLHMC_LANRXCNT_MAX_INDEX)) addr <= I40E_GLHMC_LANRXCNT(I40E_GLHMC_LANRXCNT_MAX_INDEX))
{ {
val = regs.glhmc_lanrxcnt[(addr - I40E_GLHMC_LANRXCNT(0)) / 4]; val = regs.glhmc_lanrxcnt[(addr - I40E_GLHMC_LANRXCNT(0)) / 4];
} else if (addr >= I40E_GLQF_HKEY(0) && } else if (addr >= I40E_PFQF_HKEY(0) &&
addr <= I40E_GLQF_HKEY(I40E_GLQF_HKEY_MAX_INDEX)) addr <= I40E_PFQF_HKEY(I40E_PFQF_HKEY_MAX_INDEX))
{
val = regs.pfqf_hkey[(addr - I40E_PFQF_HKEY(0)) / 128];
} else if (addr >= I40E_PFQF_HLUT(0) &&
addr <= I40E_PFQF_HLUT(I40E_PFQF_HLUT_MAX_INDEX))
{ {
val = regs.glqf_hkey[(addr - I40E_GLQF_HKEY(0)) / 4]; val = regs.pfqf_hlut[(addr - I40E_PFQF_HLUT(0)) / 128];
} else { } else {
switch (addr) { switch (addr) {
...@@ -374,6 +382,36 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr) ...@@ -374,6 +382,36 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
val = 0; val = 0;
break; break;
case I40E_PFQF_CTL_0:
val = regs.pfqf_ctl_0;
break;
case I40E_PRTDCB_FCCFG:
val = regs.prtdcb_fccfg;
break;
case I40E_PRTDCB_MFLCN:
val = regs.prtdcb_mflcn;
break;
case I40E_PRT_L2TAGSEN:
val = regs.prt_l2tagsen;
break;
case I40E_PRTQF_CTL_0:
val = regs.prtqf_ctl_0;
break;
case I40E_GLRPB_GHW:
val = regs.glrpb_ghw;
break;
case I40E_GLRPB_GLW:
val = regs.glrpb_glw;
break;
case I40E_GLRPB_PHW:
val = regs.glrpb_phw;
break;
case I40E_GLRPB_PLW:
val = regs.glrpb_plw;
break;
default: default:
#ifdef DEBUG_DEV #ifdef DEBUG_DEV
log << "unhandled mem read addr=" << addr log << "unhandled mem read addr=" << addr
...@@ -420,6 +458,11 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) ...@@ -420,6 +458,11 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
size_t idx = (addr - I40E_QTX_TAIL(0)) / 4; size_t idx = (addr - I40E_QTX_TAIL(0)) / 4;
regs.qtx_tail[idx] = val; regs.qtx_tail[idx] = val;
lanmgr.tail_updated(idx, false); lanmgr.tail_updated(idx, false);
} else if (addr >= I40E_QTX_CTL(0) &&
addr <= I40E_QTX_CTL(NUM_QUEUES - 1))
{
regs.qtx_ctl[(addr - I40E_QTX_CTL(0)) / 4] = val;
} else if (addr >= I40E_QINT_RQCTL(0) && } else if (addr >= I40E_QINT_RQCTL(0) &&
addr <= I40E_QINT_RQCTL(NUM_QUEUES - 1)) addr <= I40E_QINT_RQCTL(NUM_QUEUES - 1))
{ {
...@@ -452,10 +495,15 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) ...@@ -452,10 +495,15 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
addr <= I40E_GLHMC_LANRXCNT(I40E_GLHMC_LANRXCNT_MAX_INDEX)) addr <= I40E_GLHMC_LANRXCNT(I40E_GLHMC_LANRXCNT_MAX_INDEX))
{ {
regs.glhmc_lanrxcnt[(addr - I40E_GLHMC_LANRXCNT(0)) / 4] = val; regs.glhmc_lanrxcnt[(addr - I40E_GLHMC_LANRXCNT(0)) / 4] = val;
} else if (addr >= I40E_GLQF_HKEY(0) && } else if (addr >= I40E_PFQF_HKEY(0) &&
addr <= I40E_GLQF_HKEY(I40E_GLQF_HKEY_MAX_INDEX)) addr <= I40E_PFQF_HKEY(I40E_PFQF_HKEY_MAX_INDEX))
{
regs.pfqf_hkey[(addr - I40E_PFQF_HKEY(0)) / 128] = val;
lanmgr.rss_key_updated();
} else if (addr >= I40E_PFQF_HLUT(0) &&
addr <= I40E_PFQF_HLUT(I40E_PFQF_HLUT_MAX_INDEX))
{ {
regs.glqf_hkey[(addr - I40E_GLQF_HKEY(0)) / 4] = val; regs.pfqf_hlut[(addr - I40E_PFQF_HLUT(0)) / 128] = val;
} else { } else {
switch (addr) { switch (addr) {
case I40E_PFGEN_CTRL: case I40E_PFGEN_CTRL:
...@@ -564,6 +612,35 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val) ...@@ -564,6 +612,35 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
regs.pf_arqt = val; regs.pf_arqt = val;
break; break;
case I40E_PFQF_CTL_0:
regs.pfqf_ctl_0 = val;
break;
case I40E_PRTDCB_FCCFG:
regs.prtdcb_fccfg = val;
break;
case I40E_PRTDCB_MFLCN:
regs.prtdcb_mflcn = val;
break;
case I40E_PRT_L2TAGSEN:
regs.prt_l2tagsen = val;
break;
case I40E_PRTQF_CTL_0:
regs.prtqf_ctl_0 = val;
break;
case I40E_GLRPB_GHW:
regs.glrpb_ghw = val;
break;
case I40E_GLRPB_GLW:
regs.glrpb_glw = val;
break;
case I40E_GLRPB_PHW:
regs.glrpb_phw = val;
break;
case I40E_GLRPB_PLW:
regs.glrpb_plw = val;
break;
default: default:
#ifdef DEBUG_DEV #ifdef DEBUG_DEV
log << "unhandled mem write addr=" << addr log << "unhandled mem write addr=" << addr
...@@ -654,6 +731,25 @@ void i40e_bm::reset(bool indicate_done) ...@@ -654,6 +731,25 @@ void i40e_bm::reset(bool indicate_done)
} }
intevs[i].time = 0; intevs[i].time = 0;
} }
// add default hash key
regs.pfqf_hkey[0] = 0xda565a6d;
regs.pfqf_hkey[1] = 0xc20e5b25;
regs.pfqf_hkey[2] = 0x3d256741;
regs.pfqf_hkey[3] = 0xb08fa343;
regs.pfqf_hkey[4] = 0xcb2bcad0;
regs.pfqf_hkey[5] = 0xb4307bae;
regs.pfqf_hkey[6] = 0xa32dcb77;
regs.pfqf_hkey[7] = 0x0cf23080;
regs.pfqf_hkey[8] = 0x3bb7426a;
regs.pfqf_hkey[9] = 0xfa01acbe;
regs.pfqf_hkey[10] = 0x0;
regs.pfqf_hkey[11] = 0x0;
regs.pfqf_hkey[12] = 0x0;
regs.glrpb_ghw = 0xF2000;
regs.glrpb_phw = 0x1246;
regs.glrpb_plw = 0x0846;
} }
shadow_ram::shadow_ram(i40e_bm &dev_) shadow_ram::shadow_ram(i40e_bm &dev_)
......
...@@ -405,7 +405,24 @@ class lan_queue_rx : public lan_queue_base { ...@@ -405,7 +405,24 @@ class lan_queue_rx : public lan_queue_base {
uint32_t &reg_ena, uint32_t &fpm_basereg, uint32_t &reg_ena, uint32_t &fpm_basereg,
uint32_t &reg_intqctl); uint32_t &reg_intqctl);
virtual void reset(); virtual void reset();
void packet_received(const void *data, size_t len); void packet_received(const void *data, size_t len, uint32_t hash);
};
class rss_key_cache {
protected:
static const size_t key_len = 52;
static const size_t cache_len = 288; // big enough for 2x ipv6 (2x128 + 2x16)
bool cache_dirty;
const uint32_t (&key)[key_len / 4];
uint32_t cache[cache_len];
void build();
public:
rss_key_cache(const uint32_t (&key_)[key_len / 4]);
void set_dirty();
uint32_t hash_ipv4(uint32_t sip, uint32_t dip, uint16_t sp,
uint16_t dp);
}; };
// rx tx management // rx tx management
...@@ -417,15 +434,19 @@ class lan { ...@@ -417,15 +434,19 @@ class lan {
i40e_bm &dev; i40e_bm &dev;
logger log; logger log;
rss_key_cache rss_kc;
const size_t num_qs; const size_t num_qs;
lan_queue_rx **rxqs; lan_queue_rx **rxqs;
lan_queue_tx **txqs; lan_queue_tx **txqs;
bool rss_steering(const void *data, size_t len, uint16_t &queue,
uint32_t &hash);
public: public:
lan(i40e_bm &dev, size_t num_qs); lan(i40e_bm &dev, size_t num_qs);
void reset(); void reset();
void qena_updated(uint16_t idx, bool rx); void qena_updated(uint16_t idx, bool rx);
void tail_updated(uint16_t idx, bool rx); void tail_updated(uint16_t idx, bool rx);
void rss_key_updated();
void packet_received(const void *data, size_t len); void packet_received(const void *data, size_t len);
}; };
...@@ -481,6 +502,7 @@ protected: ...@@ -481,6 +502,7 @@ protected:
uint32_t qint_tqctl[NUM_QUEUES]; uint32_t qint_tqctl[NUM_QUEUES];
uint32_t qtx_ena[NUM_QUEUES]; uint32_t qtx_ena[NUM_QUEUES];
uint32_t qtx_tail[NUM_QUEUES]; uint32_t qtx_tail[NUM_QUEUES];
uint32_t qtx_ctl[NUM_QUEUES];
uint32_t qint_rqctl[NUM_QUEUES]; uint32_t qint_rqctl[NUM_QUEUES];
uint32_t qrx_ena[NUM_QUEUES]; uint32_t qrx_ena[NUM_QUEUES];
uint32_t qrx_tail[NUM_QUEUES]; uint32_t qrx_tail[NUM_QUEUES];
...@@ -507,7 +529,20 @@ protected: ...@@ -507,7 +529,20 @@ protected:
uint32_t pf_arqh; uint32_t pf_arqh;
uint32_t pf_arqt; uint32_t pf_arqt;
uint32_t glqf_hkey[13]; uint32_t pfqf_ctl_0;
uint32_t pfqf_hkey[13];
uint32_t pfqf_hlut[128];
uint32_t prtdcb_fccfg;
uint32_t prtdcb_mflcn;
uint32_t prt_l2tagsen;
uint32_t prtqf_ctl_0;
uint32_t glrpb_ghw;
uint32_t glrpb_glw;
uint32_t glrpb_phw;
uint32_t glrpb_plw;
}; };
public: public:
......
...@@ -2,17 +2,19 @@ ...@@ -2,17 +2,19 @@
#include <string.h> #include <string.h>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <arpa/inet.h>
#include "i40e_bm.h" #include "i40e_bm.h"
#include "i40e_base_wrapper.h" #include "i40e_base_wrapper.h"
#include "headers.h"
using namespace i40e; using namespace i40e;
extern nicbm::Runner *runner; extern nicbm::Runner *runner;
lan::lan(i40e_bm &dev_, size_t num_qs_) lan::lan(i40e_bm &dev_, size_t num_qs_)
: dev(dev_), log("lan"), num_qs(num_qs_) : dev(dev_), log("lan"), rss_kc(dev_.regs.pfqf_hkey), num_qs(num_qs_)
{ {
rxqs = new lan_queue_rx *[num_qs]; rxqs = new lan_queue_rx *[num_qs];
txqs = new lan_queue_tx *[num_qs]; txqs = new lan_queue_tx *[num_qs];
...@@ -29,6 +31,7 @@ lan::lan(i40e_bm &dev_, size_t num_qs_) ...@@ -29,6 +31,7 @@ lan::lan(i40e_bm &dev_, size_t num_qs_)
void lan::reset() void lan::reset()
{ {
rss_kc.set_dirty();
for (size_t i = 0; i < num_qs; i++) { for (size_t i = 0; i < num_qs; i++) {
rxqs[i]->reset(); rxqs[i]->reset();
txqs[i]->reset(); txqs[i]->reset();
...@@ -37,10 +40,11 @@ void lan::reset() ...@@ -37,10 +40,11 @@ void lan::reset()
void lan::qena_updated(uint16_t idx, bool rx) void lan::qena_updated(uint16_t idx, bool rx)
{ {
uint32_t &reg = (rx ? dev.regs.qrx_ena[idx] : dev.regs.qtx_ena[idx]);
#ifdef DEBUG_LAN #ifdef DEBUG_LAN
log << " qena updated idx=" << idx << " rx=" << rx << logger::endl; log << " qena updated idx=" << idx << " rx=" << rx << " reg=" << reg <<
logger::endl;
#endif #endif
uint32_t &reg = (rx ? dev.regs.qrx_ena[idx] : dev.regs.qtx_ena[idx]);
lan_queue_base &q = (rx ? static_cast<lan_queue_base &>(*rxqs[idx]) : lan_queue_base &q = (rx ? static_cast<lan_queue_base &>(*rxqs[idx]) :
static_cast<lan_queue_base &>(*txqs[idx])); static_cast<lan_queue_base &>(*txqs[idx]));
...@@ -64,14 +68,57 @@ void lan::tail_updated(uint16_t idx, bool rx) ...@@ -64,14 +68,57 @@ void lan::tail_updated(uint16_t idx, bool rx)
q.reg_updated(); q.reg_updated();
} }
void lan::rss_key_updated()
{
rss_kc.set_dirty();
}
bool lan::rss_steering(const void *data, size_t len, uint16_t &queue,
uint32_t &hash)
{
hash = 0;
const headers::pkt_tcp *tcp = reinterpret_cast<const headers::pkt_tcp *> (data);
const headers::pkt_udp *udp = reinterpret_cast<const headers::pkt_udp *> (data);
// should actually determine packet type and mask with enabled packet types
// TODO: ipv6
if (tcp->eth.type == htons(ETH_TYPE_IP) &&
tcp->ip.proto == IP_PROTO_TCP)
{
hash = rss_kc.hash_ipv4(ntohl(tcp->ip.src), ntohl(tcp->ip.dest),
ntohs(tcp->tcp.src), ntohs(tcp->tcp.dest));
} else if (udp->eth.type == htons(ETH_TYPE_IP) &&
udp->ip.proto == IP_PROTO_UDP)
{
hash = rss_kc.hash_ipv4(ntohl(udp->ip.src), ntohl(udp->ip.dest),
ntohs(udp->udp.src), ntohs(udp->udp.dest));
} else if (udp->eth.type == htons(ETH_TYPE_IP)) {
hash = rss_kc.hash_ipv4(ntohl(udp->ip.src), ntohl(udp->ip.dest), 0, 0);
} else {
return false;
}
uint16_t luts = (!(dev.regs.pfqf_ctl_0 & I40E_PFQF_CTL_0_HASHLUTSIZE_MASK) ?
128 : 512);
uint16_t idx = hash % luts;
queue = (dev.regs.pfqf_hlut[idx / 4] >> (8 * (idx % 4))) & 0x3f;
#ifdef DEBUG_LAN
log << " q=" << queue << " h=" << hash << " i=" << idx << logger::endl;
#endif
return true;
}
void lan::packet_received(const void *data, size_t len) void lan::packet_received(const void *data, size_t len)
{ {
#ifdef DEBUG_LAN #ifdef DEBUG_LAN
log << " packet received len=" << len << logger::endl; log << " packet received len=" << len << logger::endl;
#endif #endif
// TODO: steering uint32_t hash = 0;
rxqs[0]->packet_received(data, len); uint16_t queue = 0;
rss_steering(data, len, queue, hash);
rxqs[queue]->packet_received(data, len, hash);
} }
lan_queue_base::lan_queue_base(lan &lanmgr_, const std::string &qtype, lan_queue_base::lan_queue_base(lan &lanmgr_, const std::string &qtype,
...@@ -256,7 +303,7 @@ queue_base::desc_ctx &lan_queue_rx::desc_ctx_create() ...@@ -256,7 +303,7 @@ queue_base::desc_ctx &lan_queue_rx::desc_ctx_create()
return *new rx_desc_ctx(*this); return *new rx_desc_ctx(*this);
} }
void lan_queue_rx::packet_received(const void *data, size_t pktlen) void lan_queue_rx::packet_received(const void *data, size_t pktlen, uint32_t h)
{ {
size_t num_descs = (pktlen + dbuff_size - 1) / dbuff_size; size_t num_descs = (pktlen + dbuff_size - 1) / dbuff_size;
......
...@@ -164,6 +164,10 @@ void queue_base::reset() ...@@ -164,6 +164,10 @@ void queue_base::reset()
void queue_base::reg_updated() void queue_base::reg_updated()
{ {
#ifdef DEBUG_QUEUES
log << "reg_updated: tail=" << reg_tail << " enabled=" << (int) enabled <<
logger::endl;
#endif
if (!enabled) if (!enabled)
return; return;
......
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