Skip to contentSkip to conversation

Cross Memory Attach

RFC PATCH Superseded Christopher Yeoh 14 participants 40 messages Sep 15, 2010 – Nov 2, 2010

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 Cross Memory Attach

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.

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.

I've added the use of this capability to OpenMPI and run some MPI benchmarks on a 64-way (with SMT off) Power6 machine which see improvements in the following areas:

HPCC results:
=============

MB/s Num Processes
Naturally Ordered 4 8 16 32
Base 1235 935 622 419
CMA 4741 3769 1977 703

MB/s Num Processes
Randomly Ordered 4 8 16 32
Base 1227 947 638 412
CMA 4666 3682 1978 710

MB/s Num Processes
Max Ping Pong 4 8 16 32
Base 2028 1938 1928 1882
CMA 7424 7510 7598 7708

NPB:
====
BT - 12% improvement
FT - 15% improvement
IS - 30% improvement
SP - 34% improvement

IMB:
===

Ping Pong - ~30% improvement
Ping Ping - ~120% improvement
SendRecv - ~100% improvement
Exchange - ~150% improvement
Gather(v) - ~20% improvement
Scatter(v) - ~20% improvement
AlltoAll(v) - 30-50% improvement

Patch is as below. Any comments?

Regards,

Chris

Signature · 12 lines
[email protected]


Signed-off-by: Chris Yeoh <[email protected]>
--- 
 arch/powerpc/include/asm/systbl.h  |    2 
 arch/powerpc/include/asm/unistd.h  |    5 -
 arch/x86/include/asm/unistd_32.h   |    4 
 arch/x86/kernel/syscall_table_32.S |    2 
 include/linux/syscalls.h           |    6 +
 mm/memory.c                        |  184 +++++++++++++++++++++++++++++++++++++
 6 files changed, 200 insertions(+), 3 deletions(-)
arch/powerpc/include/asm/systbl.h +2 -0
index a5ee345..d82a6be 100644
@@ -326,3 +326,5 @@ SYSCALL_SPU(perf_event_open)
 COMPAT_SYS_SPU(preadv)
 COMPAT_SYS_SPU(pwritev)
 COMPAT_SYS(rt_tgsigqueueinfo)
+SYSCALL(copy_from_process)
+SYSCALL(copy_to_process)
arch/powerpc/include/asm/unistd.h +3 -2
index f0a1026..40d46fc 100644
@@ -345,10 +345,11 @@
 #define __NR_preadv		320
 #define __NR_pwritev		321
 #define __NR_rt_tgsigqueueinfo	322
-
+#define __NR_copy_from_process  323
+#define __NR_copy_to_process    324
 #ifdef __KERNEL__
 
-#define __NR_syscalls		323
+#define __NR_syscalls		325
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
arch/x86/include/asm/unistd_32.h +3 -1
index beb9b5f..9c90a65 100644
@@ -343,10 +343,12 @@
 #define __NR_rt_tgsigqueueinfo	335
 #define __NR_perf_event_open	336
 #define __NR_recvmmsg		337
+#define __NR_copy_from_process	338
+#define __NR_copy_to_process	339
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 338
+#define NR_syscalls 340
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
arch/x86/kernel/syscall_table_32.S +2 -0
index 8b37293..984b766 100644
@@ -337,3 +337,5 @@ ENTRY(sys_call_table)
 	.long sys_rt_tgsigqueueinfo	/* 335 */
 	.long sys_perf_event_open
 	.long sys_recvmmsg
+	.long sys_copy_from_process
+	.long sys_copy_to_process
include/linux/syscalls.h +6 -0
index 13ebb54..64b64c3 100644
@@ -825,5 +825,11 @@ 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_copy_from_process(pid_t pid, unsigned long addr,
+				      unsigned long len,
+				      char __user *buf, int flags);
+asmlinkage long sys_copy_to_process(pid_t pid, unsigned long addr,
+				    unsigned long len,
+				    char __user *buf, int flags);
 
 #endif
mm/memory.c +184 -0

196 lines not on this page · raw message

Signature · 1 line
[email protected]
#1 lore raw

(Interesting patch found on lkml, more folks Cc:-ed)

Quoted 61 lines · Christopher Yeoh

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.

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.

I've added the use of this capability to OpenMPI and run some MPI benchmarks on a 64-way (with SMT off) Power6 machine which see improvements in the following areas:

HPCC results:
=============

MB/s Num Processes
Naturally Ordered 4 8 16 32
Base 1235 935 622 419
CMA 4741 3769 1977 703

MB/s Num Processes
Randomly Ordered 4 8 16 32
Base 1227 947 638 412
CMA 4666 3682 1978 710

MB/s Num Processes
Max Ping Pong 4 8 16 32
Base 2028 1938 1928 1882
CMA 7424 7510 7598 7708

NPB:
====
BT - 12% improvement
FT - 15% improvement
IS - 30% improvement
SP - 34% improvement

IMB:
===

Ping Pong - ~30% improvement
Ping Ping - ~120% improvement
SendRecv - ~100% improvement
Exchange - ~150% improvement
Gather(v) - ~20% improvement
Scatter(v) - ~20% improvement
AlltoAll(v) - 30-50% improvement

Quoted 1 line

Patch is as below. Any comments?

Impressive numbers!

What did those OpenMPI facilities use before your patch - shared memory or sockets?

I have an observation about the interface:

include/linux/syscalls.h asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, · line 833

Quoted 6 lines
include/linux/syscalls.h +6 -0
+asmlinkage long sys_copy_from_process(pid_t pid, unsigned long addr,
+				      unsigned long len,
+				      char __user *buf, int flags);
+asmlinkage long sys_copy_to_process(pid_t pid, unsigned long addr,
+				    unsigned long len,
+				    char __user *buf, int flags);

