Могу ли я увидеть объем памяти, который выделяется как буферы драгоценного камня?

Подобный awk one liner:

awk -F"," 'FNR==NR{var[$2]=$1;next;}{print var[$1]FS$2}'  file1 file2

Вывод:

$ awk -F"," 'FNR==NR{var[$2]=$1;next;}{print var[$1]FS$2}'  file1.txt file2.txt
6,2.3
3,4.5
4,6.7
5,3.2
2
10.02.2019, 16:39
2 ответа

Изменить :интерфейс предназначен только для целей отладки ядра. Он доступен только через rootи не является стабильным. Он может быть переписан, переименован и/или вводить в заблуждение, если вы не являетесь разработчиком ядра. (Насколько я знаю, он может даже глючить ). Но если у вас есть проблема, может быть полезно знать, что она существует.

Мой водитель i915дает мне информацию здесь:

$ sudo sh -c 'cat /sys/kernel/debug/dri/*/i915_gem_objects'
643 objects, 205852672 bytes
75 unbound objects, 7811072 bytes
568 bound objects, 198041600 bytes
16 purgeable objects, 5750784 bytes
16 mapped objects, 606208 bytes
13 huge-paged objects (2M, 4K) 123764736 bytes
13 display objects (globally pinned), 14954496 bytes
4294967296 [0x0000000010000000] gtt total
Supported page sizes: 2M, 4K

[k]contexts: 16 objects, 548864 bytes (0 active, 548864 inactive, 548864 global, 0 shared, 0 unbound)
systemd-logind: 324 objects, 97374208 bytes (0 active, 115798016 inactive, 23941120 global, 5246976 shared, 3858432 unbound)
Xwayland: 24 objects, 6995968 bytes (0 active, 12169216 inactive, 5283840 global, 5246976 shared, 110592 unbound)
gnome-shell: 246 objects, 89739264 bytes (26517504 active, 120852480 inactive, 63016960 global, 5242880 shared, 3629056 unbound)
Xwayland: 25 objects, 17309696 bytes (0 active, 22503424 inactive, 5304320 global, 5242880 shared, 90112 unbound)

Опять же, проявляйте осторожность. Я заметил, что mapped objectsпоказывает только 600 КБ. Я предполагаю, что mappedздесь означает нечто иное, чем я ожидал. Для сравнения, запустив приведенный ниже скрипт Python, чтобы показать объекты i915, сопоставленные с адресными пространствами пользовательского процесса, я вижу в общей сложности 70 МБ.

Строка для systemd-logindв моем выводе представляет второй экземпляр gnome-shell, работающий на другой виртуальной консоли. Если я переключусь на виртуальную консоль, на которой вместо этого запущен текстовый вход в систему, то в этом файле будут показаны две строки systemd-logindи ни одной строки gnome-shell:-).


