Skip to contentSkip to conversation

pidmap(2)

PATCH In review Alexey Dobriyan 7 participants 12 messages Sep 5, 2017 – Sep 7, 2017

Subsystems (5)
x86 VFS Kselftest ABI/API +1 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 pidmap(2)

From: Tatsiana Brouka <[email protected]>

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread + converting with atoi().

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

Sample program:

#include <stdio.h>
static inline long sys_pidmap(int *pid, unsigned int n, int start)

{
	register long r10 asm ("r10") = 0;
	long rv;
	asm volatile (
		"syscall"
		: "=a" (rv)
		: "0" (333), "D" (pid), "S" (n), "d" (start), "r" (r10)
		: "rcx", "r11", "cc", "memory"
	);
	return rv;
}

int main(void)

{
	int pid[5];
	unsigned int start;
	int n;

	start = 0;
	while ((n = sys_pidmap(pid, sizeof(pid)/sizeof(pid[0]), start)) > 0) {
		int i;

		for (i = 0; i < n; i++) {
			printf(" %u", pid[i]);
		}
		printf("\n");
		start = pid[n - 1] + 1;
	}

	return 0;
}

---

 arch/x86/entry/syscalls/syscall_64.tbl  |    1
 include/linux/syscalls.h                |    4
 kernel/Makefile                         |    2
 kernel/pidmap.c                         |  116 ++++++++++++++
 tools/testing/selftests/Makefile        |    1
 tools/testing/selftests/pidmap/Makefile |    5
 tools/testing/selftests/pidmap/pidmap.c |  263 ++++++++++++++++++++++++++++++++
 7 files changed, 392 insertions(+)
arch/x86/entry/syscalls/syscall_64.tbl +1 -0
@@ -339,6 +339,7 @@
 330	common	pkey_alloc		sys_pkey_alloc
 331	common	pkey_free		sys_pkey_free
 332	common	statx			sys_statx
+333	common	pidmap			sys_pidmap
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
include/linux/syscalls.h +4 -0
@@ -923,4 +923,8 @@ asmlinkage long sys_pkey_free(int pkey);
 asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
 			  unsigned mask, struct statx __user *buffer);
 
+asmlinkage long sys_pidmap(int __user *pids,
+			   unsigned int pids_count,
+			   unsigned int start_pid,
+			   int flags);
 #endif
kernel/Makefile +2 -0
@@ -11,6 +11,8 @@ obj-y     = fork.o exec_domain.o panic.o \
 	    notifier.o ksysfs.o cred.o reboot.o \
 	    async.o range.o smpboot.o ucount.o
 
+obj-y += pidmap.o
+
 obj-$(CONFIG_MULTIUSER) += groups.o
 
 ifdef CONFIG_FUNCTION_TRACER
kernel/pidmap.c new file +116 -0

116 lines not on this page · raw message

tools/testing/selftests/Makefile +1 -0
@@ -20,6 +20,7 @@ TARGETS += mount
 TARGETS += mqueue
 TARGETS += net
 TARGETS += nsfs
+TARGETS += pidmap
 TARGETS += powerpc
 TARGETS += pstore
 TARGETS += ptrace
tools/testing/selftests/pidmap/Makefile new file +5 -0
@@ -0,0 +1,5 @@
+CFLAGS = -Wall
+
+TEST_GEN_PROGS := pidmap
+
+include ../lib.mk
tools/testing/selftests/pidmap/pidmap.c new file +263 -0

263 lines not on this page · raw message

#1 lore raw

PATCH 2/2 fdmap(2)

From: Aliaksandr Patseyenak <[email protected]>

Implement system call for bulk retrieveing of opened descriptors in binary form.

Some daemons could use it to reliably close file descriptors before starting. Currently they close everything upto some number which formally is not reliable. Other natural users are lsof(1) and CRIU (although lsof does so much in /proc that the effect is thoroughly buried).

Once again, /proc, the only way to learn anything about file descriptors may not be available.

Sample program:

#include <stdlib.h>
#include <stdio.h>

static inline long sys_fdmap(int pid, int *fd, unsigned int n, int start)