A small detail: 'int flags' should probably be 'unsigned long flags' - it leaves more space.

Also, note that there is a further performance optimization possible
here: if the other task's ->mm is the same as this task's (they share the MM), then the copy can be done straight in this process context, without GUP. User-space might not necessarily be aware of this so it might make sense to express this special case in the kernel too.

More fundamentally, wouldnt it make sense to create an iovec interface here? If the Gather(v) / Scatter(v) / AlltoAll(v) workloads have any fragmentation on the user-space buffer side then the copy of multiple areas could be done in a single syscall. (the MM lock has to be touched only once, target task only be looked up only once, etc.)

Plus, a small naming detail, shouldnt the naming be more IO like:

sys_process_vm_read()
sys_process_vm_write()

Basically a regular read()/write() interface, but instead of fd's we'd have (PID,addr) identifiers for remote buffers, and instant execution (no buffering).

This makes these somewhat special syscalls a bit less special :-)

[ In theory we could also use this new ABI in a way to help the various
RDMA efforts as well - but it looks way too complex. RDMA is rather difficult from an OS design POV - and this special case you have implemented is much easier to do, as we are in a single trust domain. ]

Thanks,

Ingo

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw
Quoted 11 lines
Quoted 11 lines

NPB:
====
BT - 12% improvement
FT - 15% improvement
IS - 30% improvement
SP - 34% improvement

IMB:
===

Quoted 7 lines
Quoted 7 lines

Ping Pong - ~30% improvement
Ping Ping - ~120% improvement
SendRecv - ~100% improvement
Exchange - ~150% improvement
Gather(v) - ~20% improvement
Scatter(v) - ~20% improvement
AlltoAll(v) - 30-50% improvement

btw., how does OpenMPI signal the target tasks that something happened to their address space - is there some pipe/socket side-channel, or perhaps purely based on flags in the modified memory areas, which are polled?

Ingo

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
Quoted 5 lines · On Wed, 15 Sep 2010 10:16:53 +0200 Ingo Molnar <[email protected]> wrote:

btw., how does OpenMPI signal the target tasks that something happened to their address space - is there some pipe/socket side-channel, or perhaps purely based on flags in the modified memory areas, which are polled?

The shared memory btl signals through shared memory, though when threading is enabled (I think its mostly used with threading support disabled) in OpenMPI there is also signalling done through a pipe.

Regards,

Chris

Signature · 7 lines
[email protected]

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#4 lore raw
In reply to Ingo Molnar
Quoted 3 lines · On Wed, 15 Sep 2010 10:02:35 +0200 Ingo Molnar <[email protected]> wrote:

What did those OpenMPI facilities use before your patch - shared memory or sockets?

This comparison is against OpenMPI using the shared memory btl.

Quoted 4 lines

I have an observation about the interface:

A small detail: 'int flags' should probably be 'unsigned long flags'
- it leaves more space.

ok.

Quoted 5 lines

Also, note that there is a further performance optimization possible
here: if the other task's ->mm is the same as this task's (they share the MM), then the copy can be done straight in this process context, without GUP. User-space might not necessarily be aware of this so it might make sense to express this special case in the kernel too.

ok.

Quoted 5 lines

More fundamentally, wouldnt it make sense to create an iovec interface here? If the Gather(v) / Scatter(v) / AlltoAll(v) workloads have any fragmentation on the user-space buffer side then the copy of multiple areas could be done in a single syscall. (the MM lock has to be touched only once, target task only be looked up only once, etc.)

yes, I think so. Currently where I'm using the interface in OpenMPI I can't take advantage of this, but it could be changed in the future- and its likely other MPI's could take advantage of it already.

Quoted 4 lines

Plus, a small naming detail, shouldnt the naming be more IO like:

sys_process_vm_read()
sys_process_vm_write()

Yes, that looks better to me. I really wasn't sure how to name them.

Regards,

Chris

Signature · 7 lines
[email protected]

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#5 lore raw
In reply to Christopher Yeoh
Quoted 3 lines · Christopher Yeoh

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.

If the host has a dma engine (many modern ones do) you can reduce this to zero copies (at least, zero processor copies).

Quoted 8 lines

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.

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

A nice property of file descriptors is that you can pass them around securely via SCM_RIGHTS. So a process can create a window into its address space and pass it to other processes.

(or you could just use a shared memory object and pass it around)

Signature · 8 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#6 lore raw
Quoted 23 lines · Avi Kivity
Quoted 3 lines · Christopher Yeoh

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.

If the host has a dma engine (many modern ones do) you can reduce this to zero copies (at least, zero processor copies).

Quoted 6 lines

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.

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 8 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

A nice property of file descriptors is that you can pass them around securely via SCM_RIGHTS. So a process can create a window into its address space and pass it to other processes.

(or you could just use a shared memory object and pass it around)

Interesting, but how will that work in a scalable way with lots of non-thread tasks?

Say we have 100 processes. We'd have to have 100 fd's - each has to be passed to a new worker process.

In that sense a PID is just as good of a reference as an fd - it can be looked up lockless, etc. - but has the added advantage that it can be passed along just by number.

Thanks,

Ingo

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw
Quoted 34 lines · Ingo Molnar
Quoted 21 lines · Avi Kivity
Quoted 3 lines · Christopher Yeoh

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.

If the host has a dma engine (many modern ones do) you can reduce this to zero copies (at least, zero processor copies).

Quoted 6 lines

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.

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 8 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

A nice property of file descriptors is that you can pass them around securely via SCM_RIGHTS. So a process can create a window into its address space and pass it to other processes.

(or you could just use a shared memory object and pass it around)

