updated arp.

This commit is contained in:
kodario 2022-07-29 17:18:35 +02:00
parent 48e4f41291
commit b6632216b3
13 changed files with 204 additions and 174 deletions

View File

@ -158,12 +158,6 @@ extern int cyt_arch;
#define POLL_TIMEOUT_SECONDS 10 #define POLL_TIMEOUT_SECONDS 10
#define NUM_POLLS_PER_SCHED 100 #define NUM_POLLS_PER_SCHED 100
/* Network */
#define BASE_IP_ADDR_0 0x0A01D497
#define BASE_IP_ADDR_1 0x0A01D497
#define NODE_ID 0
#define N_TOTAL_NODES 2
/* Physical address (ECI) */ /* Physical address (ECI) */
#define IO_PHYS_ADDR 0x900000000000UL #define IO_PHYS_ADDR 0x900000000000UL
@ -670,6 +664,10 @@ struct bus_drvdata {
int en_tcp_1; int en_tcp_1;
int en_net_0; int en_net_0;
int en_net_1; int en_net_1;
uint32_t net_0_ip_addr;
uint32_t net_0_boardnum;
uint32_t net_1_ip_addr;
uint32_t net_1_boardnum;
volatile struct fpga_stat_cnfg_regs *fpga_stat_cnfg; volatile struct fpga_stat_cnfg_regs *fpga_stat_cnfg;
struct fpga_dev *fpga_dev; struct fpga_dev *fpga_dev;

View File

@ -117,16 +117,6 @@ void read_static_config(struct bus_drvdata *d)
d->en_net_0 = d->en_rdma_0 | d->en_tcp_0; d->en_net_0 = d->en_rdma_0 | d->en_tcp_0;
d->en_net_1 = d->en_rdma_1 | d->en_tcp_1; d->en_net_1 = d->en_rdma_1 | d->en_tcp_1;
// network board setup (TODO: maybe move to sw fully?)
if (d->en_net_0) {
d->fpga_stat_cnfg->net_0_ip = BASE_IP_ADDR_0 + NODE_ID;
d->fpga_stat_cnfg->net_0_boardnum = NODE_ID;
}
if (d->en_net_1) {
d->fpga_stat_cnfg->net_1_ip = BASE_IP_ADDR_1 + NODE_ID;
d->fpga_stat_cnfg->net_1_boardnum = NODE_ID;
}
// lowspeed ctrl // lowspeed ctrl
d->fpga_stat_cnfg->lspeed_cnfg = EN_LOWSPEED; d->fpga_stat_cnfg->lspeed_cnfg = EN_LOWSPEED;
} }

View File

