Skip to content

Commit 9e13d57

Browse files
authored
mpd udev support (#2780)
1 parent 89233c0 commit 9e13d57

File tree

17 files changed

+539
-209
lines changed

17 files changed

+539
-209
lines changed

src/CMake/cpack.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ if (${LINUX_FLAVOR} MATCHES "^(Ubuntu|Debian|pynqlinux)")
4545
# aws component dependencies
4646
SET(CPACK_DEBIAN_AWS_PACKAGE_DEPENDS "xrt (>= ${XRT_VERSION_MAJOR}.${XRT_VERSION_MINOR}.${XRT_VERSION_PATCH})")
4747
# xrt component dependencies
48-
SET(CPACK_DEBIAN_XRT_PACKAGE_DEPENDS "ocl-icd-opencl-dev (>= 2.2.0), libboost-dev (>= ${Boost_VER_STR}), libboost-dev (<< ${Boost_VER_STR_ONEGREATER}), libboost-filesystem-dev (>=${Boost_VER_STR}), libboost-filesystem-dev (<<${Boost_VER_STR_ONEGREATER}), uuid-dev (>= 2.27.1), dkms (>= 2.2.0), libprotoc-dev (>=2.6.1), libssl-dev (>=1.0.2), protobuf-compiler (>=2.6.1), libncurses5-dev (>=6.0), lsb-release, libxml2-dev (>=2.9.1), libyaml-dev (>= 0.1.6), libc6 (>= ${GLIBC_VERSION}), libc6 (<< ${GLIBC_VERSION_ONEGREATER}), python (>= 2.7), python-pip ")
48+
SET(CPACK_DEBIAN_XRT_PACKAGE_DEPENDS "ocl-icd-opencl-dev (>= 2.2.0), libboost-dev (>= ${Boost_VER_STR}), libboost-dev (<< ${Boost_VER_STR_ONEGREATER}), libboost-filesystem-dev (>=${Boost_VER_STR}), libboost-filesystem-dev (<<${Boost_VER_STR_ONEGREATER}), uuid-dev (>= 2.27.1), dkms (>= 2.2.0), libprotoc-dev (>=2.6.1), libssl-dev (>=1.0.2), protobuf-compiler (>=2.6.1), libncurses5-dev (>=6.0), lsb-release, libxml2-dev (>=2.9.1), libyaml-dev (>= 0.1.6), libc6 (>= ${GLIBC_VERSION}), libc6 (<< ${GLIBC_VERSION_ONEGREATER}), python (>= 2.7), python-pip, libudev-dev ")
4949

5050
elseif (${LINUX_FLAVOR} MATCHES "^(RedHat|CentOS)")
5151
SET(CPACK_GENERATOR "RPM;TGZ")
@@ -66,7 +66,7 @@ elseif (${LINUX_FLAVOR} MATCHES "^(RedHat|CentOS)")
6666
# aws component dependencies
6767
SET(CPACK_RPM_AWS_PACKAGE_REQUIRES "xrt >= ${XRT_VERSION_MAJOR}.${XRT_VERSION_MINOR}.${XRT_VERSION_PATCH}")
6868
# xrt component dependencies
69-
SET(CPACK_RPM_XRT_PACKAGE_REQUIRES "ocl-icd-devel >= 2.2, boost-devel >= 1.53, boost-filesystem >= 1.53, libuuid-devel >= 2.23.2, dkms >= 2.5.0, protobuf-devel >= 2.5.0, protobuf-compiler >= 2.5.0, ncurses-devel >= 5.9, redhat-lsb-core, libxml2-devel >= 2.9.1, libyaml-devel >= 0.1.4, python >= 2.7, python-pip, openssl-devel >= 1.0.2 ")
69+
SET(CPACK_RPM_XRT_PACKAGE_REQUIRES "ocl-icd-devel >= 2.2, boost-devel >= 1.53, boost-filesystem >= 1.53, libuuid-devel >= 2.23.2, dkms >= 2.5.0, protobuf-devel >= 2.5.0, protobuf-compiler >= 2.5.0, ncurses-devel >= 5.9, redhat-lsb-core, libxml2-devel >= 2.9.1, libyaml-devel >= 0.1.4, python >= 2.7, python-pip, openssl-devel >= 1.0.2, libudev-devel ")
7070
else ()
7171
SET (CPACK_GENERATOR "TGZ")
7272
endif()

src/runtime_src/core/pcie/driver/linux/xocl/subdev/mailbox.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ struct mailbox {
400400
uint32_t mbx_proto_ver;
401401

402402
bool mbx_peer_dead;
403+
uint64_t mbx_opened;
403404
};
404405

405406
static inline const char *reg2name(struct mailbox *mbx, u32 *reg)
@@ -1868,6 +1869,9 @@ int mailbox_get(struct platform_device *pdev, enum mb_kind kind, u64 *data)
18681869

18691870
mutex_lock(&mbx->mbx_lock);
18701871
switch (kind) {
1872+
case DAEMON_STATE:
1873+
*data = mbx->mbx_opened;
1874+
break;
18711875
case CHAN_STATE:
18721876
*data = mbx->mbx_ch_state;
18731877
break;
@@ -1977,6 +1981,8 @@ static int mailbox_open(struct inode *inode, struct file *file)
19771981
if (!mbx)
19781982
return -ENXIO;
19791983

1984+
/* Assume msd/mpd is the only user of the software mailbox */
1985+
mbx->mbx_opened = 1;
19801986
/* create a reference to our char device in the opened file */
19811987
file->private_data = mbx;
19821988
return 0;
@@ -1989,6 +1995,7 @@ static int mailbox_close(struct inode *inode, struct file *file)
19891995
{
19901996
struct mailbox *mbx = file->private_data;
19911997

1998+
mbx->mbx_opened = 0;
19921999
xocl_drvinst_close(mbx);
19932000
return 0;
19942001
}
@@ -2227,6 +2234,7 @@ static int mailbox_probe(struct platform_device *pdev)
22272234
mbx->mbx_req_cnt = 0;
22282235
mbx->mbx_req_sz = 0;
22292236
mbx->mbx_peer_dead = false;
2237+
mbx->mbx_opened = 0;
22302238
mbx->mbx_prot_ver = XCL_MB_PROTOCOL_VER;
22312239

22322240
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

src/runtime_src/core/pcie/driver/linux/xocl/userpf/xocl_sysfs.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,26 @@ static ssize_t ready_show(struct device *dev,
343343
struct device_attribute *attr, char *buf)
344344
{
345345
struct xocl_dev *xdev = dev_get_drvdata(dev);
346-
uint64_t ch_state = 0, ret = 0;
346+
uint64_t ch_state = 0, ret = 0, daemon_state = 0;
347347

348348
/* Bypass this check for versal for now */
349349
if (XOCL_DSA_IS_VERSAL(xdev))
350350
ret = 1;
351351
else {
352352
xocl_mailbox_get(xdev, CHAN_STATE, &ch_state);
353353

354-
ret = (ch_state & XCL_MB_PEER_READY) ? 1 : 0;
354+
if (ch_state & XCL_MB_PEER_SAME_DOMAIN)
355+
ret = (ch_state & XCL_MB_PEER_READY) ? 1 : 0;
356+
else {
357+
/*
358+
* If xocl and xclmgmt are not in the same daemon,
359+
* mark the card as ready only when both MB channel
360+
* and daemon are ready
361+
*/
362+
xocl_mailbox_get(xdev, DAEMON_STATE, &daemon_state);
363+
ret = ((ch_state & XCL_MB_PEER_READY) && daemon_state)
364+
? 1 : 0;
365+
}
355366
}
356367

357368
return sprintf(buf, "0x%llx\n", ret);

src/runtime_src/core/pcie/driver/linux/xocl/xocl_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ enum data_kind {
804804
};
805805

806806
enum mb_kind {
807+
DAEMON_STATE,
807808
CHAN_STATE,
808809
CHAN_SWITCH,
809810
COMM_ID,

src/runtime_src/core/pcie/tools/cloud-daemon/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ target_link_libraries(mpd
2222
boost_system
2323
uuid
2424
dl
25+
udev
2526
)
2627
install (TARGETS mpd RUNTIME DESTINATION ${XRT_INSTALL_DIR}/bin)
2728

src/runtime_src/core/pcie/tools/cloud-daemon/aws/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ include_directories(
1414
file(GLOB AWS_PLUGIN_FILES
1515
"aws_dev.h"
1616
"aws_dev.cpp"
17+
"../common.h"
18+
"../common.cpp"
19+
"../sw_msg.h"
20+
"../sw_msg.cpp"
21+
"../pciefunc.h"
22+
"../pciefunc.cpp"
1723
)
1824

1925
add_library(aws_plugin OBJECT ${AWS_PLUGIN_FILES})
@@ -34,6 +40,7 @@ if(${INTERNAL_TESTING_FOR_AWS})
3440
boost_system
3541
pthread
3642
rt
43+
dl
3744
)
3845
else()
3946
include_directories(${AWS_FPGA_REPO_DIR}/sdk/userspace/include/) # path to fpga_mgmt.h
@@ -47,6 +54,7 @@ else()
4754
boost_system
4855
pthread
4956
rt
57+
dl
5058
${AWS_FPGA_MGMT_LIB_DIR}/libfpga_mgmt.a
5159
)
5260
endif()

src/runtime_src/core/pcie/tools/cloud-daemon/aws/aws_dev.cpp

Lines changed: 95 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@
3434
#include <iostream>
3535
#include <fstream>
3636
#include <exception>
37+
#include <future>
3738
#include <uuid/uuid.h>
3839
#include "xclbin.h"
3940
#include "aws_dev.h"
4041

41-
42+
static std::map<std::string, size_t>index_map;
4243
/*
4344
* Functions each plugin needs to provide
4445
*/
@@ -59,11 +60,15 @@ int init(mpd_plugin_callbacks *cbs)
5960
syslog(LOG_INFO, "aws: no device found");
6061
return ret;
6162
}
63+
ret = AwsDev::init(index_map);
64+
if (ret)
65+
return ret;
6266
if (cbs)
6367
{
6468
// hook functions
6569
cbs->mpc_cookie = NULL;
6670
cbs->get_remote_msd_fd = get_remote_msd_fd;
71+
cbs->mb_notify = mb_notify;
6772
cbs->mb_req.load_xclbin = awsLoadXclBin;
6873
cbs->mb_req.peer_data.get_icap_data = awsGetIcap;
6974
cbs->mb_req.peer_data.get_sensor_data = awsGetSensor;
@@ -108,6 +113,53 @@ int get_remote_msd_fd(size_t index, int* fd)
108113
return 0;
109114
}
110115

116+
/*
117+
* callback function that is used to notify xocl the imagined xclmgmt
118+
* online/offline
119+
* Input:
120+
* index: index of the user PF
121+
* fd: mailbox file descriptor
122+
* online: online or offline
123+
* Output:
124+
* None
125+
* Return value:
126+
* 0: success
127+
* others: err code
128+
*/
129+
int mb_notify(size_t index, int fd, bool online)
130+
{
131+
std::unique_ptr<sw_msg> swmsg;
132+
struct xcl_mailbox_req *mb_req = NULL;
133+
struct xcl_mailbox_peer_state mb_conn = { 0 };
134+
size_t data_len = sizeof(struct xcl_mailbox_peer_state) + sizeof(struct xcl_mailbox_req);
135+
pcieFunc dev(index);
136+
137+
std::vector<char> buf(data_len, 0);
138+
mb_req = reinterpret_cast<struct xcl_mailbox_req *>(buf.data());
139+
140+
mb_req->req = XCL_MAILBOX_REQ_MGMT_STATE;
141+
if (online)
142+
mb_conn.state_flags |= XCL_MB_STATE_ONLINE;
143+
else
144+
mb_conn.state_flags |= XCL_MB_STATE_OFFLINE;
145+
memcpy(mb_req->data, &mb_conn, sizeof(mb_conn));
146+
147+
try {
148+
swmsg = std::make_unique<sw_msg>(mb_req, data_len, 0x1234, XCL_MB_REQ_FLAG_REQUEST);
149+
} catch (std::exception &e) {
150+
std::cout << "aws mb_notify: " << e.what() << std::endl;
151+
throw;
152+
}
153+
154+
struct queue_msg msg;
155+
msg.localFd = fd;
156+
msg.type = REMOTE_MSG;
157+
msg.cb = nullptr;
158+
msg.data = std::move(swmsg);
159+
160+
return handleMsg(dev, msg);
161+
}
162+
111163
/*
112164
* callback function that is used to handle MAILBOX_REQ_LOAD_XCLBIN msg
113165
*
@@ -280,6 +332,18 @@ int awsGetSubdev(size_t index, char *resp, size_t resp_len)
280332
return ret;
281333
}
282334

335+
/*
336+
* Reset requires the mailbox msg return before the real reset
337+
* happens. So we run user special reset in async thread.
338+
*/
339+
std::future<void> nouse; //so far we don't care the return value of reset
340+
static void awsResetDeviceAsync(size_t index)
341+
{
342+
AwsDev d(index, nullptr);
343+
if (d.isGood()) {
344+
d.awsResetDevice();
345+
}
346+
}
283347
/*
284348
* callback function that is used to handle MAILBOX_REQ_HOT_RESET msg
285349
*
@@ -293,13 +357,9 @@ int awsGetSubdev(size_t index, char *resp, size_t resp_len)
293357
*/
294358
int awsResetDevice(size_t index, int *resp)
295359
{
296-
int ret = -1;
297-
AwsDev d(index, nullptr);
298-
if (d.isGood()) {
299-
*resp = d.awsResetDevice();
300-
ret = 0;
301-
}
302-
return ret;
360+
*resp = -ENOTSUP;
361+
nouse = std::async(std::launch::async, &awsResetDeviceAsync, index);
362+
return 0;
303363
}
304364

305365
/*
@@ -391,6 +451,16 @@ int awsReadP2pBarAddr(size_t index, const xcl_mailbox_p2p_bar_addr *addr, int *r
391451
return ret;
392452
}
393453

454+
/*
455+
* On AWS F1, fpga user PF without xclbin being loaded (cleared) has different
456+
* device id (0x1042) than that of the user PF with xclbin being loaded (0xf010)
457+
* Changint the device id needs pci node remove and rescan.
458+
* fpga_pci_rescan_slot_app_pfs( mBoardNumber ) is the function used to do that.
459+
* removal of the pf requires unload the xocl driver, within mpd it is impossible.
460+
* So we assume the user already made the change by loading a default afi from cmdline
461+
* with fpga-load-local-image.
462+
* From mpd & xocl perspective, whichever device id doesn't matter.
463+
*/
394464
int AwsDev::awsLoadXclBin(const xclBin *buffer)
395465
{
396466
#ifdef INTERNAL_TESTING_FOR_AWS
@@ -519,7 +589,19 @@ bool AwsDev::isGood() {
519589

520590
int AwsDev::awsUserProbe(xcl_mailbox_conn_resp *resp)
521591
{
592+
#ifndef INTERNAL_TESTING_FOR_AWS
593+
fpga_slot_spec spec_array[16];
594+
std::memset(spec_array, 0, sizeof(fpga_slot_spec) * 16);
595+
if (fpga_pci_get_all_slot_specs(spec_array, 16)) {
596+
std::cout << "ERROR: failed at fpga_pci_get_all_slot_specs" << std::endl;
597+
return -1;
598+
}
599+
600+
if (spec_array[mBoardNumber].map[FPGA_APP_PF].device_id != AWS_UserPF_DEVICE_ID)
601+
resp->conn_flags |= XCL_MB_PEER_READY;
602+
#else
522603
resp->conn_flags |= XCL_MB_PEER_READY;
604+
#endif
523605
return 0;
524606
}
525607

@@ -580,15 +662,18 @@ AwsDev::~AwsDev()
580662
}
581663
}
582664

583-
AwsDev::AwsDev(size_t index, const char *logfileName) : mBoardNumber(index)
665+
AwsDev::AwsDev(size_t index, const char *logfileName)
584666
{
585667
if (logfileName != nullptr) {
586668
mLogStream.open(logfileName);
587669
mLogStream << "FUNCTION, THREAD ID, ARG..." << std::endl;
588670
mLogStream << __func__ << ", " << std::this_thread::get_id() << std::endl;
589671
}
590672

673+
std::string sysfs_name = pcidev::get_dev(index, true)->sysfs_name;
674+
std::cout << "AwsDev: " << sysfs_name << "(index: " << index << ")" << std::endl;
591675
#ifdef INTERNAL_TESTING_FOR_AWS
676+
mBoardNumber = index;
592677
char file_name_buf[128];
593678
std::fill(&file_name_buf[0], &file_name_buf[0] + 128, 0);
594679
std::sprintf((char *)&file_name_buf, "/dev/awsmgmt%d", mBoardNumber);
@@ -600,31 +685,13 @@ AwsDev::AwsDev(size_t index, const char *logfileName) : mBoardNumber(index)
600685

601686
#else
602687
fpga_mgmt_init(); // aws-fpga version newer than 09/2019 need this
603-
loadDefaultAfiIfCleared();
688+
mBoardNumber = index_map[sysfs_name];
604689
//bar0 is mapped already. seems other 2 bars are not required.
605690
#endif
606691
}
607692

608693
//private functions
609694
#ifndef INTERNAL_TESTING_FOR_AWS
610-
int AwsDev::loadDefaultAfiIfCleared( void )
611-
{
612-
int array_len = 16;
613-
fpga_slot_spec spec_array[ array_len ];
614-
std::memset( spec_array, mBoardNumber, sizeof(fpga_slot_spec) * array_len );
615-
fpga_pci_get_all_slot_specs( spec_array, array_len );
616-
if( spec_array[mBoardNumber].map[FPGA_APP_PF].device_id == AWS_UserPF_DEVICE_ID ) {
617-
std::string agfi = DEFAULT_GLOBAL_AFI;
618-
fpga_mgmt_load_local_image( mBoardNumber, const_cast<char*>(agfi.c_str()) );
619-
if( sleepUntilLoaded( agfi ) ) {
620-
std::cout << "ERROR: Sleep until load failed." << std::endl;
621-
return -1;
622-
}
623-
fpga_pci_rescan_slot_app_pfs( mBoardNumber );
624-
}
625-
return 0;
626-
}
627-
628695
int AwsDev::sleepUntilLoaded( const std::string &afi )
629696
{
630697
for( int i = 0; i < 20; i++ ) {

0 commit comments

Comments
 (0)