Interesting, but how will that work in a scalable way with lots of non-thread tasks?

Quoted 8 lines

Say we have 100 processes. We'd have to have 100 fd's - each has to be passed to a new worker process.

In that sense a PID is just as good of a reference as an fd - it can be looked up lockless, etc. - but has the added advantage that it can be passed along just by number.

It also has better life-cycle control (with just a pid, you never know what it refers to unless you're its parent). Would have been better if clone() returned an fd from which you could derive the pid if you wanted to present it to the user.

Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
#8 lore raw
In reply to Avi Kivity
Quoted 7 lines · On Wed, 15 Sep 2010 12:58:15 +0200 Avi Kivity <[email protected]> wrote:
Quoted 3 lines · Christopher Yeoh

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.

If the host has a dma engine (many modern ones do) you can reduce this to zero copies (at least, zero processor copies).

Yes, this interface doesn't really support that. I've tried to keep things really simple here, but I see potential for increasing level/complexity of support with diminishing returns:

1. single copy (basically what the current implementation does)
2. support for async dma offload (rather arch specific)
3. ability to map part of another process's address space directly into the current one. Would have setup/tear down overhead, but this would be useful specifically for reduction operations where we don't even need to really copy the data once at all, but use it directly in arithmetic/logical operations on the receiver.

For reference, there is also knem http://runtime.bordeaux.inria.fr/knem/
which does implement (2) for I/OAT, though it looks to me the interface and implementation are relatively speaking quite a bit more complex.

Quoted 9 lines

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

That interface sounds interesting (I'm not sure I understand how this would be implemented), though this would mean that a file descriptor would need to be created for every message that each process sent wouldn't it?

Regards,

Chris

Signature · 1 line
[email protected]
#9 lore raw
Quoted 8 lines · Christopher Yeoh
Quoted 5 lines · On Wed, 15 Sep 2010 12:58:15 +0200 Avi Kivity <[email protected]> wrote:
Quoted 3 lines · Christopher Yeoh

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.

Quoted 6 lines
Quoted 2 lines

If the host has a dma engine (many modern ones do) you can reduce this to zero copies (at least, zero processor copies).

Yes, this interface doesn't really support that. I've tried to keep things really simple here, but I see potential for increasing level/complexity of support with diminishing returns:

I think keeping things simple is a good goal. The vmfd() approach might be worth looking into, but your patch certainly is pretty simple as-is.

That said, it's also buggy. You can't just get a task and then do

down_read(task->mm->mmap_sem)

on it. Not even if you have a refcount. The mm may well go away. You need to do the same thing "get_task_mm()" does, ie look up the mm under task_lock, and get a reference to it. You already get the task-lock for permission testing, so it looks like doing it there would likely work out.

Quoted 5 lines

3. ability to map part of another process's address space directly into the current one. Would have setup/tear down overhead, but this would be useful specifically for reduction operations where we don't even need to really copy the data once at all, but use it directly in arithmetic/logical operations on the receiver.

Don't even think about this. If you want to map another tasks memory, use shared memory. The shared memory code knows about that. The races for anything else are crazy.

Linus

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw
Quoted 9 lines
Quoted 5 lines

3. ability to map part of another process's address space directly into the current one. Would have setup/tear down overhead, but this would be useful specifically for reduction operations where we don't even need to really copy the data once at all, but use it directly in arithmetic/logical operations on the receiver.

Don't even think about this. If you want to map another tasks memory, use shared memory. The shared memory code knows about that. The races for anything else are crazy.

SGI has a similar, but significantly more difficult, problem to solve and have written a fairly complex driver to handle exactly the scenario IBM is proposing. In our case, not only are we trying to directly access one processes memory, we are doing it from a completely different operating system instance operating on the same numa fabric.

In our case (I have not looked at IBMs patch), we are actually using get_user_pages() to get extra references on struct pages. We are judicious about reference counting the mm and we use get_task_mm in all places with the exception of process teardown (ignorable detail for now). We have a fault handler inserting PFNs as appropriate. You can guess at the complexity. Even with all its complexity, we still need to caveat certain functionality as not being supported.

If we were to try and get that driver included in the kernel, how would you suggest we expand the shared memory code to include support for the coordination needed between those seperate operating system instances? I am genuinely interested and not trying to be argumentative. This has been on my "Get done before Aug-1 list for months and I have not had any time to pursue.

Thanks,
Robin

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#11 lore raw
In reply to Christopher Yeoh

Le 15/09/2010 16:42, Christopher Yeoh a ecrit :

Quoted 25 lines
Quoted 9 lines · On Wed, 15 Sep 2010 12:58:15 +0200 Avi Kivity <[email protected]> wrote:
Quoted 4 lines · Christopher Yeoh

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.

If the host has a dma engine (many modern ones do) you can reduce this to zero copies (at least, zero processor copies).

Yes, this interface doesn't really support that. I've tried to keep things really simple here, but I see potential for increasing level/complexity of support with diminishing returns:

1. single copy (basically what the current implementation does)
2. support for async dma offload (rather arch specific)
3. ability to map part of another process's address space directly into the current one. Would have setup/tear down overhead, but this would be useful specifically for reduction operations where we don't even need to really copy the data once at all, but use it directly in arithmetic/logical operations on the receiver.

Quoted 4 lines

For reference, there is also knem http://runtime.bordeaux.inria.fr/knem/
which does implement (2) for I/OAT, though it looks to me the interface and implementation are relatively speaking quite a bit more complex.

I am the guy doing KNEM so I can comment on this. The I/OAT part of KNEM was mostly a research topic, it's mostly useless on current machines since the memcpy performance is much larger than I/OAT DMA Engine. We also have an offload model with a kernel thread, but it wasn't used a lot so far. These features can be ignored for the current discussion.

We've been working on this for a while with MPICH and OpenMPI developers (both already use KNEM), and here's what I think is missing in Christopher's proposal:
* Vectorial buffer support: MPI likes things like datatypes, which make buffers non-contigous. You could add vectorial buffer support to your interface, but the users would have to store the data-representation of each process in all processes. Not a good idea, it's easier to keep the knowledge of the non-contigous-ness of the remote buffer only in the remote process.
* Collectives: You don't want to pin/unpin the same region over and over, it's overkill when multiple processes are reading for the same exact buffer (broadcast) or from contigous parts of the same buffer (scatter).

So what we do in KNEM is:
* declare a memory region (sets of non-contigous segments + protection), aka get_user_pages and return an associated cookie id
* have syscalls to read/write from region given a cookie, an offset in the region and a length
This one-sided interface looks like an InfiniBand model, but only for intra-node data transfers.

So OpenMPI and MPICH declare regions, pass their cookies through their shared-memory buffer, and the remote process reads from there. Then, they notify the first process that it may destroy the region (can be automatic if the region creator passed a specific flag saying destroy after first use).

Brice

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw

Le 16/09/2010 08:32, Brice Goglin a ecrit :

Quoted 5 lines

I am the guy doing KNEM so I can comment on this. The I/OAT part of KNEM was mostly a research topic, it's mostly useless on current machines since the memcpy performance is much larger than I/OAT DMA Engine. We also have an offload model with a kernel thread, but it wasn't used a lot so far. These features can be ignored for the current discussion.

I've just created a knem branch where I removed all the above, and some other stuff that are not necessary for normal users. So it just contains the region management code and two commands to copy between regions or between a region and some local iovecs.

Commands are visible at (still uses ioctls since it doesn't matter while discussing the features):
https://gforge.inria.fr/scm/viewvc.php/*checkout*/branches/kernel/driver/linux/knem_main.c?root=knem&content-type=text%2Fplain

And the actual driver is at:
https://gforge.inria.fr/scm/viewvc.php/*checkout*/branches/kernel/common/knem_io.h?root=knem&content-type=text%2Fplain

Brice

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#13 lore raw
Quoted 8 lines · On Thu, 16 Sep 2010 11:15:10 +0200 Brice Goglin <[email protected]> wrote:
Quoted 6 lines · Brice Goglin

I am the guy doing KNEM so I can comment on this. The I/OAT part of KNEM was mostly a research topic, it's mostly useless on current machines since the memcpy performance is much larger than I/OAT DMA Engine. We also have an offload model with a kernel thread, but it wasn't used a lot so far. These features can be ignored for the current discussion.

Quoted 4 lines

I've just created a knem branch where I removed all the above, and some other stuff that are not necessary for normal users. So it just contains the region management code and two commands to copy between regions or between a region and some local iovecs.

When I did the original hpcc runs for CMA vs shared mem double copy I also did some KNEM runs as a bit of a sanity check. The CMA OpenMPI implementation actually uses the infrastructure KNEM put into the OpenMPI shared mem btl - thanks for that btw it made things much easier for me to test CMA.

Interestingly although KNEM and CMA fundamentally are doing very similar things, at least with hpcc I didn't see as much of a gain with KNEM as with CMA:

MB/s
Naturally Ordered 4 8 16 32
Base 1235 935 622 419
CMA 4741 3769 1977 703
KNEM 3362 3091 1857 681

MB/s
Randomly Ordered 4 8 16 32
Base 1227 947 638 412
CMA 4666 3682 1978 710
KNEM 3348 3050 1883 684

MB/s
Max Ping Pong 4 8 16 32
Base 2028 1938 1928 1882
CMA 7424 7510 7598 7708
KNEM 5661 5476 6050 6290

I don't know the reason behind the difference - if its something perculiar to hpcc, or if there's extra overhead the way that knem does setup for copying, or if knem wasn't configured optimally. I haven't done any comparison IMB or NPB runs...

syscall and setup overhead does have some measurable effect - although I don't have the numbers for it here, neither KNEM nor CMA does quite as well with hpcc when compared against a hacked version of hpcc where everything is declared ahead of time as shared memory so the receiver can just do a single copy from userspace - which I think is representative of a theoretical maximum gain from the single copy approach.

Chris

Signature · 7 lines
[email protected]

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#14 lore raw
In reply to Avi Kivity
Quoted 9 lines · Avi Kivity

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space.  You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#15 lore raw
Quoted 9 lines · Bryan Donlan
Quoted 7 lines · Avi Kivity

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 5 lines
Quoted 2 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

Yes, opening that file should be equivalent (and you could certainly implement aio via dma for it).

Signature · 8 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#16 lore raw
Quoted 10 lines · Avi Kivity
Quoted 9 lines · Bryan Donlan
Quoted 7 lines · Avi Kivity

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

Yes, opening that file should be equivalent (and you could certainly implement aio via dma for it).

I will second this /proc/$pid/mem is semantically the same and it would really be good if this patch became a patch optimizing that case.

Otherwise we have code duplication and thus dilution of knowledge in two different places for no discernable reason. Hindering long term maintenance.

+int copy_to_from_process_allowed(struct task_struct *task) +{
+ /* Allow copy_to_from_process to access another process using
+ the same critera as a process would be allowed to ptrace
+ that same process */
+ const struct cred *cred = current_cred(), *tcred;
+
+ rcu_read_lock();
+ tcred = __task_cred(task);

+	if ((cred->uid != tcred->euid ||
+	     cred->uid != tcred->suid ||
+	     cred->uid != tcred->uid  ||
+	     cred->gid != tcred->egid ||
+	     cred->gid != tcred->sgid ||

+ cred->gid != tcred->gid) &&
+ !capable(CAP_SYS_PTRACE)) {
+ rcu_read_unlock();
+ return 0;
+ }
+ rcu_read_unlock();
+ return 1;
+}

This hunk of the patch is a copy of __ptrace_may_access without security hooks removed. Both the code duplication, the removal of the dumpable check and the removal of the security hooks look like a bad idea.

Removing the other checks in check_mem_permission seems reasonable as those appear to be overly paranoid.

Hmm. This is weird:

+ /* Get the pages we're interested in */
+ pages_pinned = get_user_pages(task, task->mm, pa,
+ nr_pages_to_copy,
+ copy_to, 0, process_pages, NULL);
+
+ if (pages_pinned != nr_pages_to_copy)
+ goto end;
+
+ /* Do the copy for each page */
+ for (i = 0; i < nr_pages_to_copy; i++) {
+ target_kaddr = kmap(process_pages[i]) + start_offset;
+ bytes_to_copy = min(PAGE_SIZE - start_offset,
+ len - *bytes_copied);
+ if (start_offset)
+ start_offset = 0;
+
+ if (copy_to) {
+ ret = copy_from_user(target_kaddr,
+ user_buf + *bytes_copied,
+ bytes_to_copy);
+ if (ret) {
+ kunmap(process_pages[i]);
+ goto end;
+ }
+ } else {
+ ret = copy_to_user(user_buf + *bytes_copied,
+ target_kaddr, bytes_to_copy);
+ if (ret) {
+ kunmap(process_pages[i]);
+ goto end;
+ }
+ }
+ kunmap(process_pages[i]);
+ *bytes_copied += bytes_to_copy;
+ }
+

That hunk of code appears to be an copy of mm/memmory.c:access_process_vm. A little more optimized by taking the get_user_pages out of the inner loop but otherwise pretty much the same code.

So I would argue it makes sense to optimize access_process_vm.

So unless there are fundamental bottlenecks to performance I am not seeing please optimize the existing code paths in the kernel that do exactly what you are trying to do.

Thanks,
Eric

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#17 lore raw
In reply to Bryan Donlan
Quoted 10 lines · On Wed, 15 Sep 2010 23:46:09 +0900 Bryan Donlan <[email protected]> wrote:
Quoted 8 lines · Avi Kivity

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space.  You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 6 lines
Quoted 2 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

Perhaps I'm misunderstanding something here, but accessing /proc/$pid/mem requires ptracing the target process. We can't really have all these MPI processes ptraceing each other just to send/receive a message....

Regards,

Chris

Signature · 1 line
[email protected]
#18 lore raw
Quoted 16 lines · Christopher Yeoh
Quoted 13 lines · On Wed, 15 Sep 2010 23:46:09 +0900 Bryan Donlan<[email protected]> wrote:
Quoted 10 lines · Avi Kivity

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Quoted 9 lines
Quoted 3 lines

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

Perhaps I'm misunderstanding something here, but accessing /proc/$pid/mem requires ptracing the target process. We can't really have all these MPI processes ptraceing each other just to send/receive a message....

You could have each process open /proc/self/mem and pass the fd using SCM_RIGHTS.

That eliminates a race; with copy_to_process(), by the time the pid is looked up it might designate a different process.

Signature · 7 lines
error compiling committee.c: too many arguments to function

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#19 lore raw
Quoted 27 lines · On Thu, 16 Sep 2010 11:26:36 +0200 Avi Kivity <[email protected]> wrote:
Quoted 16 lines · Christopher Yeoh
Quoted 13 lines · On Wed, 15 Sep 2010 23:46:09 +0900 Bryan Donlan<[email protected]> wrote:
Quoted 10 lines · Avi Kivity

Instead of those two syscalls, how about a vmfd(pid_t pid,
ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

With some care (and use of mmu_notifiers) you can even mmap()
your vmfd and access remote process memory directly.

Quoted 9 lines
Quoted 3 lines

Rather than introducing a new vmfd() API for this, why not just
add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

Perhaps I'm misunderstanding something here, but accessing /proc/$pid/mem requires ptracing the target process. We can't really have all these MPI processes ptraceing each other just to send/receive a message....

Quoted 5 lines

You could have each process open /proc/self/mem and pass the fd using SCM_RIGHTS.

That eliminates a race; with copy_to_process(), by the time the pid is looked up it might designate a different process.

Just to revive an old thread (I've been on holidays), but this doesn't work either. the ptrace check is done by mem_read (eg on each read) so even if you do pass the fd using SCM_RIGHTS, reads on the fd still fail.

So unless there's good reason to believe that the ptrace permission check is no longer needed, the /proc/pid/mem interface doesn't seem to be an option for what we want to do.

Oh and interestingly reading from /proc/pid/mem involves a double copy
- copy to a temporary kernel page and then out to userspace. But that is fixable.

Regards,

Chris

Signature · 8 lines
[email protected]

--
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>
#20 lore raw
Quoted 7 lines · Christopher Yeoh
Quoted 6 lines

You could have each process open /proc/self/mem and pass the fd using SCM_RIGHTS.

That eliminates a race; with copy_to_process(), by the time the pid is looked up it might designate a different process.

Quoted 9 lines

Just to revive an old thread (I've been on holidays), but this doesn't work either. the ptrace check is done by mem_read (eg on each read) so even if you do pass the fd using SCM_RIGHTS, reads on the fd still fail.

So unless there's good reason to believe that the ptrace permission check is no longer needed, the /proc/pid/mem interface doesn't seem to be an option for what we want to do.

Perhaps move the check to open(). I can understand the desire to avoid letting random processes peek each other's memory, but once a process has opened its own /proc/self/mem and explicitly passed it to another, we should allow it.

Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
#21 lore raw
In reply to Bryan Donlan
Quoted 9 lines · Avi Kivity
Quoted 8 lines

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space.  You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 6 lines
Quoted 2 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

As far as I heared from my friend, old HP MPI implementation used /proc/$pid/mem for this purpose. (I don't know current status). However almost implementation doesn't do that because /proc/$pid/mem required the process is ptraced. As far as I understand , very old /proc/$pid/mem doesn't require it. but It changed for security concern. Then, Anybody haven't want to change this interface because they worry break security.

But, I don't know what exactly protected "the process is ptraced" check. If anyone explain the reason and we can remove it. I'm not againt at all.

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#22 lore raw
Quoted 24 lines · KOSAKI Motohiro
Quoted 9 lines · Avi Kivity
Quoted 8 lines

Instead of those two syscalls, how about a vmfd(pid_t pid, ulong start, ulong len) system call which returns an file descriptor that represents a portion of the process address space. You can then use preadv() and pwritev() to copy memory, and io_submit(IO_CMD_PREADV) and io_submit(IO_CMD_PWRITEV) for asynchronous variants (especially useful with a dma engine, since that adds latency).

Quoted 6 lines
Quoted 2 lines

With some care (and use of mmu_notifiers) you can even mmap() your vmfd and access remote process memory directly.

Rather than introducing a new vmfd() API for this, why not just add implementations for these more efficient operations to the existing /proc/$pid/mem interface?

As far as I heared from my friend, old HP MPI implementation used /proc/$pid/mem for this purpose. (I don't know current status). However almost implementation doesn't do that because /proc/$pid/mem required the process is ptraced. As far as I understand , very old /proc/$pid/mem doesn't require it. but It changed for security concern. Then, Anybody haven't want to change this interface because they worry break security.

Quoted 3 lines

But, I don't know what exactly protected "the process is ptraced" check. If anyone explain the reason and we can remove it. I'm not againt at all.

I did some Git digging - that ptrace check for /proc/$pid/mem read/write goes all the way back to the beginning of written human history, aka Linux v2.6.12-rc2.

I researched the fragmented history of the stone ages as well, i checked out numerous cave paintings, and while much was lost, i was able to recover this old fragment of a clue in the cave called 'patch-2.3.27', carbon-dated back as far as the previous millenium (!):

mem_read() in fs/proc/base.c:

+ *  1999, Al Viro. Rewritten. Now it covers the whole per-process part.
+ *  Instead of using magical inumbers to determine the kind of object
+ *  we allocate and fill in-core inodes upon lookup. They don't even
+ *  go into icache. We cache the reference to task_struct upon lookup too.
+ *  Eventually it should become a filesystem in its own. We don't use the
+ *  rest of procfs anymore.

In such a long timespan language has changed much, so not all of this scribbling can be interpreted - but one thing appears to be sure: this is where the MAY_PTRACE() restriction was introduced to /proc/$pid/mem - as part of a massive rewrite.

Alas, the reason for the restriction was not documented, and is feared to be lost forever.

Thanks,

Ingo

--
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/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#23 lore raw
In reply to Christopher Yeoh
Quoted 10 lines · Christopher Yeoh

+
+               if (copy_to) {
+                       ret = copy_from_user(target_kaddr,
+                                            user_buf + *bytes_copied,
+                                            bytes_to_copy);
+                       if (ret) {
+                               kunmap(process_pages[i]);
+                               goto end;
+                       }
+               } else {

Quoted 8 lines

+                       ret = copy_to_user(user_buf + *bytes_copied,
+                                          target_kaddr, bytes_to_copy);
+                       if (ret) {
+                               kunmap(process_pages[i]);
+                               goto end;
+                       }
+               }
+               kunmap(process_pages[i]);

Btw, please just do this as

   if (copy_to)
      ret = copy_from_user(..);
   else
      ret = copy_to_user(..);
   kunmap(process_pages[i]);
   if (ret)
      goto out;

(and also, I think you should probably use a real variable for *bytes_copied, rather than update things behind the pointer. Update the pointer just once at the end instead, or preferably just change the calling convention to just return the number of bytes copied, and let the caller do the page counting).

Linus

#24 lore raw
Quoted 10 lines · Linus Torvalds

Btw, please just do this as

  if (copy_to)
     ret = copy_from_user(..);
  else
     ret = copy_to_user(..);
  kunmap(process_pages[i]);
  if (ret)
     goto out;

In fact, you might consider passing in a "copy_out" function pointer rather than that "copy_to" boolean, and rather than that conditional, just do a

  ret = copy_out(..);

thing. On sane/good architectures, branch target prediction will make it all work out to the same work in the end, and it certainly looks simpler and cleaner.

Linus

#25 lore raw
Quoted 10 lines · On Wed, 15 Sep 2010 08:14:49 -0700 Linus Torvalds…

In fact, you might consider passing in a "copy_out" function pointer rather than that "copy_to" boolean, and rather than that conditional, just do a

  ret = copy_out(..);

thing. On sane/good architectures, branch target prediction will make it all work out to the same work in the end, and it certainly looks simpler and cleaner.

Thanks for all the feedback - I'll rework the patch...

Regards,

Chris

Signature · 1 line
[email protected]
#26 lore raw
In reply to Linus Torvalds
Quoted 7 lines · Linus Torvalds
   if (copy_to)
      ret = copy_from_user(..);
   else
      ret = copy_to_user(..);
   kunmap(process_pages[i]);
   if (ret)
      goto out; 

Shouldn't we be using kmap_atomic()

#27 lore raw
Quoted 11 lines · Peter Zijlstra
Quoted 7 lines · Linus Torvalds

   if (copy_to)
      ret = copy_from_user(..);
   else
      ret = copy_to_user(..);
   kunmap(process_pages[i]);
   if (ret)
      goto out;

Shouldn't we be using kmap_atomic()

Over a copy_to/from_user? Not bloody likely.

Linus

#28 lore raw
Quoted 11 lines · Linus Torvalds
Quoted 10 lines · Peter Zijlstra
Quoted 7 lines · Linus Torvalds
   if (copy_to)
      ret = copy_from_user(..);
   else
      ret = copy_to_user(..);
   kunmap(process_pages[i]);
   if (ret)
      goto out;
Quoted 3 lines
Quoted 1 line

Shouldn't we be using kmap_atomic()

Over a copy_to/from_user? Not bloody likely.

Gah, indeed. OK, since its not nested kmap() should indeed work. The alternative is using get_user_pages() on both address spaces, but I guess that makes things unnecessarily complex.

#29 lore raw
Quoted 6 lines · Peter Zijlstra
Quoted 2 lines

Over a copy_to/from_user? Not bloody likely.

Gah, indeed. OK, since its not nested kmap() should indeed work. The alternative is using get_user_pages() on both address spaces, but I guess that makes things unnecessarily complex.

.. and perform horribly badly. And since the whole point was to do this really efficiently, that's not good.

What *would* work would be to have a fast case that does kmap_atomic() together with a copy_to/from_user_atomic(). And when that fast-case fails, do the full kmap. Slightly more complex than the suggested patch, but not horribly so (just a few more lines, no fundamental complexities).

Of course, these days I would seriously suggest against trying to optimize the kmap() case. It only matters on crap hardware these days. Anybody running HIGHMEM in 2010 and thinks that it makes sense deserves the pain the get. We should not complicate the kernel further for it, and sane architectures will have a no-op kmap().

So the real cost there is likely not the kmap as much as the set_page_dirty_lock() for the copy_to case. But you'd need to profile it to see how big of a hit it is compared to the copy itself.

Linus

#30 lore raw
Quoted 6 lines · Linus Torvalds

Of course, these days I would seriously suggest against trying to optimize the kmap() case. It only matters on crap hardware these days. Anybody running HIGHMEM in 2010 and thinks that it makes sense deserves the pain the get. We should not complicate the kernel further for it, and sane architectures will have a no-op kmap().

OK, fully agreed. Someone ought to tell ARM though :-)

#31 lore raw
Quoted 9 lines · Peter Zijlstra
Quoted 6 lines · Linus Torvalds

Of course, these days I would seriously suggest against trying to optimize the kmap() case. It only matters on crap hardware these days. Anybody running HIGHMEM in 2010 and thinks that it makes sense deserves the pain the get. We should not complicate the kernel further for it, and sane architectures will have a no-op kmap().

OK, fully agreed. Someone ought to tell ARM though :-)

You know what? I don't care. If the fact that ARM is messing up means that they will never be able to do well in the micro-server space, that's _their_ problem.

I fought HIGHMEM tooth and nail when it appeared originally. I lost, because we really didn't have any choice. But there is no way I'm going to say "oh, HIGHMEM still makes sense in 2010 because the ARM guys are now making all the same mistakes Intel did in 1992". Because these days we _do_ have a choice.

And all the rumors are that there will be a 64-bit ARM too. So their PAE mess will be out before, but nobody sane should really consider it a primary issue. It will work, but it will work suboptimally. That's what you get when you have bad hardware design.

Linus

#32 lore raw
Quoted 3 lines · Linus Torvalds

But there is no way I'm
going to say "oh, HIGHMEM still makes sense in 2010 because the ARM guys are now making all the same mistakes Intel did in 1992".

Off by a couple of years. Intel did it wit the PPro, in 1995, actually. But it's still going to be 16 years later by the time ARM LPAE actually ships, I guess.

Linus

#33 lore raw
Quoted 11 lines
Quoted 3 lines · Linus Torvalds

But there is no way I'm
going to say "oh, HIGHMEM still makes sense in 2010 because the ARM guys are now making all the same mistakes Intel did in 1992".

Off by a couple of years. Intel did it wit the PPro, in 1995, actually. But it's still going to be 16 years later by the time ARM LPAE actually ships, I guess.

Yep, back when the 386 was designed, having 4GB for both physical and virtual address space (which was what caused HIGHMEM to be needed at all with more than 1GB in the first place) was not a mistake.

#34 lore raw
In reply to Linus Torvalds

(Adding Russell King of ARM Linux to CC list)

----------------------------------------

Quoted 40 lines

From: [email protected]
Date: Thu, 16 Sep 2010 10:54:29 -0700
Subject: Re: [RFC][PATCH] Cross Memory Attach
To: [email protected]
CC: [email protected]; [email protected]

Quoted 9 lines · Peter Zijlstra
Quoted 6 lines · Linus Torvalds

Of course, these days I would seriously suggest against trying to optimize the kmap() case. It only matters on crap hardware these days. Anybody running HIGHMEM in 2010 and thinks that it makes sense deserves the pain the get. We should not complicate the kernel further for it, and sane architectures will have a no-op kmap().

OK, fully agreed. Someone ought to tell ARM though :-)

You know what? I don't care. If the fact that ARM is messing up means that they will never be able to do well in the micro-server space, that's _their_ problem.

I fought HIGHMEM tooth and nail when it appeared originally. I lost, because we really didn't have any choice. But there is no way I'm going to say "oh, HIGHMEM still makes sense in 2010 because the ARM guys are now making all the same mistakes Intel did in 1992". Because these days we _do_ have a choice.

And all the rumors are that there will be a 64-bit ARM too. So their PAE mess will be out before, but nobody sane should really consider it a primary issue. It will work, but it will work suboptimally. That's what you get when you have bad hardware design.

Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

#35 lore raw
Quoted 2 lines · Yuhong Bao

(Adding Russell King of ARM Linux to CC list)

I'm not sure why you're repeatedly sending me this email (this is the second in less than 24 hours.)

In any case, it's not like I can influence the direction ARM Ltd take their architecture - I only hear about stuff after the decisions have been taken and the direction set. (Sometimes I hear about stuff just before the public announcement.)

So, if you think I can do anything to stop the move towards LPAS (large physical address space) and tell ARM to go to 64-bit directly, you're sadly mistaken.

Quoted 42 lines

----------------------------------------

Quoted 40 lines

From: [email protected]
Date: Thu, 16 Sep 2010 10:54:29 -0700
Subject: Re: [RFC][PATCH] Cross Memory Attach
To: [email protected]
CC: [email protected]; [email protected]

Quoted 9 lines · Peter Zijlstra
Quoted 6 lines · Linus Torvalds

Of course, these days I would seriously suggest against trying to optimize the kmap() case. It only matters on crap hardware these days. Anybody running HIGHMEM in 2010 and thinks that it makes sense deserves the pain the get. We should not complicate the kernel further for it, and sane architectures will have a no-op kmap().

OK, fully agreed. Someone ought to tell ARM though :-)

You know what? I don't care. If the fact that ARM is messing up means that they will never be able to do well in the micro-server space, that's _their_ problem.

I fought HIGHMEM tooth and nail when it appeared originally. I lost, because we really didn't have any choice. But there is no way I'm going to say "oh, HIGHMEM still makes sense in 2010 because the ARM guys are now making all the same mistakes Intel did in 1992". Because these days we _do_ have a choice.

And all the rumors are that there will be a 64-bit ARM too. So their PAE mess will be out before, but nobody sane should really consider it a primary issue. It will work, but it will work suboptimally. That's what you get when you have bad hardware design.

Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

#36 lore raw
Quoted 5 lines
Quoted 2 lines

(Adding Russell King of ARM Linux to CC list)

I'm not sure why you're repeatedly sending me this email (this is the second in less than 24 hours.)

Sorry, the first one was sent with multipart/alternate with both HTML and plain text, leading it to be rejected by LKML.

Quoted 8 lines

In any case, it's not like I can influence the direction ARM Ltd take their architecture - I only hear about stuff after the decisions have been taken and the direction set. (Sometimes I hear about stuff just before the public announcement.)

So, if you think I can do anything to stop the move towards LPAS (large physical address space) and tell ARM to go to 64-bit directly, you're sadly mistaken.

If I know of email address of any ARM engineers, I'd add them to CC list too.

Yuhong Bao

#37 lore raw
In reply to Linus Torvalds
Quoted 6 lines

Of course, these days I would seriously suggest against trying to optimize the kmap() case. It only matters on crap hardware these days. Anybody running HIGHMEM in 2010 and thinks that it makes sense deserves the pain the get. We should not complicate the kernel further for it, and sane architectures will have a no-op kmap().

Well, keep in mind most even vaguely recent 32-bit x86 distro kernels have HIGHMEM4G enabled by default.
Some recent ones even have HIGHMEM64G enabled in order to get NX support. (And yes, as I said before, there are many processors that cannot run in long mode but have NX)

Yuhong Bao

#38 lore raw
In reply to Christopher Yeoh
Quoted 3 lines · Christopher Yeoh

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.

Interesting, and nice benchmark results. I have a question though:

Quoted 7 lines
mm/memory.c +7 -0
+	/* Get the pages we're interested in */
+	pages_pinned = get_user_pages(task, task->mm, pa,
+				      nr_pages_to_copy,
+				      copy_to, 0, process_pages, NULL);
+
+	if (pages_pinned != nr_pages_to_copy)
+		goto end;

...

mm/memory.c void print_vma_addr(char *prefix, unsigned long ip) · line 3578

Quoted 6 lines
mm/memory.c +6 -0
+end:
+	for (i = 0; i < pages_pinned; i++) {
+		if (copy_to)
+			set_page_dirty_lock(process_pages[i]);
+		put_page(process_pages[i]);
+	}

It looks to me like if get_user_pages() fails to pin *all* the pages, we treat the target pages as dirty even though we never actually touched them?

Maybe it should be 'if (copy_to && *bytes_copied)'?

#39 lore raw
Quoted 24 lines · On Wed, 15 Sep 2010 12:07:11 -0400 [email protected] wrote:

Interesting, and nice benchmark results. I have a question though:

Quoted 7 lines
mm/memory.c +4 -0
+	/* Get the pages we're interested in */
+	pages_pinned = get_user_pages(task, task->mm, pa,
+				      nr_pages_to_copy,
+				      copy_to, 0, process_pages,

NULL); +

(quoted diff) +2 -0
+	if (pages_pinned != nr_pages_to_copy)
+		goto end;

...

mm/memory.c void print_vma_addr(char *prefix, unsigned long ip) · line 3578

Quoted 6 lines
mm/memory.c +6 -0
+end:
+	for (i = 0; i < pages_pinned; i++) {
+		if (copy_to)
+			set_page_dirty_lock(process_pages[i]);
+		put_page(process_pages[i]);
+	}

It looks to me like if get_user_pages() fails to pin *all* the pages, we treat the target pages as dirty even though we never actually touched them?

Quoted 1 line

Maybe it should be 'if (copy_to && *bytes_copied)'?

Yes that can happen, though the *bytes_copied check doesn't completely fix it as copy_from_user could fail resulting in some pages being touched, but not all of them. I'll add some code to only call set_page_dirty_lock on pages that really have been touched...

Regards,

Chris

Signature · 1 line
[email protected]