Cross Memory Attach v2
Subsystems (5)
RFC PATCH 1/1 Cross Memory Attach v2
The basic idea behind cross memory attach is to allow MPI programs doing intra-node communication to do a single copy of the message rather than a double copy of the message via shared memory.
The following patch attempts to achieve this by allowing a destination process, given an address and size from a source process, to copy memory directly from the source process into its own address space via a system call. There is also a symmetrical ability to copy from the current process's address space into a destination process's address space.
This is an updated version of the patch I posted a while ago. Changes since the last version:
- Implementation is a bit more complicated now, but the syscall interface has been modified to provide an iovec one for
both the source and destination. This allows for scattered read -> scattered write.
- Rename of syscalls to process_vm_readv/process_vm_writev
- Use of /proc/pid/mem has been considered, but there are issues with
using it:
- Does not allow for specifying iovecs for both src and dest, assuming preadv or pwritev was implemented either the area read from or written to would need to be contiguous.
- Currently mem_read allows only processes who are currently ptrace'ing the target and are still able to ptrace the target to read from the target. This check could possibly be moved to the open call, but its not clear exactly what race this restriction is stopping (reason appears to have been lost)
- Having to send the fd of /proc/self/mem via SCM_RIGHTS on unix domain socket is a bit ugly from a userspace point of view, especially when you may have hundreds if not (eventually) thousands of processes that all need to do this with each other
- Doesn't allow for some future use of the interface we would like to consider adding in the future (see below)
- Interestingly reading from /proc/pid/mem currently actually involves two copies! (But this could be fixed pretty easily)
- Fixed bug around using mm without correct locking
- call set_page_dirty_lock only on pages we may have written to
- Replaces custom security check with call to __ptrace_may_access
As mentioned previously use of vmsplice instead was considered,
but has problems. Since you need the reader and writer working co-operatively
if the pipe is not drained then you block. Which requires some wrapping to do non blocking
on the send side or polling on the receive. In all to all communication
it requires ordering otherwise you can deadlock. And in the example of
many MPI tasks writing to one MPI task vmsplice serialises the
copying.
There are some cases of MPI collectives where even a single copy interface does not get us the performance gain we could. For example in an MPI_Reduce rather than copy the data from the source we would like to instead use it directly in a mathops (say the reduce is doing a sum) as this would save us doing a copy.
We don't need to keep a copy of the data from the
source. I haven't implemented this, but I think this interface could in the future do all this through the use of the flags - eg could specify the math operation and type and the kernel rather than just copying the data would apply the specified operation between the source and destination and store it in the destination.
Chris
Signature · 3 lines
[email protected] Signed-off-by: Chris Yeoh <[email protected]>
arch/powerpc/include/asm/systbl.h +2 -0
@@ -348,3 +348,5 @@ COMPAT_SYS_SPU(sendmsg) COMPAT_SYS_SPU(recvmsg) COMPAT_SYS_SPU(recvmmsg) SYSCALL_SPU(accept4) +SYSCALL(process_vm_readv) +SYSCALL(process_vm_writev)
arch/powerpc/include/asm/unistd.h +3 -1
@@ -367,10 +367,12 @@#define __NR_recvmsg 342#define __NR_recvmmsg 343#define __NR_accept4 344 +#define __NR_process_vm_readv 345 +#define __NR_process_vm_writev 346#ifdef __KERNEL__ -#define __NR_syscalls 345 +#define __NR_syscalls 347#define __NR__exit __NR_exit#define NR_syscalls __NR_syscalls
arch/powerpc/kernel/sys_ppc32.c +1 -0
@@ -624,3 +624,4 @@ asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags,u64 mask = ((u64 )mask_hi <<32 ) | mask_lo;return sys_fanotify_mark (fanotify_fd, flags, mask, dfd, pathname); } +
arch/x86/include/asm/unistd_32.h +3 -1
@@ -346,10 +346,12 @@#define __NR_fanotify_init 338#define __NR_fanotify_mark 339#define __NR_prlimit64 340 +#define __NR_process_vm_readv 341 +#define __NR_process_vm_writev 342#ifdef __KERNEL__ -#define NR_syscalls 341 +#define NR_syscalls 343#define __ARCH_WANT_IPC_PARSE_VERSION#define __ARCH_WANT_OLD_READDIR
arch/x86/kernel/syscall_table_32.S +2 -0
@@ -340,3 +340,5 @@ ENTRY(sys_call_table) .long sys_fanotify_init .long sys_fanotify_mark .long sys_prlimit64 /* 340 */ + .long sys_process_vm_readv + .long sys_process_vm_writev
include/linux/syscalls.h +12 -0
@@ -831,5 +831,17 @@ asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff);asmlinkage long sys_old_mmap (struct mmap_arg_struct __user *arg); +asmlinkage long sys_process_vm_readv (pid_t pid, +const struct iovec __user *lvec, +unsigned long liovcnt, +const struct iovec __user *rvec, +unsigned long riovcnt, +unsigned long flags); +asmlinkage long sys_process_vm_writev (pid_t pid, +const struct iovec __user *lvec, +unsigned long liovcnt, +const struct iovec __user *rvec, +unsigned long riovcnt, +unsigned long flags);#endif
mm/memory.c +330 -0
342 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>