{
	register long r10 asm ("r10") = start;
	register long r8 asm ("r8") = 0;
	long rv;
	asm volatile (
		"syscall"
		: "=a" (rv)
		: "0" (334), "D" (pid), "S" (fd), "d" (n), "r" (r10), "r" (r8)
		: "rcx", "r11", "cc", "memory"
	);
	return rv;
}

int main(int argc, char *argv[])

{
	int fd[3];
	int pid;
	unsigned int start;
	int n;

	pid = 0;
	if (argc > 1)
		pid = atoi(argv[1]);

	start = 0;
	while ((n = sys_fdmap(pid, fd, sizeof(fd)/sizeof(fd[0]), start)) > 0) {
		unsigned int i;

		for (i = 0; i < n; i++) {
			printf(" %u", fd[i]);
		}
		printf("\n");
		start = fd[n - 1] + 1;
	}

	return 0;
}

---

 arch/x86/entry/syscalls/syscall_64.tbl     |    1 
 fs/Makefile                                |    2 
 fs/fdmap.c                                 |  105 +++++++++++++++++++
 include/linux/syscalls.h                   |    2 
 tools/testing/selftests/fdmap/.gitignore   |    1 
 tools/testing/selftests/fdmap/Makefile     |    7 +
 tools/testing/selftests/fdmap/fdmap.c      |  112 +++++++++++++++++++++
 tools/testing/selftests/fdmap/fdmap.h      |   12 ++
 tools/testing/selftests/fdmap/fdmap_test.c |  153 +++++++++++++++++++++++++++++
 9 files changed, 394 insertions(+), 1 deletion(-)
arch/x86/entry/syscalls/syscall_64.tbl +1 -0
@@ -340,6 +340,7 @@
 331	common	pkey_free		sys_pkey_free
 332	common	statx			sys_statx
 333	common	pidmap			sys_pidmap
+334	common	fdmap			sys_fdmap
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
fs/Makefile +1 -1
@@ -11,7 +11,7 @@ obj-y :=	open.o read_write.o file_table.o super.o \
 		attr.o bad_inode.o file.o filesystems.o namespace.o \
 		seq_file.o xattr.o libfs.o fs-writeback.o \
 		pnode.o splice.o sync.o utimes.o \
-		stack.o fs_struct.o statfs.o fs_pin.o nsfs.o
+		stack.o fs_struct.o statfs.o fs_pin.o nsfs.o fdmap.o
 
 ifeq ($(CONFIG_BLOCK),y)
 obj-y +=	buffer.o block_dev.o direct-io.o mpage.o
fs/fdmap.c new file +105 -0

105 lines not on this page · raw message

include/linux/syscalls.h +2 -0
@@ -922,6 +922,8 @@ asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 asmlinkage long sys_pkey_free(int pkey);
 asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags,
 			  unsigned mask, struct statx __user *buffer);