В противном случае лучшее, что вы можете сделать, это найти некоторые файлы shmem, просмотрев все открытые файлы в /proc/*/fd/и/proc/*/map_files/(или/proc/*/maps).

С помощью правильных хаков можно надежно определить, какие файлы принадлежат скрытой файловой системе shmem (s ).

Каждый объект общей памяти представляет собой файл с именем. А имена можно использовать для определения того, какая подсистема ядра создала файл.

Проблема в том, что , а не показывает все распределения DRM/GEM. Буферы DRM могут существовать без отображения, просто как числовой дескриптор. Они привязаны к открытому файлу DRM, в котором они были созданы. Когда программа аварийно завершает работу или уничтожается, файл DRM будет закрыт, и все его дескрипторы DRM будут автоматически очищены. (Если какое-то другое программное обеспечение не хранит копию файлового дескриптора открытой, как эта старая ошибка .)

https://www.systutorials.com/docs/linux/man/7-drm-gem/

Вы можете найти открытые файлы DRM в /proc/*/fd/, но они отображаются как файл нулевого размера -с нулевым выделенным блоком.

Например, приведенный ниже вывод показывает систему, в которой я не могу учесть более 50% / 300 МБ от Shmem.

$ grep Shmem: /proc/meminfo
Shmem:            612732 kB

$ df -h -t tmpfs
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           3.9G   59M  3.8G   2% /dev/shm
tmpfs           3.9G  2.5M  3.9G   1% /run
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs           3.9G  9.0M  3.9G   1% /tmp
tmpfs           786M   20K  786M   1% /run/user/42
tmpfs           786M  8.0M  778M   2% /run/user/1000
tmpfs           786M  5.7M  781M   1% /run/user/1001

$ sudo ipcs -mu

------ Shared Memory Status --------
segments allocated 20
pages allocated 4226
pages resident  3990
pages swapped   0
Swap performance: 0 attempts     0 successes  

Все открытые файлы в скрытой файловой системе shmem (s):

$ sudo python3 ~/shm -s
15960   /SYSV*
79140   /i915
7912    /memfd:gdk-wayland
1164    /memfd:pulseaudio
104176

Вот «до и после» выхода из системы одного из двух моих пользователей, вошедших -в GNOME. Это можно было бы объяснить, если бы gnome-shellимел более 100 МБ неотображенных буферов DRM.

$ grep Shmem: /proc/meminfo
Shmem:            478780 kB
$ df -t tmpfs -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           3.9G  4.0K  3.9G   1% /dev/shm
tmpfs           3.9G  2.5M  3.9G   1% /run
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs           3.9G  276K  3.9G   1% /tmp
tmpfs           786M   20K  786M   1% /run/user/42
tmpfs           786M  8.0M  778M   2% /run/user/1000
tmpfs           786M  5.7M  781M   1% /run/user/1001
$ sudo./shm -s
80  /SYSV*
114716  /i915
1692    /memfd:gdk-wayland
1156    /memfd:pulseaudio
117644

$ grep Shmem: /proc/meminfo
Shmem:            313008 kB
$ df -t tmpfs -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           3.9G  4.0K  3.9G   1% /dev/shm
tmpfs           3.9G  2.1M  3.9G   1% /run
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs           3.9G  204K  3.9G   1% /tmp
tmpfs           786M   20K  786M   1% /run/user/42
tmpfs           786M  6.8M  780M   1% /run/user/1000
$ sudo./shm -s
40  /SYSV*
88496   /i915
1692    /memfd:gdk-wayland
624 /memfd:pulseaudio
90852

Сценарий Python для создания указанного выше вывода:

#!/bin/python3
# Reads Linux /proc.  No str, all bytes.

import sys
import os
import stat
import glob
import collections
import math

# File.
# 'name' is first name encountered, we don't track hardlinks.
Inode = collections.namedtuple('Inode', ['name', 'bytes', 'pids'])

# inode number -> Inode object
inodes = dict()
# pid -> program name
pids = dict()
# filename -> list() of Inodes
filenames = dict()

def add_file(pid, proclink):
    try:
        vfs = os.statvfs(proclink)

        # The tmpfs which reports 0 blocks is an internal shm mount
        # python doesn't admit f_fsid...
        if vfs.f_blocks != 0:
            return
        filename = os.readlink(proclink)
        #... but all the shm files are deleted (hack :)
        if not filename.endswith(b' (deleted)'):
            return
        filename = filename[:-10]
        # I tried a consistency check that all our st_dev are the same
        # but actually there can be more than one internal shm mount!
        # i915 added a dedicated "gemfs" so they could control mount options.

        st = os.stat(proclink)

        # hack the second: ignore deleted character devices from devpts
        if stat.S_ISCHR(st.st_mode):
            return

        # Read process name succesfully,
        # before we record file owned by process.
        if pid not in pids:
            pids[pid] = open(b'/proc/' + pid + b'/comm', 'rb').read()[:-1]

        if st.st_ino not in inodes:
            inode_pids = set()
            inode_pids.add(pid)

            inode = Inode(name=filename,
                          bytes=st.st_blocks * 512,
                          pids=inode_pids)
            inodes[st.st_ino] = inode
        else:
            inode = inodes[st.st_ino]
            inode.pids.add(pid)

        # Group SYSV shared memory objects.
        # There could be many, and the rest of the name is just a numeric ID
        if filename.startswith(b'/SYSV'):
            filename = b'/SYSV*'

        filename_inodes = filenames.setdefault(filename, set())
        filename_inodes.add(st.st_ino)

    except FileNotFoundError:
        # File disappeared (race condition).
        # Don't bother to distinguish "file closed" from "process exited".
        pass

summary = False
if sys.argv[1:]:
    if sys.argv[1:] == ['-s']:
        summary = True
    else:
        print("Usage: {0} [-s]".format(sys.argv[0]))
        sys.exit(2)

os.chdir(b'/proc')
for pid in glob.iglob(b'[0-9]*'):
    for f in glob.iglob(pid + b'/fd/*'):
        add_file(pid, f)
    for f in glob.iglob(pid + b'/map_files/*'):
        add_file(pid, f)

def pid_name(pid):
    return pid + b'/' + pids[pid]

def kB(b):
    return str(math.ceil(b / 1024)).encode('US-ASCII')

out = sys.stdout.buffer

total = 0
for (filename, filename_inodes) in sorted(filenames.items(), key=lambda p: p[0]):
    filename_bytes = 0
    for ino in filename_inodes:
        inode = inodes[ino]
        filename_bytes += inode.bytes
        if not summary:
            out.write(kB(inode.bytes))
            out.write(b'\t')
            #out.write(str(ino).encode('US-ASCII'))
            #out.write(b'\t')            
            out.write(inode.name)
            out.write(b'\t')
            out.write(b' '.join(map(pid_name, inode.pids)))
            out.write(b'\n')
    total += filename_bytes
    out.write(kB(filename_bytes))
    out.write(b'\t')
    out.write(filename)
    out.write(b'\n')
out.write(kB(total))
out.write(b'\n')
0
27.01.2020, 22:17

Они отображаются на картах процессов как «drm mm object» или «i915» .Вы можете увидеть это в /proc/<pid>/maps; учитывая PID процесса, использующего GEM/DRM:

awk '/(drm mm object)|i915/ { hypidx = index($1, "-"); from = substr($1, 1, hypidx - 1); to = substr($1, hypidx + 1); sum += strtonum("0x" to) - strtonum("0x" from) } END { print sum }' /proc/${PID}/maps

покажет общий размер выделенных буферов GEM. Вычисление общего количества может быть выполнено путем ввода всех карт, содержащих хотя бы одно вхождение «drm mm object» или «i915»; как корень:

find /proc -maxdepth 2 -name maps |
xargs grep -E -l "(drm mm object)|i915" |
xargs awk '/(drm mm object)|i915/ { hypidx = index($1, "-"); sum += strtonum("0x" substr($1, hypidx + 1)) - strtonum("0x" substr($1, 1, hypidx - 1)) } END { print sum }'

(-maxdepth 2необходимо, чтобы не смотреть на карты потоков ). Может потребоваться некоторое дополнительное дублирование inode -на основе de -.

2
27.01.2020, 22:17

Теги

Похожие вопросы