Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nvtop for openSUSE:Factory checked 
in at 2023-06-22 23:27:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nvtop (Old)
 and      /work/SRC/openSUSE:Factory/.nvtop.new.15902 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nvtop"

Thu Jun 22 23:27:07 2023 rev:2 rq:1094674 version:3.0.2+2

Changes:
--------
--- /work/SRC/openSUSE:Factory/nvtop/nvtop.changes      2023-04-26 
17:27:00.102197417 +0200
+++ /work/SRC/openSUSE:Factory/.nvtop.new.15902/nvtop.changes   2023-06-22 
23:27:51.542391743 +0200
@@ -1,0 +2,12 @@
+Thu Jun 22 13:00:22 UTC 2023 - [email protected]
+
+- Update to version 3.0.2+2:
+  * Fix a potential issue when using multiple AMDGPUs.
+  * Fix amdgpu wrong tx/rx computation
+  * Remove workaround for driver bug
+  * Uniqueness is pdev+id on amdgpu
+  * Uniqueness is pdev+id on intel
+  * README MSM information.
+  * MSM and Adreno support
+
+-------------------------------------------------------------------

Old:
----
  nvtop-3.0.1+29.obscpio

New:
----
  nvtop-3.0.2+2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nvtop.spec ++++++
--- /var/tmp/diff_new_pack.OKosug/_old  2023-06-22 23:27:52.034394253 +0200
+++ /var/tmp/diff_new_pack.OKosug/_new  2023-06-22 23:27:52.038394273 +0200
@@ -1,6 +1,7 @@
 #
 # spec file for package nvtop
 #
+# Copyright (c) 2023 SUSE LLC
 # Copyright (c) 2020-2023 Malcolm J Lewis <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
@@ -12,15 +13,16 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
+
 Name:           nvtop
-Version:        3.0.1+29
+Version:        3.0.2+2
 Release:        0
-License:        GPL-3.0+
+License:        GPL-3.0-or-later
 Summary:        A (h)top like task monitor for NVIDIA and AMD GPUs
-Url:            https://github.com/Syllo/nvtop
+URL:            https://github.com/Syllo/nvtop
 Source0:        %{name}-%{version}.tar.xz
 BuildRequires:  cmake
 BuildRequires:  gcc-c++

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.OKosug/_old  2023-06-22 23:27:52.086394518 +0200
+++ /var/tmp/diff_new_pack.OKosug/_new  2023-06-22 23:27:52.090394538 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/Syllo/nvtop.git</param>
-              <param 
name="changesrevision">d3dddbdeb16e0d5982414829a03383df93b6a4b1</param></service></servicedata>
+              <param 
name="changesrevision">9a8458b541a195a0c5cadafb66e240962c852b39</param></service></servicedata>
 (No newline at EOF)
 

++++++ nvtop-3.0.1+29.obscpio -> nvtop-3.0.2+2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/CMakeLists.txt 
new/nvtop-3.0.2+2/CMakeLists.txt
--- old/nvtop-3.0.1+29/CMakeLists.txt   2023-02-25 12:30:33.000000000 +0100
+++ new/nvtop-3.0.2+2/CMakeLists.txt    2023-06-15 11:47:30.000000000 +0200
@@ -4,7 +4,7 @@
 #                              PROJECT                              #
 #///////////////////////////////////////////////////////////////////#
 
