diff --git a/src/runtime_src/core/pcie/linux/device_linux.cpp b/src/runtime_src/core/pcie/linux/device_linux.cpp index ff218fcc8fe..c31d9d1d485 100644 --- a/src/runtime_src/core/pcie/linux/device_linux.cpp +++ b/src/runtime_src/core/pcie/linux/device_linux.cpp @@ -486,7 +486,7 @@ struct hotplug_offline auto mgmt_dev = xrt_core::pci::get_dev(device->get_device_id(), false); // Remove both user_pf and mgmt_pf - if (xrt_core::pci::shutdown(mgmt_dev, true, true)) + if (xrt_core::pci::shutdown(mgmt_dev.get(), true, true)) throw xrt_core::query::sysfs_error("Hotplug offline failed"); return true; @@ -1391,6 +1391,12 @@ lookup_query(query::key_type query_key) const device_linux:: device_linux(handle_type device_handle, id_type device_id, bool user) : shim(device_handle, device_id, user) + , m_pcidev(pci::get_dev(device_id, user)) +{ +} + +device_linux:: +~device_linux() { } @@ -1421,7 +1427,7 @@ void device_linux:: read(uint64_t offset, void* buf, uint64_t len) const { - if (auto err = xrt_core::pci::get_dev(get_device_id(), false)->pcieBarRead(offset, buf, len)) + if (auto err = get_dev()->pcieBarRead(offset, buf, len)) throw error(err, "read failed"); } @@ -1429,7 +1435,7 @@ void device_linux:: write(uint64_t offset, const void* buf, uint64_t len) const { - if (auto err = xrt_core::pci::get_dev(get_device_id(), false)->pcieBarWrite(offset, buf, len)) + if (auto err = get_dev()->pcieBarWrite(offset, buf, len)) throw error(err, "write failed"); } @@ -1438,8 +1444,7 @@ device_linux:: reset(query::reset_type& key) const { std::string err; - xrt_core::pci::get_dev(get_device_id(), false)->sysfs_put( - key.get_subdev(), key.get_entry(), err, key.get_value()); + get_dev()->sysfs_put(key.get_subdev(), key.get_entry(), err, key.get_value()); if (!err.empty()) throw error("reset failed"); } @@ -1448,14 +1453,14 @@ int device_linux:: open(const std::string& subdev, int flag) const { - return xrt_core::pci::get_dev(get_device_id(), false)->open(subdev, flag); + return get_dev()->open(subdev, flag); } void device_linux:: close(int dev_handle) const { - xrt_core::pci::get_dev(get_device_id(), false)->close(dev_handle); + get_dev()->close(dev_handle); } void @@ -1471,7 +1476,7 @@ xclmgmt_load_xclbin(const char* buffer) const { try { xrt_core::scope_value_guard> fd = file_open("", O_RDWR); xclmgmt_ioc_bitstream_axlf obj = { reinterpret_cast( const_cast(buffer) ) }; - ret = xrt_core::pci::get_dev(get_device_id(), false)->ioctl(fd.get(), XCLMGMT_IOCICAPDOWNLOAD_AXLF, &obj); + ret = get_dev()->ioctl(fd.get(), XCLMGMT_IOCICAPDOWNLOAD_AXLF, &obj); } catch (const std::exception& e) { xrt_core::send_exception_message(e.what(), "Failed to open device"); } @@ -1484,7 +1489,7 @@ xclmgmt_load_xclbin(const char* buffer) const { void device_linux:: device_shutdown() const { - auto mgmt_dev = xrt_core::pci::get_dev(get_device_id(), false); + auto mgmt_dev = get_dev(); // hot reset pcie device if (xrt_core::pci::shutdown(mgmt_dev)) throw xrt_core::error("Hot resetting pci device failed."); @@ -1493,7 +1498,7 @@ device_shutdown() const { void device_linux:: device_online() const { - auto mgmt_dev = xrt_core::pci::get_dev(get_device_id(), false); + auto mgmt_dev = get_dev(); auto peer_dev = mgmt_dev->lookup_peer_dev(); std::string errmsg; diff --git a/src/runtime_src/core/pcie/linux/device_linux.h b/src/runtime_src/core/pcie/linux/device_linux.h index cf007b1bce9..df11f5d48fe 100644 --- a/src/runtime_src/core/pcie/linux/device_linux.h +++ b/src/runtime_src/core/pcie/linux/device_linux.h @@ -9,15 +9,22 @@ #include "core/common/shim/buffer_handle.h" #include "core/common/shim/hwctx_handle.h" #include "core/pcie/common/device_pcie.h" +#include "core/pcie/linux/pcidev.h" namespace xrt_core { +// Forward declaration +namespace pci { +class dev; +} + // concrete class derives from device_pcie, but mixes in // shim layer functions for access through base class class device_linux : public shim { public: device_linux(handle_type device_handle, id_type device_id, bool user); + ~device_linux(); // query functions virtual void read_dma_stats(boost::property_tree::ptree& pt) const; @@ -86,9 +93,16 @@ class device_linux : public shim { return xrt::shim_int::alloc_bo(get_device_handle(), userptr, size, xcl_bo_flags{flags}.flags); } - //////////////////////////////////////////////////////////////// + +protected: + pci::dev* + get_dev() const + { + return m_pcidev.get(); + } private: + std::shared_ptr m_pcidev; // Private look up function for concrete query::request virtual const query::request& lookup_query(query::key_type query_key) const override; diff --git a/src/runtime_src/core/pcie/linux/pcidev.cpp b/src/runtime_src/core/pcie/linux/pcidev.cpp index 8c6acfe0a18..fb53d89a12e 100644 --- a/src/runtime_src/core/pcie/linux/pcidev.cpp +++ b/src/runtime_src/core/pcie/linux/pcidev.cpp @@ -420,7 +420,7 @@ get_subdev_path(const std::string& subdev, uint idx) const if (subdev.empty()) { std::string instStr = std::to_string(m_instance); std::string prefixStr = "/dev/"; - prefixStr += m_driver.dev_node_dir() + "/" + m_driver.dev_node_prefix(); + prefixStr += m_driver->dev_node_dir() + "/" + m_driver->dev_node_prefix(); return prefixStr + instStr; } @@ -455,25 +455,28 @@ open(const std::string& subdev, int flag) const } dev:: -dev(const drv& driver, const std::string& sysfs) : m_sysfs_name(sysfs), m_driver(driver) +dev(std::shared_ptr driver, std::string sysfs) + : m_sysfs_name(std::move(sysfs)) + , m_driver(std::move(driver)) { std::string err; - if(sscanf(sysfs.c_str(), "%hx:%hx:%hx.%hx", &m_domain, &m_bus, &m_dev, &m_func) < 4) - throw std::invalid_argument(sysfs + " is not valid BDF"); + if(sscanf(m_sysfs_name.c_str(), "%hx:%hx:%hx.%hx", &m_domain, &m_bus, &m_dev, &m_func) < 4) + throw std::invalid_argument(m_sysfs_name + " is not valid BDF"); - m_is_mgmt = !driver.is_user(); + m_is_mgmt = !m_driver->is_user(); if (m_is_mgmt) { sysfs_get("", "instance", err, m_instance, static_cast(INVALID_ID)); - } else { + } + else { m_instance = get_render_value( - sysfs::dev_root + sysfs + "/" + driver.sysfs_dev_node_dir(), - driver.dev_node_prefix()); + sysfs::dev_root + m_sysfs_name + "/" + m_driver->sysfs_dev_node_dir(), + m_driver->dev_node_prefix()); } sysfs_get("", "userbar", err, m_user_bar, 0); - m_user_bar_size = bar_size(sysfs::dev_root + sysfs, m_user_bar); + m_user_bar_size = bar_size(sysfs::dev_root + m_sysfs_name, m_user_bar); sysfs_get("", "ready", err, m_is_ready, false); m_user_bar_map = reinterpret_cast(MAP_FAILED); } @@ -487,7 +490,7 @@ dev:: int dev:: -map_usr_bar() +map_usr_bar() const { std::lock_guard l(m_lock); @@ -522,7 +525,7 @@ close(int dev_handle) const int dev:: -pcieBarRead(uint64_t offset, void* buf, uint64_t len) +pcieBarRead(uint64_t offset, void* buf, uint64_t len) const { if (m_user_bar_map == MAP_FAILED) { int ret = map_usr_bar(); @@ -535,7 +538,7 @@ pcieBarRead(uint64_t offset, void* buf, uint64_t len) int dev:: -pcieBarWrite(uint64_t offset, const void* buf, uint64_t len) +pcieBarWrite(uint64_t offset, const void* buf, uint64_t len) const { if (m_user_bar_map == MAP_FAILED) { int ret = map_usr_bar(); @@ -720,7 +723,7 @@ get_runtime_active_kids(std::string &pci_bridge_path) } int -shutdown(std::shared_ptr mgmt_dev, bool remove_user, bool remove_mgmt) +shutdown(dev *mgmt_dev, bool remove_user, bool remove_mgmt) { if (!mgmt_dev->m_is_mgmt) return -EINVAL; diff --git a/src/runtime_src/core/pcie/linux/pcidev.h b/src/runtime_src/core/pcie/linux/pcidev.h index b05ead193c8..388d0f74d2f 100644 --- a/src/runtime_src/core/pcie/linux/pcidev.h +++ b/src/runtime_src/core/pcie/linux/pcidev.h @@ -80,10 +80,10 @@ class dev bool m_is_mgmt = false; bool m_is_ready = false; - dev(const drv& driver, const std::string& sysfs_name); + dev(std::shared_ptr driver, std::string sysfs_name); + virtual ~dev(); - dev() = delete; virtual void sysfs_get(const std::string& subdev, const std::string& entry, @@ -135,10 +135,10 @@ class dev get_subdev_path(const std::string& subdev, uint32_t idx) const; virtual int - pcieBarRead(uint64_t offset, void* buf, uint64_t len); + pcieBarRead(uint64_t offset, void* buf, uint64_t len) const; virtual int - pcieBarWrite(uint64_t offset, const void* buf, uint64_t len); + pcieBarWrite(uint64_t offset, const void* buf, uint64_t len) const; virtual int open(const std::string& subdev, int flag) const; @@ -185,12 +185,13 @@ class dev private: int - map_usr_bar(); + map_usr_bar() const; - std::mutex m_lock; - char *m_user_bar_map = reinterpret_cast(MAP_FAILED); + mutable std::mutex m_lock; + // Virtual address of memory mapped BAR0, mapped on first use, once mapped, never change. + mutable char *m_user_bar_map = reinterpret_cast(MAP_FAILED); - const drv& m_driver; + std::shared_ptr m_driver; }; size_t @@ -206,7 +207,7 @@ std::shared_ptr lookup_user_dev(std::shared_ptr mgmt_dev); int -shutdown(std::shared_ptr mgmt_dev, bool remove_user = false, bool remove_mgmt = false); +shutdown(dev *mgmt_dev, bool remove_user = false, bool remove_mgmt = false); int check_p2p_config(const std::shared_ptr& dev, std::string &err); diff --git a/src/runtime_src/core/pcie/linux/pcidrv.cpp b/src/runtime_src/core/pcie/linux/pcidrv.cpp index a366cfbb57b..7acbd8b011a 100644 --- a/src/runtime_src/core/pcie/linux/pcidrv.cpp +++ b/src/runtime_src/core/pcie/linux/pcidrv.cpp @@ -47,7 +47,7 @@ std::shared_ptr drv:: create_pcidev(const std::string& sysfs) const { - return std::make_shared(*this, sysfs); + return std::make_shared(shared_from_this(), sysfs); } } } // namespace xrt_core :: pci diff --git a/src/runtime_src/core/pcie/linux/pcidrv.h b/src/runtime_src/core/pcie/linux/pcidrv.h index 41d96fcec30..1fd79e4283d 100644 --- a/src/runtime_src/core/pcie/linux/pcidrv.h +++ b/src/runtime_src/core/pcie/linux/pcidrv.h @@ -8,7 +8,7 @@ namespace xrt_core { namespace pci { -class drv +class drv : public std::enable_shared_from_this { public: // Name of the driver as shown under /sys/bus/pci/drivers/