+asmlinkage long sys_fdmap(pid_t pid, int __user *fds, unsigned int count,
+			  int start_fd, int flags);
 
 asmlinkage long sys_pidmap(int __user *pids,
 			   unsigned int pids_count,
tools/testing/selftests/fdmap/.gitignore new file +1 -0
@@ -0,0 +1 @@
+fdmap_test
tools/testing/selftests/fdmap/Makefile new file +7 -0
@@ -0,0 +1,7 @@
+TEST_GEN_PROGS := fdmap_test
+CFLAGS += -Wall
+
+include ../lib.mk
+
+$(TEST_GEN_PROGS): fdmap_test.c fdmap.c fdmap.h ../kselftest_harness.h
+	$(CC) $(CFLAGS) $(LDFLAGS) $< fdmap.c -o $@
tools/testing/selftests/fdmap/fdmap.c new file +112 -0

112 lines not on this page · raw message

tools/testing/selftests/fdmap/fdmap.h new file +12 -0
@@ -0,0 +1,12 @@
+#ifndef FDMAP_H
+#define FDMAP_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+long fdmap(pid_t pid, int *fds, size_t count, int start_fd, int flags);
+int fdmap_full(pid_t pid, int **fds, size_t *n);
+int fdmap_proc(pid_t pid, int **fds, size_t *n);
+
+#endif
tools/testing/selftests/fdmap/fdmap_test.c new file +153 -0

153 lines not on this page · raw message

#2 lore raw
In reply to Alexey Dobriyan
Quoted 10 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan <[email protected]> wrote:

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread + converting with atoi().

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

The patches are performance optimizations, but their changelogs contain no performance measurements!

Demonstration of some compelling real-world performance benefits would help things along a lot.

#3 lore raw
Quoted 10 lines · Andrew Morton
Quoted 8 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan…

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread + converting with atoi().

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

Quoted 9 lines
Quoted 2 lines

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

The patches are performance optimizations, but their changelogs contain no performance measurements!

Demonstration of some compelling real-world performance benefits would help things along a lot.

also, I expect that the tiny kernel people will want kconfig options for these syscalls.

Signature · 1 line
~Randy
#4 lore raw
Quoted 17 lines · Randy Dunlap
Quoted 16 lines · Andrew Morton
Quoted 10 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan…

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread + converting with atoi().

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

The patches are performance optimizations, but their changelogs contain no performance measurements!

Quoted 6 lines
Quoted 3 lines

Demonstration of some compelling real-world performance benefits would help things along a lot.

also, I expect that the tiny kernel people will want kconfig options for these syscalls.

And of course that stuff wants the corresponding man pages written up.

Thanks,

tglx

#5 lore raw
In reply to Randy Dunlap
Quoted 20 lines · Randy Dunlap
Quoted 19 lines · Andrew Morton
Quoted 6 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan…

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread +
converting with atoi().

Quoted 6 lines

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

The patches are performance optimizations, but their changelogs contain no performance measurements!

Quoted 6 lines
Quoted 3 lines

Demonstration of some compelling real-world performance benefits would help things along a lot.

also, I expect that the tiny kernel people will want kconfig options for these syscalls.

We'll add it but the question if it is a good idea. Ideally these system calls should be mandatory and /proc optional.

$ size kernel/pidmap.o fs/fdmap.o
   text    data     bss     dec     hex filename
    560       0       0     560     230 kernel/pidmap.o
    617       0       0     617     269 fs/fdmap.o
#6 lore raw
Quoted 28 lines · Alexey Dobriyan
Quoted 20 lines · Randy Dunlap
Quoted 19 lines · Andrew Morton
Quoted 6 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan…

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread +
converting with atoi().

Quoted 6 lines

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

The patches are performance optimizations, but their changelogs contain no performance measurements!

Quoted 6 lines
Quoted 3 lines

Demonstration of some compelling real-world performance benefits would help things along a lot.

also, I expect that the tiny kernel people will want kconfig options for these syscalls.

Quoted 7 lines

We'll add it but the question if it is a good idea. Ideally these system calls should be mandatory and /proc optional.

$ size kernel/pidmap.o fs/fdmap.o
   text    data     bss     dec     hex filename
    560       0       0     560     230 kernel/pidmap.o
    617       0       0     617     269 fs/fdmap.o

After much discussion at LPC/KS last year, I thought the idea was to try to speed up /proc rather than replacing it outright. The two specific ideas I recall were:

1. Add a syscall like readfileat() that you can use to, in a single operation, open, read, and close a /proc file (or other file). This should vastly reduce locking and RCU overhead.

2. Add a /proc file that has a nice binary format for task info. (nl_attr?)

I don't see why pidmap() deserves to be significantly faster than getdents().

Also, a pidmap() syscall like this inherently bypasses any security restrictions implied by the way that /proc is mounted. It can respect hidepid, but hidepid (as a per-namespace concept) is an enormous turd that badly needs to be deprecated, and Djalal is working on exactly that.

#7 lore raw

Hi Alexey,

Quoted 3 lines · Andy Lutomirski
Quoted 2 lines · Alexey Dobriyan
Quoted 1 line · Randy Dunlap

On 09/05/17 15:53, Andrew Morton wrote:

[...]

Quoted 22 lines
Quoted 11 lines
Quoted 3 lines

also, I expect that the tiny kernel people will want kconfig options for these syscalls.

We'll add it but the question if it is a good idea. Ideally these system calls should be mandatory and /proc optional.

$ size kernel/pidmap.o fs/fdmap.o
   text    data     bss     dec     hex filename
    560       0       0     560     230 kernel/pidmap.o
    617       0       0     617     269 fs/fdmap.o

After much discussion at LPC/KS last year, I thought the idea was to try to speed up /proc rather than replacing it outright. The two specific ideas I recall were:

1. Add a syscall like readfileat() that you can use to, in a single operation, open, read, and close a /proc file (or other file). This should vastly reduce locking and RCU overhead.

2. Add a /proc file that has a nice binary format for task info. (nl_attr?)

Quoted 7 lines

I don't see why pidmap() deserves to be significantly faster than getdents().

Also, a pidmap() syscall like this inherently bypasses any security restrictions implied by the way that /proc is mounted. It can respect hidepid, but hidepid (as a per-namespace concept) is an enormous turd that badly needs to be deprecated, and Djalal is working on exactly that.

Yes as noted by Andy, me and Alexey Gladkov are working on modernizing procfs [1] and to reduce/remove ties within pid namespaces which has lot of problems now.

We just picked the task again, and this was the result of discussion with Andy some months ago, on how to improve hidepid, but also how to improve procfs in general, so we can add other mechanisms to hide or return NULL on other /proc/_file_not_needed_by_containers_ or /proc/_specific_module_files_ everything that is not virtualized , or mount only some specific view of the whole /proc API this will also be used by containers. This also should make it hard for attackers since we are planning to have a backward compatible options on how to better treat some of these files in regard of some namespaces.

The syscall or readfileat() for one operation is a nice addition definitively. But
in general it would be better to treat /proc as a filesystem and not add other specific interfaces that may abstract it with pidns, as it is the situation now which make it from userspace perspective: hard to use especially for security context.

Alexey, could you please Cc'us on future, thank you very much!

[1] https://lkml.org/lkml/2017/4/25/282

Signature · 1 line
tixxdz
#8 lore raw
Quoted 43 lines · Djalal Harouni

Hi Alexey,

Quoted 4 lines · Andy Lutomirski
Quoted 2 lines · Alexey Dobriyan
Quoted 1 line · Randy Dunlap

On 09/05/17 15:53, Andrew Morton wrote:

[...]

Quoted 25 lines
Quoted 5 lines
Quoted 4 lines

also, I expect that the tiny kernel people will want kconfig options for
these syscalls.

Quoted 8 lines

We'll add it but the question if it is a good idea. Ideally these system calls
should be mandatory and /proc optional.

$ size kernel/pidmap.o fs/fdmap.o
   text    data     bss     dec     hex filename
    560       0       0     560     230 kernel/pidmap.o
    617       0       0     617     269 fs/fdmap.o

After much discussion at LPC/KS last year, I thought the idea was to try to speed up /proc rather than replacing it outright. The two specific ideas I recall were:

1. Add a syscall like readfileat() that you can use to, in a single operation, open, read, and close a /proc file (or other file). This should vastly reduce locking and RCU overhead.

2. Add a /proc file that has a nice binary format for task info. (nl_attr?)

Quoted 8 lines

I don't see why pidmap() deserves to be significantly faster than getdents().

Also, a pidmap() syscall like this inherently bypasses any security restrictions implied by the way that /proc is mounted. It can respect hidepid, but hidepid (as a per-namespace concept) is an enormous turd that badly needs to be deprecated, and Djalal is working on exactly that.

Quoted 4 lines

Yes as noted by Andy, me and Alexey Gladkov are working on modernizing procfs [1] and to reduce/remove ties within pid namespaces which has lot of problems now.
...

Kudos for digging into this mess.
But the question will remain: how get pids of existing processes quickly.

#9 lore raw
In reply to Andy Lutomirski
Quoted 44 lines · Andy Lutomirski
Quoted 29 lines · Alexey Dobriyan
Quoted 21 lines · Randy Dunlap
Quoted 20 lines · Andrew Morton
Quoted 6 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan <[email protected]> wrote:

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread +
converting with atoi().

Quoted 7 lines

/proc may be not mounted especially in containers. Natural extension of
hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

The patches are performance optimizations, but their changelogs contain no performance measurements!

Quoted 6 lines
Quoted 3 lines

Demonstration of some compelling real-world performance benefits would help things along a lot.

also, I expect that the tiny kernel people will want kconfig options for these syscalls.

Quoted 8 lines

We'll add it but the question if it is a good idea. Ideally these system calls
should be mandatory and /proc optional.

$ size kernel/pidmap.o fs/fdmap.o
   text    data     bss     dec     hex filename
    560       0       0     560     230 kernel/pidmap.o
    617       0       0     617     269 fs/fdmap.o

After much discussion at LPC/KS last year, I thought the idea was to try to speed up /proc rather than replacing it outright. The two specific ideas I recall were:

Quoted 6 lines

1. Add a syscall like readfileat() that you can use to, in a single operation, open, read, and close a /proc file (or other file). This should vastly reduce locking and RCU overhead.

2. Add a /proc file that has a nice binary format for task info. (nl_attr?)

If you do binary data in /proc there is no need for /proc part. System call can do everything /proc/$PID/bstat (or whatever the name) does.

Quoted 2 lines

I don't see why pidmap() deserves to be significantly faster than getdents().

Just look at profile. XXX is pure slowdown. _Some_ of it can be deleted or sped up but not everything. All dcache stuff is unavoidable.

XXX 6.35% [k] number
OK* 5.21% [k] proc_readfd_common (* partially XXX)
OK 4.19% [k] __rcu_read_unlock
XXX 4.05% [.] __GI_____strtoll_l_internal
XXX 3.73% [k] dput
OK 3.64% [k] entry_SYSCALL_64_fastpath
XXX 3.23% [k] proc_fill_cache
XXX 3.10% [k] __d_lookup
XXX 3.09% [k] filldir
XXX 2.74% [k] format_decode
XXX 2.47% [k] link_path_walk
OK* 2.26% [k] _raw_spin_lock
OK 1.73% [k] get_files_struct
XXX 1.64% [k] __d_lookup_rcu
XXX 1.61% [k] do_sys_open
XXX 1.49% [k] pid_revalidate
OK 1.48% [k] __check_object_size
XXX 1.47% [k] do_filp_open
? 1.44% [.] __memmove_sse2
OK 1.40% [k] __rcu_read_lock
XXX 1.33% [.] __readdir64
XXX 1.32% [k] __follow_mount_rcu.isra.6
XXX 1.30% [k] set_root
XXX 1.27% [k] lookup_fast
XXX 1.23% [k] full_name_hash
OK? 1.17% [k] call_rcu
XXX 1.17% [k] sys_open
? 1.02% [k] lockref_put_or_lock
XXX 1.00% [k] pid_delete_dentry
XXX 0.99% [k] iterate_dir
XXX 0.95% [k] inode_permission
XXX 0.94% [k] __slab_alloc.isra.22.constprop.26
OK 0.93% [k] rcu_process_callbacks
XXX 0.93% [.] __getdents64
XXX 0.93% [k] vsnprintf
XXX 0.92% [k] sys_close

Quoted 5 lines

Also, a pidmap() syscall like this inherently bypasses any security restrictions implied by the way that /proc is mounted. It can respect hidepid, but hidepid (as a per-namespace concept) is an enormous turd that badly needs to be deprecated, and Djalal is working on exactly that.

I agree pid_ns->hide_pid is silly idea. It should be a property of an individual mount but as posted pidmap() respect it (at a cost of some slowdown).

#10 lore raw
In reply to Andrew Morton
Quoted 16 lines · Andrew Morton
Quoted 6 lines · On Tue, 5 Sep 2017 22:05:00 +0300 Alexey Dobriyan…

Implement system call for bulk retrieveing of pids in binary form.

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread +
converting with atoi().

Quoted 6 lines

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

Quoted 5 lines

The patches are performance optimizations, but their changelogs contain no performance measurements!

Demonstration of some compelling real-world performance benefits would help things along a lot.

I forgot the sheet with numbers at work. :^)
They're very embarrassing for /proc.

