[Cuse/Fix] Add ENABLE_CUSE macro instead of variable
authorDongju Chae <dongju.chae@samsung.com>
Fri, 24 Sep 2021 06:35:23 +0000 (15:35 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Mon, 27 Sep 2021 01:24:41 +0000 (10:24 +0900)
This patch explicitly adds ENABLE_CUSE macro rather than
using an internal variable.

Note that in case of .NET app running on the Tizen emulator,
cuse context's pid is not the calling process. So, the pid
info is shared via a file. But, this may not have any sync issue
because an emulator may not support concurrent executions.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
meson.build
meson_options.txt
packaging/npu-engine.spec
src/core/npu/NPUdrvAPI.h
src/core/npu/NPUdrvAPI_triv2.cc
utils/trinity_cuse/trinity-cuse.cc

index 7f77c34435b099fc69a6e0219bb2b356e85360c0..b69b9cf5565d3393d639252d220db698086620d0 100644 (file)
@@ -100,6 +100,10 @@ if get_option('enable_npu_emul')
   add_project_arguments('-DENABLE_EMUL', language: ['c', 'cpp'])
 endif
 
+if get_option('enable_npu_cuse')
+  add_project_arguments('-DENABLE_CUSE', language: ['c', 'cpp'])
+endif
+
 if sysroot.startswith('/')
   sysroot_inc_cflags_template = '-I@0@/usr/include@1@'
   sysroot_inc = sysroot_inc_cflags_template.format(sysroot, '')
index 1ac4f9c6a95b37b98b5f8f2286a7f9b8ffe52195..62acb8ddc26b81a76884197a8c229ad3ddc89c5e 100644 (file)
@@ -8,6 +8,7 @@ option('log_level', type : 'string', value : '2')
 option('mute_stdout', type : 'boolean', value : false)
 option('target_platform', type : 'combo', choices : ['debian', 'tizen', 'fpga'], value : 'debian')
 option('enable_npu_emul', type : 'boolean', value : false)
+option('enable_npu_cuse', type : 'boolean', value : false)
 option('enable_data_manip', type : 'boolean', value : false)
 option('enable_buffering', type : 'boolean', value : false)
 option('enable_plugin_npumgr', type : 'boolean', value : false)
index ab42c3a92590cf12a241336c32cd0c1188dd6080..7edc28698b0335af448e0c6c70b4e1922759459a 100644 (file)
@@ -29,10 +29,6 @@ BuildRequires:       pkgconfig(libdrm)
 BuildRequires: pkgconfig(tinyxml2)
 BuildRequires: pkgconfig(dlog)
 
-%if 0%{?npu_cuse}
-BuildRequires: libmrpsim-devel
-%endif
-
 %if 0%{?npu_emul}
 BuildRequires: libmrpsim-devel
 %define enable_npu_emul -Denable_npu_emul=true
@@ -40,6 +36,13 @@ BuildRequires:       libmrpsim-devel
 %define enable_npu_emul -Denable_npu_emul=false
 %endif
 
+%if 0%{?npu_cuse}
+BuildRequires: libmrpsim-devel
+%define enable_npu_cuse -Denable_npu_cuse=true
+%else
+%define enable_npu_cuse -Denable_npu_cuse=false
+%endif
+
 %if 0%{?npumgr_plugin}
 BuildRequires: glib2-devel
 %define enable_plugin_npumgr -Denable_plugin_npumgr=true
@@ -69,7 +72,7 @@ meson --buildtype=plain --bindir=%{neexampledir} --prefix=%{_prefix} \
       --libdir=%{_libdir} --includedir=%{_includedir} \
       --datadir=%{_datadir} --sysconfdir=%{_sysconfdir} \
       -Dtarget_platform=tizen -Denable_data_manip=true \
-      %{enable_npu_emul} %{enable_plugin_npumgr} %{enable_plugin_nns} \
+      %{enable_npu_emul} %{enable_npu_cuse} %{enable_plugin_npumgr} %{enable_plugin_nns} \
       build
 ninja -C build %{?_smp_mflags}
 
index 31171e8a3ce83d55ebed8db42f5f092417e54d69..632ee9bedfe6cf86afdb73632cb03bacb5d00c38 100644 (file)
@@ -115,7 +115,9 @@ class DriverAPI {
   static uint32_t api_level_; /**< Trinity API level */
 };
 
+#ifdef ENABLE_CUSE
 class CuseElement;
+#endif
 
 /** @brief Driver APIs for TRIV2 */
 class TrinityVision2API : public DriverAPI {
@@ -162,9 +164,9 @@ class TrinityVision2API : public DriverAPI {
   static const std::string dev_node_base;
   static std::bitset<CHAR_BIT> dev_bitset;
 
+#ifdef ENABLE_CUSE
   static ThreadSafeMap<int, CuseElement> cuse_map;
-
-  bool is_cuse_;
+#endif
 
   std::fstream dev_ios_;
 };
index 9d4780c7ffc7426b1776671bd591a15163d7583f..08939bdf33c0085a938819fc4619a67edcba1ca1 100644 (file)
@@ -42,6 +42,7 @@ constexpr size_t default_buf_size = (256 * PAGE_SIZE);
 const std::string TrinityVision2API::dev_node_base = "triv2";
 std::bitset<CHAR_BIT> TrinityVision2API::dev_bitset = 0;
 
+#ifdef ENABLE_CUSE
 /** @brief Cuse-hwmem element */
 class CuseElement {
  public:
@@ -64,12 +65,13 @@ class CuseElement {
 };
 
 ThreadSafeMap<int, CuseElement> TrinityVision2API::cuse_map;
+#endif
 
 /**
  * @brief constructor of the API instance for Trinity Vision driver
  * @param[in] dev_id device id
  */
-TrinityVision2API::TrinityVision2API (int dev_id) : DriverAPI (dev_id), is_cuse_ (false) {
+TrinityVision2API::TrinityVision2API (int dev_id) : DriverAPI (dev_id) {
   int num_devs;
 
   if (dev_id > max_num_devs) {
@@ -108,6 +110,12 @@ TrinityVision2API::open () {
     return -ENODEV;
   }
 
+#ifdef ENABLE_CUSE
+  std::ofstream ofs ("/tmp/npu-engine-pid.txt");
+  ofs << getpid ();
+  ofs.close ();
+#endif
+
   path = "/dev/" + TrinityVision2API::dev_node_base + "-" + std::to_string (dev_id_);
   fd = ::open (path.c_str (), O_RDWR);
   if (fd < 0) {
@@ -131,10 +139,6 @@ TrinityVision2API::checkSanity () {
     return -ENODEV;
   }
 
-  /* Check if this device is using a cuse-based driver */
-  if (type == TRINITY_DEV_VISION2_CUSE)
-    this->is_cuse_ = true;
-
   min_ver &= ~TRINITY_MASK_DEV;
   /* Check if the major version numbers are same */
   if ((lib_ver & TRINITY_MASK_MAJOR_VER) != (min_ver & TRINITY_MASK_MAJOR_VER)) {
@@ -248,9 +252,7 @@ TrinityVision2API::alloc (size_t size, bool contiguous) const {
   if (ret < 0)
     IOCTL_RETURN_ERRNO (TRINITY_IOCTL_HWMEM_ALLOC);
 
-  if (!is_cuse_)
-    return ret;
-
+#ifdef ENABLE_CUSE
   CuseElement *elem;
   std::string shm_name;
   int dbuf_fd = ret;
@@ -277,6 +279,7 @@ TrinityVision2API::alloc (size_t size, bool contiguous) const {
     delete elem;
     return -EINVAL;
   }
+#endif
 
   return ret;
 }
@@ -299,18 +302,18 @@ TrinityVision2API::dealloc (int dmabuf, bool contiguous) const {
 
   hwmem.type = contiguous ? TRINITY_HWMEM_DMA_CONT : TRINITY_HWMEM_DMA_IOMMU;
 
+#ifdef ENABLE_CUSE
   /* translate dmabuf FDs to cuse-compatible ones */
-  if (is_cuse_) {
-    CuseElement *elem = cuse_map.find (dmabuf);
-    if (elem == nullptr)
-      return -ENOENT;
+  CuseElement *elem = cuse_map.find (dmabuf);
+  if (elem == nullptr)
+    return -ENOENT;
 
-    hwmem.dbuf_fd = elem->getDbufFD ();
+  hwmem.dbuf_fd = elem->getDbufFD ();
 
-    cuse_map.remove (dmabuf);
-  } else {
-    hwmem.dbuf_fd = dmabuf;
-  }
+  cuse_map.remove (dmabuf);
+#else
+  hwmem.dbuf_fd = dmabuf;
+#endif
 
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_HWMEM_DEALLOC, &hwmem);
   if (ret < 0)
@@ -436,30 +439,30 @@ TrinityVision2API::registerModel (model_config_t *model_config, uint64_t npu_ver
     }
   } /** else: don't care */
 
+#ifdef ENABLE_CUSE
   /* translate dmabuf FDs to cuse-compatible ones */
   int dbuf_fd = model_config->dbuf_fd;
   int metadata_dbuf_fd = model_config->metadata_dbuf_fd;
 
-  if (is_cuse_) {
-    CuseElement *prog = cuse_map.find (dbuf_fd);
-    if (prog == nullptr)
-      return -ENOENT;
+  CuseElement *prog = cuse_map.find (dbuf_fd);
+  if (prog == nullptr)
+    return -ENOENT;
 
-    CuseElement *meta = cuse_map.find (metadata_dbuf_fd);
-    if (meta == nullptr)
-      return -ENOENT;
+  CuseElement *meta = cuse_map.find (metadata_dbuf_fd);
+  if (meta == nullptr)
+    return -ENOENT;
 
-    model_config->dbuf_fd = prog->getDbufFD ();
-    model_config->metadata_dbuf_fd = meta->getDbufFD ();
-  }
+  model_config->dbuf_fd = prog->getDbufFD ();
+  model_config->metadata_dbuf_fd = meta->getDbufFD ();
+#endif
 
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_REGISTER_MODEL, model_config);
 
+#ifdef ENABLE_CUSE
   /* rollback FDs to prevent any side-effects */
-  if (is_cuse_) {
-    model_config->dbuf_fd = dbuf_fd;
-    model_config->metadata_dbuf_fd = metadata_dbuf_fd;
-  }
+  model_config->dbuf_fd = dbuf_fd;
+  model_config->metadata_dbuf_fd = metadata_dbuf_fd;
+#endif
 
   if (ret < 0)
     IOCTL_RETURN_ERRNO (TRINITY_IOCTL_REGISTER_MODEL);
@@ -503,39 +506,39 @@ TrinityVision2API::runInput (input_config_t *input_config) const {
     return -EINVAL;
   }
 
+#ifdef ENABLE_CUSE
   /* translate dmabuf FDs to cuse-compatible ones */
-  if (is_cuse_) {
-    CuseElement *elem;
-    void *segt;
+  CuseElement *elem;
+  void *segt;
 
-    elem = cuse_map.find (input_config->dbuf_fd);
-    if (elem == nullptr)
-      return -ENOENT;
+  elem = cuse_map.find (input_config->dbuf_fd);
+  if (elem == nullptr)
+    return -ENOENT;
+
+  segt = this->mmap (input_config->dbuf_fd, PAGE_SIZE);
+  if (segt == nullptr)
+    return -EINVAL;
 
-    segt = this->mmap (input_config->dbuf_fd, PAGE_SIZE);
-    if (segt == nullptr)
+  input_config->dbuf_fd = elem->getDbufFD ();
+  for (uint32_t i = 0; i < input_config->num_segments; i++) {
+    int dbuf_fd = ((int *) segt)[i];
+    if (dbuf_fd < 0) {
+      this->munmap (segt, PAGE_SIZE);
       return -EINVAL;
+    }
 
-    input_config->dbuf_fd = elem->getDbufFD ();
-    for (uint32_t i = 0; i < input_config->num_segments; i++) {
-      int dbuf_fd = ((int *) segt)[i];
-      if (dbuf_fd < 0) {
-        this->munmap (segt, PAGE_SIZE);
-        return -EINVAL;
-      }
-
-      elem = cuse_map.find (dbuf_fd);
-      if (elem == nullptr) {
-        this->munmap (segt, PAGE_SIZE);
-        return -ENOENT;
-      }
-
-      ((int *) segt)[i] = elem->getDbufFD ();
+    elem = cuse_map.find (dbuf_fd);
+    if (elem == nullptr) {
+      this->munmap (segt, PAGE_SIZE);
+      return -ENOENT;
     }
 
-    this->munmap (segt, PAGE_SIZE);
+    ((int *) segt)[i] = elem->getDbufFD ();
   }
 
+  this->munmap (segt, PAGE_SIZE);
+#endif
+
   ret = ioctl (this->getDeviceFD (), TRINITY_IOCTL_RUN_INPUT, input_config);
   if (ret < 0)
     IOCTL_RETURN_ERRNO (TRINITY_IOCTL_RUN_INPUT);
@@ -647,11 +650,11 @@ TrinityVision2API::getProfile (int req_id, npu_profile *profile) const {
   profile->num_layers = meta.total_ops;
   profile->layers = new npu_profile_layer[profile->num_layers];
 
-  if (is_cuse_) {
-    std::string prof_path = Conf::getInstance ().getPrefixProfile ();
-    prof_path += "/ne_profile." + std::to_string (req_id) + ".rec";
-    profile->prof_path = strdup (prof_path.c_str ());
-  }
+#ifdef ENABLE_CUSE
+  std::string prof_path = Conf::getInstance ().getPrefixProfile ();
+  prof_path += "/ne_profile." + std::to_string (req_id) + ".rec";
+  profile->prof_path = strdup (prof_path.c_str ());
+#endif
 
   buff.req_id = meta.req_id;
 
index 5a23b6eb835faf31b2d29101bd008d470468f7a0..45663f9eca79f39904ab7bc8a39d59a18d1dc636 100644 (file)
@@ -14,6 +14,7 @@
 #define FUSE_USE_VERSION 29
 
 #include <iostream>
+#include <fstream>
 
 #include <cuse_lowlevel.h>
 #include <string.h>
@@ -46,6 +47,18 @@ find_ioctl_vtable (const std::string &dev_name) {
   return false;
 }
 
+int
+get_app_id (const fuse_req_t &req) {
+  int app_id = fuse_req_ctx (req)->pid;
+
+  /* FIXME: in .NET app, the ctx's pid is not the calling DLL process */
+  std::ifstream ifs ("/tmp/npu-engine-pid.txt");
+  if (ifs.is_open ())
+    ifs >> app_id;
+
+  return app_id;
+}
+
 /**
  * @brief impl. of .open ()
  */
@@ -54,7 +67,7 @@ trinity_cuse_open (fuse_req_t req, struct fuse_file_info *fi) {
   trinity_cuse_context *ctx;
 
   ctx = new trinity_cuse_context;
-  ctx->app_id = fuse_req_ctx (req)->pid;
+  ctx->app_id = get_app_id (req);
   ctx->prefix_share = Conf::getInstance ().getPrefixShare ();
   ctx->prefix_profile = Conf::getInstance ().getPrefixProfile ();