@ -282,19 +282,15 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
// arp lookup // arp lookup
case IOCTL_ARP_LOOKUP: case IOCTL_ARP_LOOKUP:
if (pd->en_net_0 || pd->en_net_1) { if (pd->en_net_0 || pd->en_net_1) {
ret_val = copy_from_user(&tmp, (unsigned long*) arg, sizeof(unsigned long)); ret_val = copy_from_user(&tmp, (unsigned long*) arg, 2 * sizeof(unsigned long));
if (ret_val != 0) { if (ret_val != 0) {
pr_info("user data could not be coppied, return %d\n", ret_val); pr_info("user data could not be coppied, return %d\n", ret_val);
} else { } else {
dbg_info("arp lookup ..."); dbg_info("arp lookup qsfp%llx, target ip %08llx", tmp[0], tmp[1]);
spin_lock(&pd->stat_lock); spin_lock(&pd->stat_lock);
for (i = 0; i < N_TOTAL_NODES; i++) { tmp[0] ? (pd->fpga_stat_cnfg->net_1_arp = tmp[1]) :
if (i == NODE_ID) (pd->fpga_stat_cnfg->net_0_arp = tmp[1]);
continue;
tmp[0] ? (pd->fpga_stat_cnfg->net_1_arp = BASE_IP_ADDR_1 + i) :
(pd->fpga_stat_cnfg->net_0_arp = BASE_IP_ADDR_0 + i);
}
spin_unlock(&pd->stat_lock); spin_unlock(&pd->stat_lock);
} }
@ -314,12 +310,23 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
else { else {
spin_lock(&pd->stat_lock); spin_lock(&pd->stat_lock);
// Set ip // ip change
tmp[0] ? (pd->fpga_stat_cnfg->net_1_ip = tmp[1]) : if(tmp[0]) {
(pd->fpga_stat_cnfg->net_0_ip = tmp[1]); if(pd->net_1_ip_addr != tmp[1]) {
pd->fpga_stat_cnfg->net_1_ip = tmp[1];
dbg_info("ip address qsfp%llx changed to %08llx\n", tmp[0], tmp[1]);
pd->net_1_ip_addr = tmp[1];
}
} else {
if(pd->net_0_ip_addr != tmp[1]) {
pd->fpga_stat_cnfg->net_0_ip = tmp[1];
dbg_info("ip address qsfp%llx changed to %08llx\n", tmp[0], tmp[1]);
pd->net_0_ip_addr = tmp[1];
}
}
spin_unlock(&pd->stat_lock); spin_unlock(&pd->stat_lock);
dbg_info("ip address changed to %llx\n", tmp[1]);
} }
} else { } else {
pr_info("network not enabled\n"); pr_info("network not enabled\n");
@ -337,12 +344,22 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} else { } else {
spin_lock(&pd->stat_lock); spin_lock(&pd->stat_lock);
// Set board number // board number change
tmp[0] ? (pd->fpga_stat_cnfg->net_1_boardnum = tmp[1]) : if(tmp[0]) {
(pd->fpga_stat_cnfg->net_0_boardnum = tmp[1]); if(pd->net_1_boardnum != tmp[1]) {
pd->fpga_stat_cnfg->net_1_boardnum = tmp[1];
dbg_info("board number qsfp%llx changed to %llx\n", tmp[0], tmp[1]);
pd->net_1_boardnum = tmp[1];
}
} else {
if(pd->net_0_boardnum != tmp[1]) {
pd->fpga_stat_cnfg->net_0_boardnum = tmp[1];
dbg_info("board number qsfp%llx changed to %llx\n", tmp[0], tmp[1]);
pd->net_0_boardnum = tmp[1];
}
}
spin_unlock(&pd->stat_lock); spin_unlock(&pd->stat_lock);
dbg_info("board number changed to %llx\n", tmp[1]);
} }
} else { } else {
pr_info("network not enabled\n"); pr_info("network not enabled\n");
@ -426,7 +443,7 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
((uint64_t)pd->en_avx) | ((uint64_t)pd->en_bypass << 1) | ((uint64_t)pd->en_tlbf << 2) | ((uint64_t)pd->en_wb << 3) | ((uint64_t)pd->en_avx) | ((uint64_t)pd->en_bypass << 1) | ((uint64_t)pd->en_tlbf << 2) | ((uint64_t)pd->en_wb << 3) |
((uint64_t)pd->en_strm << 4) | ((uint64_t)pd->en_mem << 5) | ((uint64_t)pd->en_pr << 6) | ((uint64_t)pd->en_strm << 4) | ((uint64_t)pd->en_mem << 5) | ((uint64_t)pd->en_pr << 6) |
((uint64_t)pd->en_rdma_0 << 16) | ((uint64_t)pd->en_rdma_1 << 17) | ((uint64_t)pd->en_tcp_0 << 18) | ((uint64_t)pd->en_tcp_1 << 19); ((uint64_t)pd->en_rdma_0 << 16) | ((uint64_t)pd->en_rdma_1 << 17) | ((uint64_t)pd->en_tcp_0 << 18) | ((uint64_t)pd->en_tcp_1 << 19);
dbg_info("reading config %llx\n", tmp[0]); dbg_info("reading config 0x%llx\n", tmp[0]);
ret_val = copy_to_user((unsigned long *)arg, &tmp, sizeof(unsigned long)); ret_val = copy_to_user((unsigned long *)arg, &tmp, sizeof(unsigned long));
break; break;

View File

@ -22,17 +22,24 @@ using namespace std;
using namespace std::chrono; using namespace std::chrono;
using namespace fpga; using namespace fpga;
/* Runtime */ /* Params */
constexpr auto const nIdMaster = 0; constexpr auto const mstrNodeId = 0;
constexpr auto const nBenchRuns = 1;
constexpr auto const nReps = 1000;
constexpr auto const defSize = 128;
constexpr auto const maxSize = 1 * 1024 * 1024;
constexpr auto const defOper = 0;
constexpr auto const targetRegion = 0; constexpr auto const targetRegion = 0;
constexpr auto const defMstrIp = "10.1.212.123";
constexpr auto const defPort = 18488;
constexpr auto const qpId = 0; constexpr auto const qpId = 0;
constexpr auto const port = 18488;
/* Runtime */
constexpr auto const defQsfp = 0;
constexpr auto const defNodeId = 0;
constexpr auto const defTcpMstrIp = "192.168.98.97";
constexpr auto const defIbvIp = "192.168.98.97";
/* Bench */
constexpr auto const defNBenchRuns = 1;
constexpr auto const defNReps = 1000;
constexpr auto const defMinSize = 128;
constexpr auto const defMaxSize = 1 * 1024 * 1024;
constexpr auto const defOper = 0;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -43,50 +50,59 @@ int main(int argc, char *argv[])
// Read arguments // Read arguments
boost::program_options::options_description programDescription("Options:"); boost::program_options::options_description programDescription("Options:");
programDescription.add_options() programDescription.add_options()
("nodeid,i", boost::program_options::value<uint32_t>(), "Node ID") ("qsfp,q", boost::program_options::value<uint32_t>(), "QSFP port")
("oper,w", boost::program_options::value<bool>(), "Read or Write") ("node,d", boost::program_options::value<uint32_t>(), "Node ID")
("size,s", boost::program_options::value<uint32_t>(), "Transfer size") ("tcpaddr,t", boost::program_options::value<string>(), "TCP conn IP")
("ipaddr,p", boost::program_options::value<string>(), "IP address") ("ibvaddr,i", boost::program_options::value<string>(), "IBV conn IP")
("port,t", boost::program_options::value<uint32_t>(), "Port number"); ("benchruns,b", boost::program_options::value<uint32_t>(), "Number of bench runs")
("reps,r", boost::program_options::value<uint32_t>(), "Number of repetitions within a run")
("mins,n", boost::program_options::value<uint32_t>(), "Minimum transfer size")
("maxs,x", boost::program_options::value<uint32_t>(), "Maximum transfer size")
("oper,w", boost::program_options::value<bool>(), "Read or Write");
boost::program_options::variables_map commandLineArgs; boost::program_options::variables_map commandLineArgs;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, programDescription), commandLineArgs); boost::program_options::store(boost::program_options::parse_command_line(argc, argv, programDescription), commandLineArgs);
boost::program_options::notify(commandLineArgs); boost::program_options::notify(commandLineArgs);
// Stat // Stat
uint32_t node_id = nIdMaster; uint32_t qsfp = defQsfp;
uint32_t node_id = defNodeId;
string tcp_mstr_ip = defTcpMstrIp;
string ibv_ip = defIbvIp;
uint32_t n_bench_runs = defNBenchRuns;
uint32_t n_reps = defNReps;
uint32_t min_size = defMinSize;
uint32_t max_size = defMaxSize;
bool oper = defOper; bool oper = defOper;
uint32_t n_reps = nReps;
uint32_t size = defSize;
string mstr_ip_addr = defMstrIp;
uint32_t port = defPort;
if(commandLineArgs.count("nodeid") > 0) node_id = commandLineArgs["nodeid"].as<uint32_t>(); if(commandLineArgs.count("qsfp") > 0) qsfp = commandLineArgs["qsfp"].as<uint32_t>();
if(commandLineArgs.count("node") > 0) node_id = commandLineArgs["node"].as<uint32_t>();
if(commandLineArgs.count("tcpaddr") > 0) tcp_mstr_ip = commandLineArgs["tcpaddr"].as<string>();
if(commandLineArgs.count("ibvaddr") > 0) ibv_ip = commandLineArgs["ibvaddr"].as<string>();
if(commandLineArgs.count("benchruns") > 0) n_bench_runs = commandLineArgs["benchruns"].as<uint32_t>();
if(commandLineArgs.count("reps") > 0) n_reps = commandLineArgs["reps"].as<uint32_t>();
if(commandLineArgs.count("mins") > 0) min_size = commandLineArgs["mins"].as<uint32_t>();
if(commandLineArgs.count("maxs") > 0) max_size = commandLineArgs["maxs"].as<uint32_t>();
if(commandLineArgs.count("oper") > 0) oper = commandLineArgs["oper"].as<bool>(); if(commandLineArgs.count("oper") > 0) oper = commandLineArgs["oper"].as<bool>();
if(commandLineArgs.count("size") > 0) size = commandLineArgs["size"].as<uint32_t>();
if(commandLineArgs.count("ipaddr") > 0) mstr_ip_addr = commandLineArgs["ipaddr"].as<string>();
if(commandLineArgs.count("port") > 0) port = commandLineArgs["port"].as<uint32_t>();
uint32_t n_pages = (size + hugePageSize - 1) / hugePageSize; uint32_t n_pages = (max_size + hugePageSize - 1) / hugePageSize;
bool mstr = node_id == nIdMaster; uint32_t size = min_size;
uint32_t ibv_ip_addr = baseIpAddress + node_id; bool mstr = (node_id == mstrNodeId);
PR_HEADER("PARAMS"); PR_HEADER("PARAMS");
std::cout << "Node ID: " << node_id << std::endl; std::cout << "Node ID: " << node_id << std::endl;
std::cout << "TCP master IP address: " << tcp_mstr_ip << std::endl;
std::cout << "IBV IP address: " << ibv_ip << std::endl;
std::cout << "Number of allocated pages: " << n_pages << std::endl; std::cout << "Number of allocated pages: " << n_pages << std::endl;
std::cout << (oper ? "Write operation" : "Read operation") << std::endl; std::cout << (oper ? "Write operation" : "Read operation") << std::endl;
std::cout << "Transfer size: " << size << std::endl; std::cout << "Min size: " << min_size << std::endl;
std::cout << "Master IP address: " << mstr_ip_addr << std::endl; std::cout << "Max size: " << max_size << std::endl;
std::cout << "Number of reps: " << n_reps << std::endl;
// Handles
cProc cproc(targetRegion, getpid());
cproc.changeIpAddress(ibv_ip_addr);
cproc.changeBoardNumber(node_id);
// Create queue pairs // Create queue pairs
ibvQpMap ictx; ibvQpMap ictx;
ictx.addQpair(qpId, &cproc, node_id, n_pages); ictx.addQpair(qpId, targetRegion, node_id, ibv_ip, n_pages);
mstr ? ictx.exchangeQpMaster(port) : ictx.exchangeQpSlave(mstr_ip_addr.c_str(), port); mstr ? ictx.exchangeQpMaster(port) : ictx.exchangeQpSlave(tcp_mstr_ip.c_str(), port);
ibvQpConn *iqp = ictx.getQpairConn(qpId); ibvQpConn *iqp = ictx.getQpairConn(qpId);
// Init app layer -------------------------------------------------------------------------------- // Init app layer --------------------------------------------------------------------------------
@ -105,9 +121,10 @@ int main(int argc, char *argv[])
wr.send_flags = IBV_LEG_SEP_MASK; wr.send_flags = IBV_LEG_SEP_MASK;
uint64_t *hMem = (uint64_t*)iqp->getQpairStruct()->local.vaddr; uint64_t *hMem = (uint64_t*)iqp->getQpairStruct()->local.vaddr;
iqp->ibvSync(mstr);
/*
PR_HEADER("RDMA BENCHMARK"); PR_HEADER("RDMA BENCHMARK");
while(sg.type.rdma.len <= maxSize) { while(sg.type.rdma.len <= max_size) {
// Setup // Setup
iqp->ibvClear(); iqp->ibvClear();
iqp->ibvSync(mstr); iqp->ibvSync(mstr);
@ -119,7 +136,7 @@ int main(int argc, char *argv[])
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Runs // Runs
// --------------------------------------------------------------- // ---------------------------------------------------------------
cBench bench(nBenchRuns); cBench bench(n_bench_runs);
uint32_t n_runs = 0; uint32_t n_runs = 0;
auto benchmark_thr = [&]() { auto benchmark_thr = [&]() {
@ -159,7 +176,7 @@ int main(int argc, char *argv[])
// Server // Server
if(oper) { if(oper) {
for(uint32_t n_runs = 1; n_runs <= nBenchRuns; n_runs++) { for(uint32_t n_runs = 1; n_runs <= n_bench_runs; n_runs++) {
bool k = false; bool k = false;
// Wait for incoming transactions // Wait for incoming transactions
@ -176,7 +193,7 @@ int main(int argc, char *argv[])
//std::cout << "\e[1mSyncing ...\e[0m" << std::endl; //std::cout << "\e[1mSyncing ...\e[0m" << std::endl;
iqp->ibvSync(mstr); iqp->ibvSync(mstr);
for(int n_runs = 1; n_runs <= nBenchRuns; n_runs++) { for(int n_runs = 1; n_runs <= n_bench_runs; n_runs++) {
// Wait for the incoming transaction and send back // Wait for the incoming transaction and send back
for(int i = 0; i < n_reps; i++) { for(int i = 0; i < n_reps; i++) {
@ -193,6 +210,7 @@ int main(int argc, char *argv[])
sg.type.rdma.len *= 2; sg.type.rdma.len *= 2;
} }
std::cout << std::endl; std::cout << std::endl;
*/
// Done // Done
if (mstr) { if (mstr) {

View File

@ -55,6 +55,12 @@ constexpr auto const hugePageShift = 21UL;
constexpr auto const useHugePages = true; constexpr auto const useHugePages = true;
constexpr auto const clocNs = 4; constexpr auto const clocNs = 4;
/* Bits */
constexpr auto const pidBits = 6;
constexpr auto const pidMask = 0x3f;
constexpr auto const nRegBits = 4;
constexpr auto const nRegMask = 0xf;
/* FIFOs */ /* FIFOs */
constexpr auto const cmdFifoDepth = 32; constexpr auto const cmdFifoDepth = 32;
constexpr auto const cmdFifoThr = 10; constexpr auto const cmdFifoThr = 10;
@ -88,9 +94,6 @@ constexpr auto const axiDataWidth = 64;
/* Net regs */ /* Net regs */
constexpr auto const nNetRegs = 9; constexpr auto const nNetRegs = 9;
/* Def BASE_IP_ADDRESS */
constexpr auto const baseIpAddress = 0x0A'01'D4'97;
/* QSFP regs offset */ /* QSFP regs offset */
constexpr auto const qsfpOffsAvx = 4; constexpr auto const qsfpOffsAvx = 4;
constexpr auto const qsfpOffsLeg = 11; constexpr auto const qsfpOffsLeg = 11;
@ -118,6 +121,9 @@ constexpr auto const immedLowParams = 3;
constexpr auto const immedMedParams = 7; constexpr auto const immedMedParams = 7;
constexpr auto const immedHighParams = 8; constexpr auto const immedHighParams = 8;
/* ARP sleep */
constexpr auto const arpSleepTime = 100;
enum class CoyoteOper { enum class CoyoteOper {
NOOP = 0, NOOP = 0,
READ = 1, READ = 1,

View File

@ -116,6 +116,10 @@ protected:
uint32_t wr_cmd_cnt = { 0 }; uint32_t wr_cmd_cnt = { 0 };
uint32_t rdma_cmd_cnt = { 0 }; uint32_t rdma_cmd_cnt = { 0 };
/* QSFP port */
uint32_t qsfp = { 0 };
uint32_t qsfp_offs = { 0 };
/* Mmapped regions */ /* Mmapped regions */
#ifdef EN_AVX #ifdef EN_AVX
volatile __m256i *cnfg_reg_avx = { 0 }; volatile __m256i *cnfg_reg_avx = { 0 };
@ -146,7 +150,6 @@ protected:
/* Post to controller */ /* Post to controller */
void postCmd(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t offs_0, int32_t send_flags = 0); void postCmd(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t offs_0, int32_t send_flags = 0);
void postPrep(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t offs_0, uint8_t offs_reg = 0); void postPrep(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t offs_0, uint8_t offs_reg = 0);
void postGo();
uint32_t last_qp = { 0 }; uint32_t last_qp = { 0 };
public: public:
@ -229,23 +232,6 @@ public:
void removeBitstream(int32_t oid); void removeBitstream(int32_t oid);
auto isReconfigurable() const { return fcnfg.en_pr; } auto isReconfigurable() const { return fcnfg.en_pr; }
/**
* @brief Initiate an ibv command
*
* @param qp : queue pair struct
* @param wr : rdma operation context struct
*/
void ibvPostSend(ibvQp *qp, ibvSendWr *wr);
void ibvPostGo(ibvQp *qp);
/**
* @brief Write the queue pair context
*
* @param qp : queue pair struct
*/
void writeQpContext(ibvQp *qp);
void writeConnContext(ibvQp *qp, uint32_t port);
/** /**
* @brief Change the IP address and board numbers * @brief Change the IP address and board numbers
* *
@ -257,7 +243,23 @@ public:
* @brief Perform an arp lookup * @brief Perform an arp lookup
* *
*/ */
void doArpLookup(); void doArpLookup(uint32_t ip_addr);
/**
* @brief Write the queue pair context
*
* @param qp : queue pair struct
*/
void writeQpContext(ibvQp *qp);
void writeConnContext(ibvQp *qp, uint32_t port);
/**
* @brief Initiate an ibv command
*
* @param qp : queue pair struct
* @param wr : rdma operation context struct
*/
void ibvPostSend(ibvQp *qp, ibvSendWr *wr);
/** /**
* @brief Debug * @brief Debug

View File

@ -23,24 +23,20 @@ class ibvQpConn {
std::unique_ptr<ibvQp> qpair; std::unique_ptr<ibvQp> qpair;
/* vFPGA */ /* vFPGA */
cProc *fdev; std::unique_ptr<cProc> fdev;
/* Buffer pages */
uint32_t n_pages;
/* Connection */ /* Connection */
int connection = { 0 }; int connection = { 0 };
bool is_connected; bool is_connected;
/* Buffer pages */
uint32_t n_pages;
/* Static */
static const uint32_t base_ib_addr = { baseIpAddress };
/* Init */ /* Init */
void initLocalQueue(uint32_t node_id); void initLocalQueue(uint32_t node_id, string ip_addr);
public: public:
ibvQpConn(int32_t vfid, uint32_t node_id, string ip_addr, uint32_t n_pages);
ibvQpConn(cProc *fdev, uint32_t node_id, uint32_t n_pages);
~ibvQpConn(); ~ibvQpConn();
// Connection // Connection
@ -49,12 +45,15 @@ public:
void closeConnection(); void closeConnection();
// Qpair // Qpair
inline auto getQpairStruct() { return qpair.get(); }; inline auto getQpairStruct() { return qpair.get(); }
inline auto getCProc() { return fdev.get(); }
void writeContext(uint16_t port); void writeContext(uint16_t port);
// ARP
inline auto doArpLookup() { fdev->doArpLookup(qpair->remote.ip_addr); }
// RDMA ops // RDMA ops
void ibvPostSend(ibvSendWr *wr); void ibvPostSend(ibvSendWr *wr);
void ibvPostGo();
// Poll // Poll
uint32_t ibvDone(); uint32_t ibvDone();

View File

@ -28,7 +28,7 @@ public:
~ibvQpMap() {} ~ibvQpMap() {}
// Qpair mgmt // Qpair mgmt
void addQpair(uint32_t qpid, cProc *fdev, uint32_t node_id, uint32_t n_pages); void addQpair(uint32_t qpid, int32_t vfid, uint32_t node_id, string ip_addr, uint32_t n_pages);
void removeQpair(uint32_t qpid); void removeQpair(uint32_t qpid);
ibvQpConn* getQpairConn(uint32_t qpid); ibvQpConn* getQpairConn(uint32_t qpid);

View File

@ -17,7 +17,7 @@ namespace fpga {
struct ibvQ { struct ibvQ {
// Node // Node
uint32_t node_id; uint32_t node_id;
uint32_t vfid; uint32_t ip_addr;
// Queue // Queue
uint32_t qpn; uint32_t qpn;

View File

@ -594,7 +594,7 @@ void cProc::removeBitstream(int32_t oid) {
*/ */
void cProc::ibvPostSend(ibvQp *qp, ibvSendWr *wr) { void cProc::ibvPostSend(ibvQp *qp, ibvSendWr *wr) {
if(fcnfg.en_rdma) { if(fcnfg.en_rdma) {
if(qp->local.node_id == qp->remote.node_id) { if(qp->local.ip_addr == qp->remote.ip_addr) {
for(int i = 0; i < wr->num_sge; i++) { for(int i = 0; i < wr->num_sge; i++) {
void *local_addr = (void*)(qp->local.vaddr + wr->sg_list[i].type.rdma.local_offs); void *local_addr = (void*)(qp->local.vaddr + wr->sg_list[i].type.rdma.local_offs);
void *remote_addr = (void*)(qp->remote.vaddr + wr->sg_list[i].type.rdma.remote_offs); void *remote_addr = (void*)(qp->remote.vaddr + wr->sg_list[i].type.rdma.remote_offs);
@ -664,12 +664,6 @@ void cProc::postPrep(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t
#endif #endif
} }
void cProc::ibvPostGo(ibvQp *qp) {
if(last_qp == qp->getId()) {
postGo();
}
}
/** /**
* Post command * Post command
*/ */
@ -702,12 +696,11 @@ void cProc::postCmd(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t
cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG_1) + fcnfg.qsfp_offs] = offs_1; cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG_1) + fcnfg.qsfp_offs] = offs_1;
cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG_2) + fcnfg.qsfp_offs] = offs_2; cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG_2) + fcnfg.qsfp_offs] = offs_2;
cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG_3) + fcnfg.qsfp_offs] = offs_3; cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG_3) + fcnfg.qsfp_offs] = offs_3;
if((send_flags >> IBV_LEG_SEP_SHFT) & IBV_LEG_SEP_MASK != 0x1) { cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG) + fcnfg.qsfp_offs] = 0x1;
cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG) + fcnfg.qsfp_offs] = 0x1;
// Inc
rdma_cmd_cnt++;
// Inc
rdma_cmd_cnt++;
}
#ifdef EN_AVX #ifdef EN_AVX
} }
#endif #endif
@ -716,27 +709,6 @@ void cProc::postCmd(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t
dlock.unlock(); dlock.unlock();
} }
void cProc::postGo() {
// Lock
dlock.lock();
// Check outstanding
while (rdma_cmd_cnt > (cmd_fifo_depth - cmd_fifo_thr)) {
rdma_cmd_cnt = cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_STAT_CMD_USED_REG) + fcnfg.qsfp_offs];
if (rdma_cmd_cnt > (cmd_fifo_depth - cmd_fifo_thr))
nanosleep((const struct timespec[]){{0, 100L}}, NULL);
}
// Fire the request
cnfg_reg[static_cast<uint32_t>(CnfgLegRegs::RDMA_POST_REG) + fcnfg.qsfp_offs] = 0x1;
// Inc
rdma_cmd_cnt++;
// Unlock
dlock.unlock();
}
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
// Network management // Network management
// ------------------------------------------------------------------------------- // -------------------------------------------------------------------------------
@ -744,11 +716,15 @@ void cProc::postGo() {
/** /**
* Arp lookup * Arp lookup
*/ */
void cProc::doArpLookup() { void cProc::doArpLookup(uint32_t ip_addr) {
uint64_t tmp = fcnfg.qsfp; uint64_t tmp[2];
tmp[0] = fcnfg.qsfp;
tmp[1] = ip_addr;
if(ioctl(fd, IOCTL_ARP_LOOKUP, &tmp)) if(ioctl(fd, IOCTL_ARP_LOOKUP, &tmp))
throw std::runtime_error("ioctl_arp_lookup failed"); throw std::runtime_error("ioctl_arp_lookup failed");
usleep(arpSleepTime);
} }
/** /**

View File

@ -30,18 +30,15 @@ namespace fpga {
* @param: node_id - current node ID * @param: node_id - current node ID
* @param: n_pages - number of buffer pages * @param: n_pages - number of buffer pages
*/ */
ibvQpConn::ibvQpConn(cProc *fdev, uint32_t node_id, uint32_t n_pages) { ibvQpConn::ibvQpConn(int32_t vfid, uint32_t node_id, string ip_addr, uint32_t n_pages) {
this->fdev = fdev; this->fdev = make_unique<cProc>(vfid, getpid());
this->n_pages = n_pages; this->n_pages = n_pages;
// Conn // Conn
is_connected = false; is_connected = false;
// Initialize local queues // Initialize local queues
initLocalQueue(node_id); initLocalQueue(node_id, ip_addr);
// ARP lookup
fdev->doArpLookup();
} }
/** /**
@ -49,33 +46,57 @@ ibvQpConn::ibvQpConn(cProc *fdev, uint32_t node_id, uint32_t n_pages) {
*/ */
ibvQpConn::~ibvQpConn() { ibvQpConn::~ibvQpConn() {
closeConnection(); closeConnection();
fdev->freeMem((void*) qpair->local.vaddr);
} }
static unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); static unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
uint32_t convert( const std::string& ipv4Str ) {
std::istringstream iss( ipv4Str );
uint32_t ipv4 = 0;
for( uint32_t i = 0; i < 4; ++i ) {
uint32_t part;
iss >> part;
if ( iss.fail() || part > 255 )
throw std::runtime_error( "Invalid IP address - Expected [0, 255]" );
// LSHIFT and OR all parts together with the first part as the MSB
ipv4 |= part << ( 8 * ( 3 - i ) );
// Check for delimiter except on last iteration
if ( i != 3 ) {
char delimiter;
iss >> delimiter;
if ( iss.fail() || delimiter != '.' )
throw std::runtime_error( "Invalid IP address - Expected '.' delimiter" );
}
}
return ipv4;
}
/** /**
* Initialization of the local queues * Initialization of the local queues
*/ */
void ibvQpConn::initLocalQueue(uint32_t node_id) { void ibvQpConn::initLocalQueue(uint32_t node_id, string ip_addr) {
std::default_random_engine rand_gen(seed); std::default_random_engine rand_gen(seed);
std::uniform_int_distribution<int> distr(0, std::numeric_limits<std::uint32_t>::max()); std::uniform_int_distribution<int> distr(0, std::numeric_limits<std::uint32_t>::max());
uint32_t ib_addr = base_ib_addr + node_id;
qpair = std::make_unique<ibvQp>(); qpair = std::make_unique<ibvQp>();
// IP // IP
qpair->local.uintToGid(0, ib_addr); uint32_t ibv_ip_addr = convert(ip_addr);
qpair->local.uintToGid(8, ib_addr); qpair->local.node_id = node_id;
qpair->local.uintToGid(16, ib_addr); qpair->local.ip_addr = ibv_ip_addr;
qpair->local.uintToGid(24, ib_addr); qpair->local.uintToGid(0, ibv_ip_addr);
qpair->local.uintToGid(8, ibv_ip_addr);
qpair->local.uintToGid(16, ibv_ip_addr);
qpair->local.uintToGid(24, ibv_ip_addr);
// qpn and psn // qpn and psn
qpair->local.node_id = node_id; qpair->local.qpn = ((fdev->getVfid() & nRegMask) << pidBits) || (fdev->getCpid() & pidMask);
qpair->local.vfid = fdev->getVfid();
qpair->local.qpn = fdev->getCpid();
if(qpair->local.qpn == -1) if(qpair->local.qpn == -1)
throw std::runtime_error("Coyote PID incorrect, vfid: " + fdev->getVfid()); throw std::runtime_error("Coyote PID incorrect, vfid: " + fdev->getVfid());
qpair->local.psn = distr(rand_gen) & 0xFFFFFF; qpair->local.psn = distr(rand_gen) & 0xFFFFFF;
@ -85,6 +106,10 @@ void ibvQpConn::initLocalQueue(uint32_t node_id) {
void *vaddr = fdev->getMem({CoyoteAlloc::HOST_2M, n_pages}); void *vaddr = fdev->getMem({CoyoteAlloc::HOST_2M, n_pages});
qpair->local.vaddr = (uint64_t) vaddr; qpair->local.vaddr = (uint64_t) vaddr;
qpair->local.size = n_pages * hugePageSize; qpair->local.size = n_pages * hugePageSize;
// Set ip
fdev->changeIpAddress(ibv_ip_addr);
fdev->changeBoardNumber(node_id);
} }
/** /**
@ -121,13 +146,6 @@ void ibvQpConn::ibvPostSend(ibvSendWr *wr) {
fdev->ibvPostSend(qpair.get(), wr); fdev->ibvPostSend(qpair.get(), wr);
} }
void ibvQpConn::ibvPostGo() {
if(!is_connected)
throw std::runtime_error("Queue pair not connected\n");
fdev->ibvPostGo(qpair.get());
}
/** /**
* RDMA polling function for incoming data * RDMA polling function for incoming data
*/ */

View File

@ -23,11 +23,11 @@ constexpr auto const recvBuffSize = 1024;
namespace fpga { namespace fpga {
void ibvQpMap::addQpair(uint32_t qpid, cProc *fdev, uint32_t node_id, uint32_t n_pages) { void ibvQpMap::addQpair(uint32_t qpid, int32_t vfid, uint32_t node_id, string ip_addr, uint32_t n_pages) {
if(qpairs.find(qpid) != qpairs.end()) if(qpairs.find(qpid) != qpairs.end())
throw std::runtime_error("Queue pair already exists"); throw std::runtime_error("Queue pair already exists");
auto qpair = std::make_unique<ibvQpConn>(fdev, node_id, n_pages); auto qpair = std::make_unique<ibvQpConn>(vfid, node_id, ip_addr, n_pages);
qpairs.emplace(qpid, std::move(qpair)); qpairs.emplace(qpid, std::move(qpair));
DBG1("Queue pair created, qpid: " << qpid); DBG1("Queue pair created, qpid: " << qpid);
} }
@ -127,6 +127,9 @@ void ibvQpMap::exchangeQpMaster(uint16_t port) {
// Write context and connection // Write context and connection
ibv_qpair_conn->writeContext(port); ibv_qpair_conn->writeContext(port);
// ARP lookup
ibv_qpair_conn->doArpLookup();
} }
} }
@ -207,6 +210,9 @@ void ibvQpMap::exchangeQpSlave(const char *trgt_addr, uint16_t port) {
// Write context and connection // Write context and connection
curr_qp_conn->writeContext(port); curr_qp_conn->writeContext(port);
// ARP lookup
curr_qp_conn->doArpLookup();
if (res) if (res)
freeaddrinfo(res); freeaddrinfo(res);
free(service); free(service);

View File

@ -29,8 +29,8 @@ void ibvQ::uintToGid(int idx, uint32_t ip_addr) {
} }
void ibvQ::print(const char *name) { void ibvQ::print(const char *name) {
printf("%s: VFID 0x%02x, PID 0x%04x, PSN 0x%06x, GID %s, VADDR %016lx, SIZE %08x\n", printf("%s: ID 0x%02x, QPN 0x%06x, PSN 0x%06x, VADDR %016lx, SIZE %08x, IP 0x%08x, GID 0x%s,\n",
name, vfid, qpn & 0x3f, psn, gid, vaddr, size); name, node_id, qpn, psn, vaddr, size, ip_addr, gid);
} }
ibvQpPool::ibvQpPool(int32_t n_el) { ibvQpPool::ibvQpPool(int32_t n_el) {