-project(nvtop VERSION 3.0.1
+project(nvtop VERSION 3.0.2
   LANGUAGES C CXX)
 
 set(default_build_type "Release")
@@ -63,6 +63,7 @@
 option(NVIDIA_SUPPORT "Build support for NVIDIA GPUs through libnvml" ON)
 option(AMDGPU_SUPPORT "Build support for AMD GPUs through amdgpu driver" ON)
 option(INTEL_SUPPORT "Build support for Intel GPUs through i915 driver" ON)
+option(MSM_SUPPORT "Build support for Adreno GPUs through msm driver" ON)
 
 add_subdirectory(src)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/README.markdown 
new/nvtop-3.0.2+2/README.markdown
--- old/nvtop-3.0.1+29/README.markdown  2023-02-25 12:30:33.000000000 +0100
+++ new/nvtop-3.0.2+2/README.markdown   2023-06-15 11:47:30.000000000 +0200
@@ -23,11 +23,12 @@
   - [AMD](#amd)
   - [Intel](#intel)
   - [NVIDIA](#nvidia)
+  - [Adreno](#adreno)
 - [Build](#build)
 - [Distribution Specific Installation 
Process](#distribution-specific-installation-process)
   - [Ubuntu / Debian](#ubuntu--debian)
-    - [Ubuntu disco (19.04) / Debian buster 
(stable)](#ubuntu-disco-1904--debian-buster-stable)
-  - [Fedora / RedHat / CentOS](#fedora--redhat--centos)
+    - [Ubuntu Impish (21.10) / Debian buster (stable) and more recent 
(stable)](#ubuntu-impish-2110-debian-buster-stable-and-more-recent)
+  - [Fedora / Red Hat / CentOS](#fedora--red-hat--centos)
   - [OpenSUSE](#opensuse)
   - [Arch Linux](#arch-linux)
   - [AppImage](#appimage)
@@ -102,6 +103,15 @@
 successor should work fine. For more information about supported GPUs please
 take a look at the [NVML 
documentation](http://docs.nvidia.com/deploy/nvml-api/nvml-api-reference.html#nvml-api-reference).
 
+### Adreno
+
+NVTOP supports Adreno GPUs using the `msm` linux driver.
+
+msm introduced the fdinfo interface in kernel 6.0 ([browse kernel
+source](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/gpu/drm/msm/msm_drv.c?h=linux-6.0.y)).
+Hence, you will need a kernel with a version greater or equal to 6.0 to see the
+processes using Adreno GPUs.
+
 Build
 -----
 
@@ -160,11 +170,31 @@
   - Follow the [NVTOP Build](#nvtop-build)
 
 
-### Fedora / RedHat / CentOS
+### Fedora / Red Hat / CentOS
 
 A standalone application is available as [AppImage](#appimage).
 
-#### Build process for Fedora / RedHat / CentOS:
+#### Fedora 36 and newer
+
+- ```bash
+  sudo dnf install nvtop
+  ```
+  
+#### Red Hat Enterprise Linux 8 and 9
+
+- ```bash
+  sudo dnf install -y 
https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E 
%{rhel}).noarch.rpm
+  sudo dnf install nvtop
+  ```
+  
+#### CentOS Stream, Rocky Linux, AlmaLinux
+
+- ```bash
+  sudo dnf install -y epel-release
+  sudo dnf install nvtop
+  ```  
+
+#### Build process for Fedora / Red Hat / CentOS:
 
 - AMD and Intel Dependencies
   ```bash
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/CMakeLists.txt 
new/nvtop-3.0.2+2/src/CMakeLists.txt
--- old/nvtop-3.0.1+29/src/CMakeLists.txt       2023-02-25 12:30:33.000000000 
+0100
+++ new/nvtop-3.0.2+2/src/CMakeLists.txt        2023-06-15 11:47:30.000000000 
+0200
@@ -58,17 +58,24 @@
   target_sources(nvtop PRIVATE device_discovery_linux.c)
 endif()
 
-if(AMDGPU_SUPPORT)
+if(AMDGPU_SUPPORT OR MSM_SUPPORT)
   # Search for libdrm for AMDGPU support
   find_package(Libdrm)
 
   if(Libdrm_FOUND)
-    message(STATUS "Found libdrm; Enabling AMDGPU support")
+    message(STATUS "Found libdrm; Enabling support")
     target_include_directories(nvtop PRIVATE ${Libdrm_INCLUDE_DIRS})
-    target_sources(nvtop PRIVATE extract_gpuinfo_amdgpu.c)
-    target_sources(nvtop PRIVATE extract_gpuinfo_amdgpu_utils.c)
+    if (AMDGPU_SUPPORT)
+      target_sources(nvtop PRIVATE extract_gpuinfo_amdgpu.c)
+      target_sources(nvtop PRIVATE extract_gpuinfo_amdgpu_utils.c)
+    endif()
+
+    if (MSM_SUPPORT)
+      target_sources(nvtop PRIVATE extract_gpuinfo_msm.c)
+      target_sources(nvtop PRIVATE extract_gpuinfo_msm_utils.c)
+    endif()
   else()
-    message(FATAL_ERROR "libdrm not found; This library is required for AMDGPU 
support")
+    message(FATAL_ERROR "libdrm not found; This library is required for AMDGPU 
and MSM support")
   endif()
 endif()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/extract_gpuinfo.c 
new/nvtop-3.0.2+2/src/extract_gpuinfo.c
--- old/nvtop-3.0.1+29/src/extract_gpuinfo.c    2023-02-25 12:30:33.000000000 
+0100
+++ new/nvtop-3.0.2+2/src/extract_gpuinfo.c     2023-06-15 11:47:30.000000000 
+0200
@@ -154,11 +154,9 @@
     if (!GPUINFO_DYNAMIC_FIELD_VALID(dynamic_info, gpu_util_rate) && 
validReportedGpuRate) {
       SET_GPUINFO_DYNAMIC(dynamic_info, gpu_util_rate, reportedGpuRate);
     } else if (GPUINFO_DYNAMIC_FIELD_VALID(dynamic_info, gpu_util_rate) && 
validReportedGpuRate) {
-      // Reinstate the driver reported usage if within reasonable margin of 
processes usage
-      if (!(/*more than 10% lower*/ reportedGpuRate < 
dynamic_info->gpu_util_rate - 10 ||
-            /*more than 10% greater*/ reportedGpuRate > 
dynamic_info->gpu_util_rate + 10)) {
-        SET_GPUINFO_DYNAMIC(dynamic_info, gpu_util_rate, reportedGpuRate);
-      }
+      SET_GPUINFO_DYNAMIC(
+          dynamic_info, gpu_util_rate,
+          (dynamic_info->gpu_util_rate > reportedGpuRate ? 
dynamic_info->gpu_util_rate : reportedGpuRate));
     }
   }
   return true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/extract_gpuinfo_amdgpu.c 
new/nvtop-3.0.2+2/src/extract_gpuinfo_amdgpu.c
--- old/nvtop-3.0.1+29/src/extract_gpuinfo_amdgpu.c     2023-02-25 
12:30:33.000000000 +0100
+++ new/nvtop-3.0.2+2/src/extract_gpuinfo_amdgpu.c      2023-06-15 
11:47:30.000000000 +0200
@@ -53,7 +53,7 @@
 #include <xf86drm.h>
 
 // extern
-const char * amdgpu_parse_marketing_name(struct amdgpu_gpu_info *info);
+const char *amdgpu_parse_marketing_name(struct amdgpu_gpu_info *info);
 
 // Local function pointers to DRM interface
 static typeof(drmGetDevices) *_drmGetDevices;
@@ -99,6 +99,7 @@
 struct __attribute__((__packed__)) unique_cache_id {
   unsigned client_id;
   pid_t pid;
+  char *pdev;
 };
 
 struct amdgpu_process_info_cache {
@@ -459,7 +460,7 @@
       gpu_infos[amdgpu_count].fd = fd;
       gpu_infos[amdgpu_count].base.vendor = &gpu_vendor_amdgpu;
 
-      snprintf(gpu_infos[*count].base.pdev, PDEV_LEN - 1, "%04x:%02x:%02x.%d", 
devs[i]->businfo.pci->domain,
+      snprintf(gpu_infos[amdgpu_count].base.pdev, PDEV_LEN - 1, 
"%04x:%02x:%02x.%d", devs[i]->businfo.pci->domain,
                devs[i]->businfo.pci->bus, devs[i]->businfo.pci->dev, 
devs[i]->businfo.pci->func);
       initDeviceSysfsPaths(&gpu_infos[amdgpu_count]);
       list_add_tail(&gpu_infos[amdgpu_count].base.list, devices);
@@ -528,7 +529,7 @@
    * It may take long time for a Linux distribution to get latest GPU info.
    * here a GPU IDS is maintained, which allows to support GPU info faster. */
   if (!name) {
-      name = amdgpu_parse_marketing_name(&info);
+    name = amdgpu_parse_marketing_name(&info);
   }
 
   static_info->device_name[MAX_DEVICE_NAME - 1] = '\0';
@@ -753,6 +754,9 @@
     if (NreadPatterns == 3) {
       received *= maxPayloadSize;
       transmitted *= maxPayloadSize;
+      // Set in KiB
+      received /= 1024;
+      transmitted /= 1024;
       SET_GPUINFO_DYNAMIC(dynamic_info, pcie_rx, received);
       SET_GPUINFO_DYNAMIC(dynamic_info, pcie_tx, transmitted);
     }
@@ -906,7 +910,7 @@
   // busy percentage since the last measurement.
   if (client_id_set) {
     struct amdgpu_process_info_cache *cache_entry;
-    struct unique_cache_id ucid = {.client_id = cid, .pid = process_info->pid};
+    struct unique_cache_id ucid = {.client_id = cid, .pid = process_info->pid, 
.pdev = gpu_info->base.pdev};
     HASH_FIND_CLIENT(gpu_info->last_update_process_cache, &ucid, cache_entry);
     if (cache_entry) {
       uint64_t time_elapsed = 
nvtop_difftime_u64(cache_entry->last_measurement_tstamp, current_time);
@@ -952,6 +956,7 @@
         goto parse_fdinfo_exit;
       cache_entry->client_id.client_id = cid;
       cache_entry->client_id.pid = process_info->pid;
+      cache_entry->client_id.pdev = gpu_info->base.pdev;
     }
 
 #ifndef NDEBUG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/extract_gpuinfo_intel.c 
new/nvtop-3.0.2+2/src/extract_gpuinfo_intel.c
--- old/nvtop-3.0.1+29/src/extract_gpuinfo_intel.c      2023-02-25 
12:30:33.000000000 +0100
+++ new/nvtop-3.0.2+2/src/extract_gpuinfo_intel.c       2023-06-15 
11:47:30.000000000 +0200
@@ -47,6 +47,7 @@
 struct __attribute__((__packed__)) unique_cache_id {
   unsigned client_id;
   pid_t pid;
+  char *pdev;
 };
 
 struct intel_process_info_cache {
@@ -183,7 +184,7 @@
   process_info->type |= gpu_process_graphical;
 
   struct intel_process_info_cache *cache_entry;
-  struct unique_cache_id ucid = {.client_id = cid, .pid = process_info->pid};
+  struct unique_cache_id ucid = {.client_id = cid, .pid = process_info->pid, 
.pdev = gpu_info->base.pdev};
   HASH_FIND_CLIENT(gpu_info->last_update_process_cache, &ucid, cache_entry);
   if (cache_entry) {
     uint64_t time_elapsed = 
nvtop_difftime_u64(cache_entry->last_measurement_tstamp, current_time);
@@ -219,6 +220,7 @@
       goto parse_fdinfo_exit;
     cache_entry->client_id.client_id = cid;
     cache_entry->client_id.pid = process_info->pid;
+    cache_entry->client_id.pdev = gpu_info->base.pdev;
   }
 
 #ifndef NDEBUG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/extract_gpuinfo_msm.c 
new/nvtop-3.0.2+2/src/extract_gpuinfo_msm.c
--- old/nvtop-3.0.1+29/src/extract_gpuinfo_msm.c        1970-01-01 
01:00:00.000000000 +0100
+++ new/nvtop-3.0.2+2/src/extract_gpuinfo_msm.c 2023-06-15 11:47:30.000000000 
+0200
@@ -0,0 +1,523 @@
+/*
+ *
+ * Copyright (C) 2023 Ryan Houdek <[email protected]>
+ *
+ * This file is part of Nvtop and adapted from the amdgpu implementation.
+ *
+ * Nvtop is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Nvtop is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with nvtop.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "nvtop/device_discovery.h"
+#include "nvtop/extract_gpuinfo_common.h"
+#include "nvtop/extract_processinfo_fdinfo.h"
+#include "nvtop/time.h"
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libdrm/msm_drm.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/sysinfo.h>
+#include <unistd.h>
+#include <uthash.h>
+#include <xf86drm.h>
+
+// extern
+const char * msm_parse_marketing_name(uint64_t gpu_id);
+
+#define HASH_FIND_CLIENT(head, key_ptr, out_ptr) HASH_FIND(hh, head, key_ptr, 
sizeof(unsigned), out_ptr)
+#define HASH_ADD_CLIENT(head, in_ptr) HASH_ADD(hh, head, client_id, 
sizeof(unsigned), in_ptr)
+
+#define SET_MSM_CACHE(cachePtr, field, value) SET_VALUE(cachePtr, field, 
value, msm_cache_)
+#define RESET_MSM_CACHE(cachePtr, field) INVALIDATE_VALUE(cachePtr, field, 
msm_cache_)
+#define MSM_CACHE_FIELD_VALID(cachePtr, field) VALUE_IS_VALID(cachePtr, field, 
msm_cache_)
+
+enum intel_process_info_cache_valid {
+  msm_cache_engine_render_valid = 0,
+  msm_cache_process_info_cache_valid_count
+};
+
+struct __attribute__((__packed__)) unique_cache_id {
+  unsigned client_id;
+  pid_t pid;
+};
+
+struct msm_process_info_cache {
+  struct unique_cache_id client_id;
+  uint64_t engine_render;
+  nvtop_time last_measurement_tstamp;
+  unsigned char valid[(msm_cache_process_info_cache_valid_count + CHAR_BIT - 
1) / CHAR_BIT];
+  UT_hash_handle hh;
+};
+
+struct gpu_info_msm {
+  drmVersionPtr drmVersion;
+  struct gpu_info base;
+  int fd;
+
+  struct msm_process_info_cache *last_update_process_cache, 
*current_update_process_cache; // Cached processes info
+};
+
+static bool gpuinfo_msm_init(void);
+static void gpuinfo_msm_shutdown(void);
+static const char *gpuinfo_msm_last_error_string(void);
+static bool gpuinfo_msm_get_device_handles(struct list_head *devices, unsigned 
*count);
+static void gpuinfo_msm_populate_static_info(struct gpu_info *_gpu_info);
+static void gpuinfo_msm_refresh_dynamic_info(struct gpu_info *_gpu_info);
+static void gpuinfo_msm_get_running_processes(struct gpu_info *_gpu_info);
+
+struct gpu_vendor gpu_vendor_msm = {
+    .init = gpuinfo_msm_init,
+    .shutdown = gpuinfo_msm_shutdown,
+    .last_error_string = gpuinfo_msm_last_error_string,
+    .get_device_handles = gpuinfo_msm_get_device_handles,
+    .populate_static_info = gpuinfo_msm_populate_static_info,
+    .refresh_dynamic_info = gpuinfo_msm_refresh_dynamic_info,
+    .refresh_running_processes = gpuinfo_msm_get_running_processes,
+    .name = "msm",
+};
+
+unsigned msm_gpu_count;
+static struct gpu_info_msm *gpu_infos;
+
+static void *libdrm_handle;
+
+static int last_libdrm_return_status = 0;
+static char didnt_call_gpuinfo_init[] = "uninitialized";
+static const char *local_error_string = didnt_call_gpuinfo_init;
+
+// Local function pointers to DRM interface
+static typeof(drmGetDevices) *_drmGetDevices;
+static typeof(drmGetDevices2) *_drmGetDevices2;
+static typeof(drmFreeDevices) *_drmFreeDevices;
+static typeof(drmGetVersion) *_drmGetVersion;
+static typeof(drmFreeVersion) *_drmFreeVersion;
+static typeof(drmGetMagic) *_drmGetMagic;
+static typeof(drmAuthMagic) *_drmAuthMagic;
+static typeof(drmDropMaster) *_drmDropMaster;
+static typeof(drmCommandWriteRead) *_drmCommandWriteRead;
+
+static int wrap_drmGetDevices(drmDevicePtr devices[], int max_devices) {
+  assert(_drmGetDevices2 || _drmGetDevices);
+
+  if (_drmGetDevices2)
+    return _drmGetDevices2(0, devices, max_devices);
+  return _drmGetDevices(devices, max_devices);
+}
+
+static void authenticate_drm(int fd) {
+  drm_magic_t magic;
+
+  if (_drmGetMagic(fd, &magic) < 0) {
+    return;
+  }
+
+  if (_drmAuthMagic(fd, magic) == 0) {
+    if (_drmDropMaster(fd)) {
+      perror("Failed to drop DRM master");
+      fprintf(
+          stderr,
+          "\nWARNING: other DRM clients will crash on VT switch while nvtop is 
running!\npress ENTER to continue\n");
+      fgetc(stdin);
+    }
+    return;
+  }
+
+  // XXX: Ideally I'd implement this too, but I'd need to pull in libxcb and 
yet
+  // more functions and structs that may break ABI compatibility.
+  // See radeontop auth_xcb.c for what is involved here
+  fprintf(stderr, "Failed to authenticate to DRM; XCB authentication 
unimplemented\n");
+}
+
+#define STRINGIFY(x) STRINGIFY_HELPER_(x)
+#define STRINGIFY_HELPER_(x) #x
+
+__attribute__((constructor)) static void init_extract_gpuinfo_msm(void) { 
register_gpu_vendor(&gpu_vendor_msm); }
+
+bool gpuinfo_msm_init(void) {
+  libdrm_handle = dlopen("libdrm.so", RTLD_LAZY);
+  if (!libdrm_handle)
+    libdrm_handle = dlopen("libdrm.so.2", RTLD_LAZY);
+  if (!libdrm_handle)
+    libdrm_handle = dlopen("libdrm.so.1", RTLD_LAZY);
+  if (!libdrm_handle) {
+    local_error_string = dlerror();
+    return false;
+  }
+
+  _drmGetDevices2 = dlsym(libdrm_handle, "drmGetDevices2");
+  if (!_drmGetDevices2)
+    _drmGetDevices = dlsym(libdrm_handle, "drmGetDevices");
+  if (!_drmGetDevices2 && !_drmGetDevices)
+    goto init_error_clean_exit;
+
+  _drmFreeDevices = dlsym(libdrm_handle, "drmFreeDevices");
+  if (!_drmFreeDevices)
+    goto init_error_clean_exit;
+
+  _drmGetVersion = dlsym(libdrm_handle, "drmGetVersion");
+  if (!_drmGetVersion)
+    goto init_error_clean_exit;
+
+  _drmFreeVersion = dlsym(libdrm_handle, "drmFreeVersion");
+  if (!_drmFreeVersion)
+    goto init_error_clean_exit;
+
+  _drmGetMagic = dlsym(libdrm_handle, "drmGetMagic");
+  if (!_drmGetMagic)
+    goto init_error_clean_exit;
+
+  _drmAuthMagic = dlsym(libdrm_handle, "drmAuthMagic");
+  if (!_drmAuthMagic)
+    goto init_error_clean_exit;
+
+  _drmDropMaster = dlsym(libdrm_handle, "drmDropMaster");
+  if (!_drmDropMaster)
+    goto init_error_clean_exit;
+
+  _drmCommandWriteRead = dlsym(libdrm_handle, "drmCommandWriteRead");
+  if (!_drmCommandWriteRead)
+    goto init_error_clean_exit;
+
+  local_error_string = NULL;
+  return true;
+
+init_error_clean_exit:
+  dlclose(libdrm_handle);
+  libdrm_handle = NULL;
+  return false;
+}
+
+void gpuinfo_msm_shutdown(void) {
+  for (unsigned i = 0; i < msm_gpu_count; ++i) {
+    struct gpu_info_msm *current = &gpu_infos[i];
+    _drmFreeVersion(current->drmVersion);
+  }
+
+  free(gpu_infos);
+  gpu_infos = NULL;
+  msm_gpu_count = 0;
+
+  if (libdrm_handle) {
+    dlclose(libdrm_handle);
+    libdrm_handle = NULL;
+    local_error_string = didnt_call_gpuinfo_init;
+  }
+}
+
+static const char *gpuinfo_msm_last_error_string(void) {
+  if (local_error_string) {
+    return local_error_string;
+  } else if (last_libdrm_return_status < 0) {
+    switch (last_libdrm_return_status) {
+    case DRM_ERR_NO_DEVICE:
+      return "no device\n";
+    case DRM_ERR_NO_ACCESS:
+      return "no access\n";
+    case DRM_ERR_NOT_ROOT:
+      return "not root\n";
+    case DRM_ERR_INVALID:
+      return "invalid args\n";
+    case DRM_ERR_NO_FD:
+      return "no fd\n";
+    default:
+      return "unknown error\n";
+    }
+  } else {
+    return "An unanticipated error occurred while accessing AMDGPU "
+           "information\n";
+  }
+}
+
+static const char drm_msm_engine_gpu[] = "drm-engine-gpu";
+static const char drm_msm_cycles_gpu[] = "drm-cycles-gpu";
+static const char drm_msm_maxfreq_gpu[] = "drm-maxfreq-gpu";
+static const char drm_msm_resident_mem[] = "drm-resident-memory";
+
+static bool parse_drm_fdinfo_msm(struct gpu_info *info, FILE *fdinfo_file, 
struct gpu_process *process_info) {
+  struct gpu_info_msm *gpu_info = container_of(info, struct gpu_info_msm, 
base);
+  static char *line = NULL;
+  static size_t line_buf_size = 0;
+  ssize_t count = 0;
+
+  bool client_id_set = false;
+  unsigned cid;
+  nvtop_time current_time;
+  nvtop_get_current_time(&current_time);
+
+  while ((count = getline(&line, &line_buf_size, fdinfo_file)) != -1) {
+    char *key, *val;
+    // Get rid of the newline if present
+    if (line[count - 1] == '\n') {
+      line[--count] = '\0';
+    }
+
+    if (!extract_drm_fdinfo_key_value(line, &key, &val))
+      continue;
+
+    if (!strcmp(key, drm_client_id)) {
+      char *endptr;
+      cid = strtoul(val, &endptr, 10);
+      if (*endptr)
+        continue;
+      client_id_set = true;
+    } else {
+      bool is_engine = !strcmp(key, drm_msm_engine_gpu);
+      bool is_cycles = !strcmp(key, drm_msm_cycles_gpu);
+      bool is_maxfreq = !strcmp(key, drm_msm_maxfreq_gpu);
+      bool is_resident = !strcmp(key, drm_msm_resident_mem);
+
+      if (is_engine || is_cycles || is_maxfreq) {
+        char *endptr;
+        uint64_t time_spent = strtoull(val, &endptr, 10);
+        if (endptr == val || strcmp(endptr, " ns"))
+          continue;
+        if (is_engine) {
+          SET_GPUINFO_PROCESS(process_info, gfx_engine_used, time_spent);
+        }
+      }
+      else if (is_resident) {
+        uint64_t mem_int;
+        char *endptr;
+
+        mem_int = strtoull(val, &endptr, 10);
+        if (endptr == val)
+          continue;
+
+        uint64_t multiplier = 1;
+        if (strcmp(endptr, " B") == 0) {
+          multiplier = 1;
+        }
+        else if (strcmp(endptr, " KiB") == 0) {
+          multiplier = 1024;
+        }
+        else if (strcmp(endptr, " MiB") == 0) {
+          multiplier = 1024 * 1024;
+        }
+        else if (strcmp(endptr, " GiB") == 0) {
+          multiplier = 1024 * 1024 * 1024;
+        }
+
+        SET_GPUINFO_PROCESS(process_info, gpu_memory_usage, mem_int * 
multiplier);
+      }
+    }
+  }
+  if (!client_id_set)
+    return false;
+
+  // The msm driver does not expose compute engine metrics as of yet
+  process_info->type |= gpu_process_graphical;
+
+  struct msm_process_info_cache *cache_entry;
+  struct unique_cache_id ucid = {.client_id = cid, .pid = process_info->pid};
+  HASH_FIND_CLIENT(gpu_info->last_update_process_cache, &ucid, cache_entry);
+  if (cache_entry) {
+    uint64_t time_elapsed = 
nvtop_difftime_u64(cache_entry->last_measurement_tstamp, current_time);
+    HASH_DEL(gpu_info->last_update_process_cache, cache_entry);
+    if (GPUINFO_PROCESS_FIELD_VALID(process_info, gfx_engine_used) &&
+        MSM_CACHE_FIELD_VALID(cache_entry, engine_render) &&
+        // In some rare occasions, the gfx engine usage reported by the driver 
is lowering (might be a driver bug)
+        process_info->gfx_engine_used >= cache_entry->engine_render &&
+        process_info->gfx_engine_used - cache_entry->engine_render <= 
time_elapsed) {
+      SET_GPUINFO_PROCESS(
+          process_info, gpu_usage,
+          busy_usage_from_time_usage_round(process_info->gfx_engine_used, 
cache_entry->engine_render, time_elapsed));
+    }
+  } else {
+    cache_entry = calloc(1, sizeof(*cache_entry));
+    if (!cache_entry)
+      goto parse_fdinfo_exit;
+    cache_entry->client_id.client_id = cid;
+    cache_entry->client_id.pid = process_info->pid;
+  }
+
+#ifndef NDEBUG
+  // We should only process one fdinfo entry per client id per update
+  struct msm_process_info_cache *cache_entry_check;
+  HASH_FIND_CLIENT(gpu_info->current_update_process_cache, &cid, 
cache_entry_check);
+  assert(!cache_entry_check && "We should not be processing a client id twice 
per update");
+#endif
+
+  RESET_ALL(cache_entry->valid);
+  if (GPUINFO_PROCESS_FIELD_VALID(process_info, gfx_engine_used))
+    SET_MSM_CACHE(cache_entry, engine_render, process_info->gfx_engine_used);
+
+  cache_entry->last_measurement_tstamp = current_time;
+  HASH_ADD_CLIENT(gpu_info->current_update_process_cache, cache_entry);
+
+parse_fdinfo_exit:
+  return true;
+}
+
+static bool gpuinfo_msm_get_device_handles(struct list_head *devices, unsigned 
*count) {
+  if (!libdrm_handle)
+    return false;
+
+  last_libdrm_return_status = wrap_drmGetDevices(NULL, 0);
+  if (last_libdrm_return_status <= 0)
+    return false;
+
+  drmDevicePtr devs[last_libdrm_return_status];
+  last_libdrm_return_status = wrap_drmGetDevices(devs, 
last_libdrm_return_status);
+  if (last_libdrm_return_status <= 0)
+    return false;
+
+  unsigned int libdrm_count = last_libdrm_return_status;
+  gpu_infos = calloc(libdrm_count, sizeof(*gpu_infos));
+  if (!gpu_infos) {
+    local_error_string = strerror(errno);
+    return false;
+  }
+
+  for (unsigned int i = 0; i < libdrm_count; i++) {
+    int fd = -1;
+
+    // Try render node first
+    if (1 << DRM_NODE_RENDER & devs[i]->available_nodes) {
+      fd = open(devs[i]->nodes[DRM_NODE_RENDER], O_RDWR);
+    }
+    if (fd < 0) {
+      // Fallback to primary node (control nodes are unused according to the 
DRM documentation)
+      if (1 << DRM_NODE_PRIMARY & devs[i]->available_nodes) {
+        fd = open(devs[i]->nodes[DRM_NODE_PRIMARY], O_RDWR);
+      }
+    }
+
+    if (fd < 0)
+      continue;
+
+    drmVersionPtr ver = _drmGetVersion(fd);
+
+    if (!ver) {
+      close(fd);
+      continue;
+    }
+
+    bool is_msm = !strcmp(ver->name, "msm");
+
+    if (!is_msm) {
+      _drmFreeVersion(ver);
+      close(fd);
+      continue;
+    }
+
+    authenticate_drm(fd);
+
+    gpu_infos[msm_gpu_count].drmVersion = ver;
+    gpu_infos[msm_gpu_count].fd = fd;
+    gpu_infos[msm_gpu_count].base.vendor = &gpu_vendor_msm;
+
+    list_add_tail(&gpu_infos[msm_gpu_count].base.list, devices);
+    // Register a fdinfo callback for this GPU
+    processinfo_register_fdinfo_callback(parse_drm_fdinfo_msm, 
&gpu_infos[msm_gpu_count].base);
+    msm_gpu_count++;
+  }
+
+  _drmFreeDevices(devs, libdrm_count);
+  *count = msm_gpu_count;
+
+  return true;
+}
+
+static int gpuinfo_msm_query_param(int gpu, uint32_t param, uint64_t *value) {
+  struct drm_msm_param req = {
+    .pipe = MSM_PIPE_3D0, // Only the 3D pipe.
+    .param = param,
+  };
+
+  int ret = _drmCommandWriteRead(gpu, DRM_MSM_GET_PARAM, &req, sizeof(req));
+
+  if (ret)
+    return ret;
+
+  *value = req.value;
+
+  return 0;
+}
+
+void gpuinfo_msm_populate_static_info(struct gpu_info *_gpu_info) {
+  struct gpu_info_msm *gpu_info = container_of(_gpu_info, struct gpu_info_msm, 
base);
+  struct gpuinfo_static_info *static_info = &gpu_info->base.static_info;
+  const char *dev_name;
+
+  static_info->integrated_graphics = true;
+  RESET_ALL(static_info->valid);
+
+  uint64_t gpuid;
+  if (gpuinfo_msm_query_param(gpu_info->fd, MSM_PARAM_CHIP_ID, &gpuid) == 0) {
+    const char* name = msm_parse_marketing_name(gpuid);
+    if (name) {
+      strncpy(static_info->device_name, name, 
sizeof(static_info->device_name));
+    }
+    else {
+      snprintf(static_info->device_name, sizeof(static_info->device_name), 
"Unknown Adreno %lx", gpuid);
+    }
+    SET_VALID(gpuinfo_device_name_valid, static_info->valid);
+  }
+}
+
+void gpuinfo_msm_refresh_dynamic_info(struct gpu_info *_gpu_info) {
+  struct gpu_info_msm *gpu_info = container_of(_gpu_info, struct gpu_info_msm, 
base);
+  struct gpuinfo_static_info *static_info = &gpu_info->base.static_info;
+  struct gpuinfo_dynamic_info *dynamic_info = &gpu_info->base.dynamic_info;
+
+  RESET_ALL(dynamic_info->valid);
+  dynamic_info->encode_decode_shared = true;
+
+  // GPU clock
+  uint64_t val;
+  if (gpuinfo_msm_query_param(gpu_info->fd, MSM_PARAM_MAX_FREQ, &val) == 0) {
+    // TODO: No way to query current clock speed.
+    SET_GPUINFO_DYNAMIC(dynamic_info, gpu_clock_speed, val / 1000000);
+    SET_GPUINFO_DYNAMIC(dynamic_info, gpu_clock_speed_max, val / 1000000);
+  }
+
+  // Mem clock
+  // TODO: No way to query.
+
+  // TODO: find how to extract global utilization
+  // gpu util will be computed as the sum of all the processes utilization for 
now
+
+  struct sysinfo info;
+  if (sysinfo(&info) == 0) {
+    SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, info.totalram);
+    SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, info.totalram - 
info.freeram);
+    SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, info.freeram);
+    SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate,
+                        (dynamic_info->total_memory - 
dynamic_info->free_memory) * 100 / dynamic_info->total_memory);
+  }
+}
+
+static void swap_process_cache_for_next_update(struct gpu_info_msm *gpu_info) {
+  // Free old cache data and set the cache for the next update
+  if (gpu_info->last_update_process_cache) {
+    struct msm_process_info_cache *cache_entry, *tmp;
+    HASH_ITER(hh, gpu_info->last_update_process_cache, cache_entry, tmp) {
+      HASH_DEL(gpu_info->last_update_process_cache, cache_entry);
+      free(cache_entry);
+    }
+  }
+  gpu_info->last_update_process_cache = gpu_info->current_update_process_cache;
+  gpu_info->current_update_process_cache = NULL;
+}
+
+void gpuinfo_msm_get_running_processes(struct gpu_info *_gpu_info) {
+  // For Adreno, we register a fdinfo callback that will fill the gpu_process 
datastructure of the gpu_info structure
+  // for us. This avoids going through /proc multiple times per update for 
multiple GPUs.
+  struct gpu_info_msm *gpu_info = container_of(_gpu_info, struct gpu_info_msm, 
base);
+  swap_process_cache_for_next_update(gpu_info);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/extract_gpuinfo_msm_utils.c 
new/nvtop-3.0.2+2/src/extract_gpuinfo_msm_utils.c
--- old/nvtop-3.0.1+29/src/extract_gpuinfo_msm_utils.c  1970-01-01 
01:00:00.000000000 +0100
+++ new/nvtop-3.0.2+2/src/extract_gpuinfo_msm_utils.c   2023-06-15 
11:47:30.000000000 +0200
@@ -0,0 +1,96 @@
+/*
+ *
+ * Copyright (C) 2023 Ryan Houdek <[email protected]>
+ *
+ * Nvtop is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Nvtop is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with nvtop.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "nvtop/interface_internal_common.h"
+#include <stdint.h>
+
+struct msm_id_struct {
+  uint64_t id;
+  const char *name;
+};
+
+#define GetHundredDigit(coreid) (coreid / 100)
+#define GetHundred(coreid) (GetHundredDigit(coreid) * 100)
+#define GetTenDigit(coreid) ((coreid - GetHundred(coreid)) / 10)
+#define GetTen(coreid) (GetTenDigit(coreid) * 10)
+#define GetOneDigit(coreid) (coreid - (GetHundred(coreid) + GetTen(coreid)))
+
+#define CHIPID(coreid) \
+  (GetHundredDigit(coreid) << 24) | \
+  (GetTenDigit(coreid) << 16) | \
+  (GetOneDigit(coreid) << 8)
+
+static const struct msm_id_struct msm_ids[] = {
+  // Adreno 2xx
+  {CHIPID(200),   "Adreno 200"},
+  {CHIPID(201),   "Adreno 201"},
+  {CHIPID(205),   "Adreno 205"},
+  {CHIPID(220),   "Adreno 220"},
+
+  // Adreno 3xx
+  {CHIPID(305),   "Adreno 305"},
+  {CHIPID(307),   "Adreno 307"},
+  {CHIPID(320),   "Adreno 320"},
+  {CHIPID(330),   "Adreno 330"},
+
+  // Adreno 4xx
+  {CHIPID(405),   "Adreno 405"},
+  {CHIPID(420),   "Adreno 420"},
+  {CHIPID(430),   "Adreno 430"},
+
+  // Adreno 5xx
+  {CHIPID(508),   "Adreno 508"},
+  {CHIPID(509),   "Adreno 509"},
+  {CHIPID(510),   "Adreno 510"},
+  {CHIPID(512),   "Adreno 512"},
+  {CHIPID(530),   "Adreno 530"},
+  {CHIPID(540),   "Adreno 540"},
+
+  // Adreno 6xx
+  {CHIPID(615),   "Adreno 615"},
+  {CHIPID(616),   "Adreno 616"},
+  {CHIPID(618),   "Adreno 618"},
+  {CHIPID(619),   "Adreno 619"},
+  {CHIPID(620),   "Adreno 620"},
+  {CHIPID(630),   "Adreno 630"},
+  {CHIPID(640),   "Adreno 640"},
+  {CHIPID(650),   "Adreno 650"},
+  {CHIPID(660),   "Adreno 660"},
+  {CHIPID(680),   "Adreno 680"},
+  {CHIPID(690),   "Adreno 690"},
+
+  // Adreno 7xx
+  {CHIPID(730),   "Adreno 730"},
+  {CHIPID(740),   "Adreno 740"},
+
+  // Misc
+  {0x00be06030500, "Adreno 8c Gen 3"},
+  {0x007506030500, "Adreno 7c+ Gen 3"},
+  {0x006006030500, "Adreno 7c+ Gen 3 Lite"},
+};
+
+const char * msm_parse_marketing_name(uint64_t gpu_id) {
+  for (unsigned i = 0; i < ARRAY_SIZE(msm_ids); i++) {
+    if (gpu_id == msm_ids[i].id) {
+      return msm_ids[i].name;
+    }
+  }
+
+  return NULL;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/extract_processinfo_fdinfo.c 
new/nvtop-3.0.2+2/src/extract_processinfo_fdinfo.c
--- old/nvtop-3.0.1+29/src/extract_processinfo_fdinfo.c 2023-02-25 
12:30:33.000000000 +0100
+++ new/nvtop-3.0.2+2/src/extract_processinfo_fdinfo.c  2023-06-15 
11:47:30.000000000 +0200
@@ -25,13 +25,16 @@
 #include <ctype.h>
 #include <dirent.h>
 #include <fcntl.h>
-#include <linux/kcmp.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <sys/sysmacros.h>
 #include <unistd.h>
 
+#ifndef KCMP_FILE
+#define KCMP_FILE 0
+#endif
+
 struct callback_entry {
   struct gpu_info *gpu_info;
   processinfo_fdinfo_callback callback;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nvtop-3.0.1+29/src/info_messages_linux.c 
new/nvtop-3.0.2+2/src/info_messages_linux.c
--- old/nvtop-3.0.1+29/src/info_messages_linux.c        2023-02-25 
12:30:33.000000000 +0100
+++ new/nvtop-3.0.2+2/src/info_messages_linux.c 2023-06-15 11:47:30.000000000 
+0200
@@ -41,6 +41,7 @@
     "Nvtop won't be able to show AMD GPU processes on your kernel version 
(requires Linux >= 5.14)",
     "Nvtop won't be able to show Intel GPU utilization and processes on your 
kernel version (requires Linux >= 5.19)",
     "This version of Nvtop is missing support for reporting Intel GPU memory, 
power, fan and temperature",
+    "This version of Nvtop is missing support for reporting MSM power, fan and 
temperature",
 };
 static const char *message_array[sizeof(allMessages) / sizeof(*allMessages)];
 
@@ -52,12 +53,16 @@
 
   *messages = message_array;
   bool hasIntel = false;
+  bool hasMSM = false;
   bool hasAMD = false;
   struct gpu_info *gpuinfo;
   list_for_each_entry(gpuinfo, devices, list) {
     if (strcmp(gpuinfo->vendor->name, "Intel") == 0) {
       hasIntel = true;
     }
+    if (strcmp(gpuinfo->vendor->name, "msm") == 0) {
+      hasMSM = true;
+    }
     if (strcmp(gpuinfo->vendor->name, "AMD") == 0) {
       hasAMD = true;
     }
@@ -73,4 +78,7 @@
     }
     message_array[(*num_messages)++] = allMessages[2];
   }
-}
\ No newline at end of file
+  if (hasMSM) {
+    message_array[(*num_messages)++] = allMessages[3];
+  }
+}

++++++ nvtop.obsinfo ++++++
--- /var/tmp/diff_new_pack.OKosug/_old  2023-06-22 23:27:52.274395477 +0200
+++ /var/tmp/diff_new_pack.OKosug/_new  2023-06-22 23:27:52.278395497 +0200
@@ -1,5 +1,5 @@
 name: nvtop
-version: 3.0.1+29
-mtime: 1677324633
-commit: d3dddbdeb16e0d5982414829a03383df93b6a4b1
+version: 3.0.2+2
+mtime: 1686822450
+commit: 9a8458b541a195a0c5cadafb66e240962c852b39
 

Reply via email to