pidmap:
N=1<<16 times
~130 processes (~250 task_structs) on a regular desktop system opendir + readdir + closedir /proc + the same for every /proc/$PID/task (roughly what htop(1) does) vs pidmap

/proc 16.80+-0.73%
pidmap 0.06+-0.31%

fdmap:
N=1<<22 times
4 opened descriptors (0, 1, 2, 3) opendir+readdir+closedir /proc/self/fd (lsof(1)) vs fdmap

/proc 8.31+-0.37%
fdmap 0.32+-0.72%

Currently performance improvements may not be huge or even visible. That's because programs like ps/top/lsof _have_ to use /proc to retrieve other information. If combined with bulk taskstats-ish retrieval interfaces they should run around /proc.

#include <sys/types.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>

void f(void)

{
	DIR *d;
	struct dirent *de;

	d = opendir("/proc/");
	while ((de = readdir(d))) {
		if ('1' <= de->d_name[0] && de->d_name[0] <= '9') {
			int pid = atoi(de->d_name);
			char buf[32];
			DIR *dt;
			struct dirent *dte;

			snprintf(buf, sizeof(buf), "/proc/%d/task", pid);
			dt = opendir(buf);
			readdir(dt);
			readdir(dt);
			while ((dte = readdir(dt))) {
				int tid = atoi(dte->d_name);
				asm volatile ("" :: "g" (&tid) : "memory");
			}
			closedir(dt);
		}
	}
	closedir(d);
}

