updated arp.
This commit is contained in:
parent
48e4f41291
commit
b6632216b3
|
@ -158,12 +158,6 @@ extern int cyt_arch;
|
|||
#define POLL_TIMEOUT_SECONDS 10
|
||||
#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) */
|
||||
#define IO_PHYS_ADDR 0x900000000000UL
|
||||
|
||||
|
@ -670,6 +664,10 @@ struct bus_drvdata {
|
|||
int en_tcp_1;
|
||||
int en_net_0;
|
||||
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;
|
||||
struct fpga_dev *fpga_dev;
|
||||
|
||||
|
|
|
@ -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_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
|
||||
d->fpga_stat_cnfg->lspeed_cnfg = EN_LOWSPEED;
|
||||
}
|
||||
|
|
|
@ -282,19 +282,15 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
// arp lookup
|
||||
case IOCTL_ARP_LOOKUP:
|
||||
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) {
|
||||
pr_info("user data could not be coppied, return %d\n", ret_val);
|
||||
} else {
|
||||
dbg_info("arp lookup ...");
|
||||
dbg_info("arp lookup qsfp%llx, target ip %08llx", tmp[0], tmp[1]);
|
||||
spin_lock(&pd->stat_lock);
|
||||
|
||||
for (i = 0; i < N_TOTAL_NODES; i++) {
|
||||
if (i == NODE_ID)
|
||||
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);
|
||||
}
|
||||
|
||||
tmp[0] ? (pd->fpga_stat_cnfg->net_1_arp = tmp[1]) :
|
||||
(pd->fpga_stat_cnfg->net_0_arp = tmp[1]);
|
||||
|
||||
spin_unlock(&pd->stat_lock);
|
||||
}
|
||||
|
@ -314,12 +310,23 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
else {
|
||||
spin_lock(&pd->stat_lock);
|
||||
|
||||
// Set ip
|
||||
tmp[0] ? (pd->fpga_stat_cnfg->net_1_ip = tmp[1]) :
|
||||
(pd->fpga_stat_cnfg->net_0_ip = tmp[1]);
|
||||
// ip change
|
||||
if(tmp[0]) {
|
||||
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);
|
||||
dbg_info("ip address changed to %llx\n", tmp[1]);
|
||||
|
||||
}
|
||||
} else {
|
||||
pr_info("network not enabled\n");
|
||||
|
@ -337,12 +344,22 @@ long fpga_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
} else {
|
||||
spin_lock(&pd->stat_lock);
|
||||
|
||||
// Set board number
|
||||
tmp[0] ? (pd->fpga_stat_cnfg->net_1_boardnum = tmp[1]) :
|
||||
(pd->fpga_stat_cnfg->net_0_boardnum = tmp[1]);
|
||||
// board number change
|
||||
if(tmp[0]) {
|
||||
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);
|
||||
dbg_info("board number changed to %llx\n", tmp[1]);
|
||||
}
|
||||
} else {
|
||||
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_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);
|
||||
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));
|
||||
break;
|
||||
|
||||
|
|
|
@ -22,17 +22,24 @@ using namespace std;
|
|||
using namespace std::chrono;
|
||||
using namespace fpga;
|
||||
|
||||
/* Runtime */
|
||||
constexpr auto const nIdMaster = 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;
|
||||
/* Params */
|
||||
constexpr auto const mstrNodeId = 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 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[])
|
||||
{
|
||||
|
@ -43,50 +50,59 @@ int main(int argc, char *argv[])
|
|||
// Read arguments
|
||||
boost::program_options::options_description programDescription("Options:");
|
||||
programDescription.add_options()
|
||||
("nodeid,i", boost::program_options::value<uint32_t>(), "Node ID")
|
||||
("oper,w", boost::program_options::value<bool>(), "Read or Write")
|
||||
("size,s", boost::program_options::value<uint32_t>(), "Transfer size")
|
||||
("ipaddr,p", boost::program_options::value<string>(), "IP address")
|
||||
("port,t", boost::program_options::value<uint32_t>(), "Port number");
|
||||
("qsfp,q", boost::program_options::value<uint32_t>(), "QSFP port")
|
||||
("node,d", boost::program_options::value<uint32_t>(), "Node ID")
|
||||
("tcpaddr,t", boost::program_options::value<string>(), "TCP conn IP")
|
||||
("ibvaddr,i", boost::program_options::value<string>(), "IBV conn IP")
|
||||
("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::store(boost::program_options::parse_command_line(argc, argv, programDescription), commandLineArgs);
|
||||
boost::program_options::notify(commandLineArgs);
|
||||
|
||||
// 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;
|
||||
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("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;
|
||||
bool mstr = node_id == nIdMaster;
|
||||
uint32_t ibv_ip_addr = baseIpAddress + node_id;
|
||||
uint32_t n_pages = (max_size + hugePageSize - 1) / hugePageSize;
|
||||
uint32_t size = min_size;
|
||||
bool mstr = (node_id == mstrNodeId);
|
||||
|
||||
PR_HEADER("PARAMS");
|
||||
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 << (oper ? "Write operation" : "Read operation") << std::endl;
|
||||
std::cout << "Transfer size: " << size << std::endl;
|
||||
std::cout << "Master IP address: " << mstr_ip_addr << std::endl;
|
||||
|
||||
// Handles
|
||||
cProc cproc(targetRegion, getpid());
|
||||
cproc.changeIpAddress(ibv_ip_addr);
|
||||
cproc.changeBoardNumber(node_id);
|
||||
std::cout << "Min size: " << min_size << std::endl;
|
||||
std::cout << "Max size: " << max_size << std::endl;
|
||||
std::cout << "Number of reps: " << n_reps << std::endl;
|
||||
|
||||
// Create queue pairs
|
||||
ibvQpMap ictx;
|
||||
ictx.addQpair(qpId, &cproc, node_id, n_pages);
|
||||
mstr ? ictx.exchangeQpMaster(port) : ictx.exchangeQpSlave(mstr_ip_addr.c_str(), port);
|
||||
ictx.addQpair(qpId, targetRegion, node_id, ibv_ip, n_pages);
|
||||
mstr ? ictx.exchangeQpMaster(port) : ictx.exchangeQpSlave(tcp_mstr_ip.c_str(), port);
|
||||
ibvQpConn *iqp = ictx.getQpairConn(qpId);
|
||||
|
||||
// Init app layer --------------------------------------------------------------------------------
|
||||
|
@ -105,9 +121,10 @@ int main(int argc, char *argv[])
|
|||
wr.send_flags = IBV_LEG_SEP_MASK;
|
||||
|
||||
uint64_t *hMem = (uint64_t*)iqp->getQpairStruct()->local.vaddr;
|
||||
|
||||
iqp->ibvSync(mstr);
|
||||
/*
|
||||
PR_HEADER("RDMA BENCHMARK");
|
||||
while(sg.type.rdma.len <= maxSize) {
|
||||
while(sg.type.rdma.len <= max_size) {
|
||||
// Setup
|
||||
iqp->ibvClear();
|
||||
iqp->ibvSync(mstr);
|
||||
|
@ -119,7 +136,7 @@ int main(int argc, char *argv[])
|
|||
// ---------------------------------------------------------------
|
||||
// Runs
|
||||
// ---------------------------------------------------------------
|
||||
cBench bench(nBenchRuns);
|
||||
cBench bench(n_bench_runs);
|
||||
uint32_t n_runs = 0;
|
||||
|
||||
auto benchmark_thr = [&]() {
|
||||
|
@ -159,7 +176,7 @@ int main(int argc, char *argv[])
|
|||
// Server
|
||||
|
||||
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;
|
||||
|
||||
// Wait for incoming transactions
|
||||
|
@ -176,7 +193,7 @@ int main(int argc, char *argv[])
|
|||
//std::cout << "\e[1mSyncing ...\e[0m" << std::endl;
|
||||
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
|
||||
for(int i = 0; i < n_reps; i++) {
|
||||
|
@ -193,6 +210,7 @@ int main(int argc, char *argv[])
|
|||
sg.type.rdma.len *= 2;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
*/
|
||||
|
||||
// Done
|
||||
if (mstr) {
|
||||
|
|
|
@ -55,6 +55,12 @@ constexpr auto const hugePageShift = 21UL;
|
|||
constexpr auto const useHugePages = true;
|
||||
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 */
|
||||
constexpr auto const cmdFifoDepth = 32;
|
||||
constexpr auto const cmdFifoThr = 10;
|
||||
|
@ -88,9 +94,6 @@ constexpr auto const axiDataWidth = 64;
|
|||
/* Net regs */
|
||||
constexpr auto const nNetRegs = 9;
|
||||
|
||||
/* Def BASE_IP_ADDRESS */
|
||||
constexpr auto const baseIpAddress = 0x0A'01'D4'97;
|
||||
|
||||
/* QSFP regs offset */
|
||||
constexpr auto const qsfpOffsAvx = 4;
|
||||
constexpr auto const qsfpOffsLeg = 11;
|
||||
|
@ -118,6 +121,9 @@ constexpr auto const immedLowParams = 3;
|
|||
constexpr auto const immedMedParams = 7;
|
||||
constexpr auto const immedHighParams = 8;
|
||||
|
||||
/* ARP sleep */
|
||||
constexpr auto const arpSleepTime = 100;
|
||||
|
||||
enum class CoyoteOper {
|
||||
NOOP = 0,
|
||||
READ = 1,
|
||||
|
|
|
@ -116,6 +116,10 @@ protected:
|
|||
uint32_t wr_cmd_cnt = { 0 };
|
||||
uint32_t rdma_cmd_cnt = { 0 };
|
||||
|
||||
/* QSFP port */
|
||||
uint32_t qsfp = { 0 };
|
||||
uint32_t qsfp_offs = { 0 };
|
||||
|
||||
/* Mmapped regions */
|
||||
#ifdef EN_AVX
|
||||
volatile __m256i *cnfg_reg_avx = { 0 };
|
||||
|
@ -146,7 +150,6 @@ protected:
|
|||
/* 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 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 };
|
||||
|
||||
public:
|
||||
|
@ -229,23 +232,6 @@ public:
|
|||
void removeBitstream(int32_t oid);
|
||||
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
|
||||
*
|
||||
|
@ -257,8 +243,24 @@ public:
|
|||
* @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
|
||||
*
|
||||
|
|
|
@ -23,24 +23,20 @@ class ibvQpConn {
|
|||
std::unique_ptr<ibvQp> qpair;
|
||||
|
||||
/* vFPGA */
|
||||
cProc *fdev;
|
||||
std::unique_ptr<cProc> fdev;
|
||||
|
||||
/* Buffer pages */
|
||||
uint32_t n_pages;
|
||||
|
||||
/* Connection */
|
||||
int connection = { 0 };
|
||||
bool is_connected;
|
||||
|
||||
/* Buffer pages */
|
||||
uint32_t n_pages;
|
||||
|
||||
/* Static */
|
||||
static const uint32_t base_ib_addr = { baseIpAddress };
|
||||
|
||||
/* Init */
|
||||
void initLocalQueue(uint32_t node_id);
|
||||
void initLocalQueue(uint32_t node_id, string ip_addr);
|
||||
|
||||
public:
|
||||
|
||||
ibvQpConn(cProc *fdev, uint32_t node_id, uint32_t n_pages);
|
||||
ibvQpConn(int32_t vfid, uint32_t node_id, string ip_addr, uint32_t n_pages);
|
||||
~ibvQpConn();
|
||||
|
||||
// Connection
|
||||
|
@ -49,12 +45,15 @@ public:
|
|||
void closeConnection();
|
||||
|
||||
// Qpair
|
||||
inline auto getQpairStruct() { return qpair.get(); };
|
||||
inline auto getQpairStruct() { return qpair.get(); }
|
||||
inline auto getCProc() { return fdev.get(); }
|
||||
void writeContext(uint16_t port);
|
||||
|
||||
// ARP
|
||||
inline auto doArpLookup() { fdev->doArpLookup(qpair->remote.ip_addr); }
|
||||
|
||||
// RDMA ops
|
||||
void ibvPostSend(ibvSendWr *wr);
|
||||
void ibvPostGo();
|
||||
|
||||
// Poll
|
||||
uint32_t ibvDone();
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
~ibvQpMap() {}
|
||||
|
||||
// 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);
|
||||
ibvQpConn* getQpairConn(uint32_t qpid);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace fpga {
|
|||
struct ibvQ {
|
||||
// Node
|
||||
uint32_t node_id;
|
||||
uint32_t vfid;
|
||||
uint32_t ip_addr;
|
||||
|
||||
// Queue
|
||||
uint32_t qpn;
|
||||
|
|
|
@ -594,7 +594,7 @@ void cProc::removeBitstream(int32_t oid) {
|
|||
*/
|
||||
void cProc::ibvPostSend(ibvQp *qp, ibvSendWr *wr) {
|
||||
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++) {
|
||||
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);
|
||||
|
@ -664,12 +664,6 @@ void cProc::postPrep(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t
|
|||
#endif
|
||||
}
|
||||
|
||||
void cProc::ibvPostGo(ibvQp *qp) {
|
||||
if(last_qp == qp->getId()) {
|
||||
postGo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_2) + fcnfg.qsfp_offs] = offs_2;
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -716,27 +709,6 @@ void cProc::postCmd(uint64_t offs_3, uint64_t offs_2, uint64_t offs_1, uint64_t
|
|||
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
|
||||
// -------------------------------------------------------------------------------
|
||||
|
@ -744,11 +716,15 @@ void cProc::postGo() {
|
|||
/**
|
||||
* Arp lookup
|
||||
*/
|
||||
void cProc::doArpLookup() {
|
||||
uint64_t tmp = fcnfg.qsfp;
|
||||
void cProc::doArpLookup(uint32_t ip_addr) {
|
||||
uint64_t tmp[2];
|
||||
tmp[0] = fcnfg.qsfp;
|
||||
tmp[1] = ip_addr;
|
||||
|
||||
if(ioctl(fd, IOCTL_ARP_LOOKUP, &tmp))
|
||||
throw std::runtime_error("ioctl_arp_lookup failed");
|
||||
|
||||
usleep(arpSleepTime);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,18 +30,15 @@ namespace fpga {
|
|||
* @param: node_id - current node ID
|
||||
* @param: n_pages - number of buffer pages
|
||||
*/
|
||||
ibvQpConn::ibvQpConn(cProc *fdev, uint32_t node_id, uint32_t n_pages) {
|
||||
this->fdev = fdev;
|
||||
ibvQpConn::ibvQpConn(int32_t vfid, uint32_t node_id, string ip_addr, uint32_t n_pages) {
|
||||
this->fdev = make_unique<cProc>(vfid, getpid());
|
||||
this->n_pages = n_pages;
|
||||
|
||||
// Conn
|
||||
is_connected = false;
|
||||
|
||||
// Initialize local queues
|
||||
initLocalQueue(node_id);
|
||||
|
||||
// ARP lookup
|
||||
fdev->doArpLookup();
|
||||
initLocalQueue(node_id, ip_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,33 +46,57 @@ ibvQpConn::ibvQpConn(cProc *fdev, uint32_t node_id, uint32_t n_pages) {
|
|||
*/
|
||||
ibvQpConn::~ibvQpConn() {
|
||||
closeConnection();
|
||||
fdev->freeMem((void*) qpair->local.vaddr);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
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::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>();
|
||||
|
||||
// IP
|
||||
qpair->local.uintToGid(0, ib_addr);
|
||||
qpair->local.uintToGid(8, ib_addr);
|
||||
qpair->local.uintToGid(16, ib_addr);
|
||||
qpair->local.uintToGid(24, ib_addr);
|
||||
uint32_t ibv_ip_addr = convert(ip_addr);
|
||||
qpair->local.node_id = node_id;
|
||||
qpair->local.ip_addr = ibv_ip_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
|
||||
qpair->local.node_id = node_id;
|
||||
qpair->local.vfid = fdev->getVfid();
|
||||
qpair->local.qpn = fdev->getCpid();
|
||||
qpair->local.qpn = ((fdev->getVfid() & nRegMask) << pidBits) || (fdev->getCpid() & pidMask);
|
||||
if(qpair->local.qpn == -1)
|
||||
throw std::runtime_error("Coyote PID incorrect, vfid: " + fdev->getVfid());
|
||||
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});
|
||||
qpair->local.vaddr = (uint64_t) vaddr;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -23,11 +23,11 @@ constexpr auto const recvBuffSize = 1024;
|
|||
|
||||
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())
|
||||
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));
|
||||
DBG1("Queue pair created, qpid: " << qpid);
|
||||
}
|
||||
|
@ -127,6 +127,9 @@ void ibvQpMap::exchangeQpMaster(uint16_t port) {
|
|||
|
||||
// Write context and connection
|
||||
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
|
||||
curr_qp_conn->writeContext(port);
|
||||
|
||||
// ARP lookup
|
||||
curr_qp_conn->doArpLookup();
|
||||
|
||||
if (res)
|
||||
freeaddrinfo(res);
|
||||
free(service);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <netdb.h>
|
||||
|
||||
namespace fpga {
|
||||
|
||||
|
||||
uint32_t ibvQ::gidToUint(int idx) {
|
||||
if(idx > 24) {
|
||||
std::cerr << "Invalid index for gidToUint" << std::endl;
|
||||
|
@ -29,8 +29,8 @@ void ibvQ::uintToGid(int idx, uint32_t ip_addr) {
|
|||
}
|
||||
|
||||
void ibvQ::print(const char *name) {
|
||||
printf("%s: VFID 0x%02x, PID 0x%04x, PSN 0x%06x, GID %s, VADDR %016lx, SIZE %08x\n",
|
||||
name, vfid, qpn & 0x3f, psn, gid, vaddr, size);
|
||||
printf("%s: ID 0x%02x, QPN 0x%06x, PSN 0x%06x, VADDR %016lx, SIZE %08x, IP 0x%08x, GID 0x%s,\n",
|
||||
name, node_id, qpn, psn, vaddr, size, ip_addr, gid);
|
||||
}
|
||||
|
||||
ibvQpPool::ibvQpPool(int32_t n_el) {
|
||||
|
|
Loading…
Reference in New Issue