static inline long sys_pidmap(int *pid, unsigned int n, int start)

{
	register long r10 asm ("r10") = 0;
	long rv;
	asm volatile (
		"syscall"
		: "=a" (rv)
		: "0" (333), "D" (pid), "S" (n), "d" (start), "r" (r10)
		: "rcx", "r11", "cc", "memory"
	);
	return rv;
}

void g(void)

{
	int pid[1024];

	sys_pidmap(pid, sizeof(pid)/sizeof(pid[0]), 0);
}

int main(void)

{
	unsigned int i;

// for (i = 0; i < (1<<16); i++)
// f();

	for (i = 0; i < (1<<16); i++)
		g();

	return 0;
}

#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>

void f(void)

{
	DIR *d;
	struct dirent *de;

	d = opendir("/proc/self/fd");
	while ((de = readdir(d))) {
		int fd = atoi(de->d_name);
		asm volatile ("" :: "g" (&fd) : "memory");
	}
	closedir(d);
}

static inline long sys_fdmap(int pid, int *fd, unsigned int n, int start)

{
	register long r10 asm ("r10") = start;
	register long r8 asm ("r8") = 0;
	long rv;
	asm volatile (
		"syscall"
		: "=a" (rv)
		: "0" (334), "D" (pid), "S" (fd), "d" (n), "r" (r10), "r" (r8)
		: "rcx", "r11", "cc", "memory"
	);
	return rv;
}

void g(void)

{
	int fd[1024];

	sys_fdmap(0, fd, sizeof(fd)/sizeof(fd[0]), 0);
}

int main(void)

{
	unsigned int i;

// for (i = 0; i < (1<<22); i++)
// f();

	dup(0);
	for (i = 0; i < (1<<22); i++)
		g();

	return 0;
}
#11 lore raw
In reply to Alexey Dobriyan
Quoted 4 lines · Alexey Dobriyan

From: Tatsiana Brouka <[email protected]>

Implement system call for bulk retrieveing of pids in binary form.

Quoted 8 lines

Using /proc is slower than necessary: 3 syscalls + another 3 for each thread + converting with atoi().

/proc may be not mounted especially in containers. Natural extension of hidepid=2 efforts is to not mount /proc at all.

It could be used by programs like ps, top or CRIU. Speed increase will become more drastic once combined with bulk retrieval of process statistics.

What could give a noticeable performance gain in a less ridiculous way is an interface like task_diag, see https://lkml.org/lkml/2016/4/11/924 .

Signature · 1 line
ldv