Live data from Hacker News

Linux Memory Management FAQ

landley.net

21–30 of 75 posts

Re: Linux Memory Management FAQ

#22
post #8

Earlier quoted context omitted.

Your CPU can handle 39-bit physical memory addresses (up to 512 GB of physical memory), and 48-bit virtual addresses (256 TB). Your operating system maintains a mapping from virtual to physical addresses, usually arranging the map so that every process has a separate memory space. Pointers are all still 64 bits long though.

So are the 16 leftmost bits of a virtual address always 0?

Yes generally for userspace addresses they are 0. But more importantly they can be used for other stuff, commonly referred to as pointer tagging / smuggling etc.

It's a useful optimisation technique where you can add some extra metadata without having to dereference a pointer.

Re: Linux Memory Management FAQ

#23

Earlier quoted context omitted.

So are the 16 leftmost bits of a virtual address always 0?

No, it must be sign-extended from the top bit of the valid set. Otherwise the address is non-canonical.

This is true for x86-64, not true for other architectures such as arm64.

Apple uses the high bits to cryptographicly sign the pointer value.

Re: Linux Memory Management FAQ

#24

The times I have had to explain how mm works is draining. yes you can malloc 2M, no that does not mean you have 2M to use.

Well, it does mean that in C. But some folks prefer to play by their own rules.

Actually no, the malloc doesn't allocate any memory it just updates the process's VMA to say that the allocated virtual range is valid. The pages are then faulted in on write. This is where things like OOM killer become very confusing for people.

In linux (in sane configurations) allocations are just preorders.

EDIT: I can't reply below due to rate limiting:

I'd argue that overcommit just makes the difference between allocation and backing very stark.

Your memory IS in fact allocated in the process VMA, it's just the anonymous pages cannot necessarily be backed.

This differs, obviously, in other OSes as pointed out. Also differs if you turn overcommit off but since so much in linux assumes it your system will soon break if you try it.

Re: Linux Memory Management FAQ

#25

Earlier quoted context omitted.

Well, it does mean that in C. But some folks prefer to play by their own rules.

Actually no, the malloc doesn't allocate any memory it just updates the process's VMA to say that the allocated virtual range is valid. The pages are then faulted in on write. This is where things like OOM killer become very confusing for people. In linux (in sane configurations) allocations are just preorders. EDIT: I can't reply below due to rate limiting: I'd argue that overcommit just makes the difference between…

I said "in C". You're talking "in Linux" (or glibc/whatever). Which, as I already said, plays by its own rules and defies C. It's broken by design.

Re: Linux Memory Management FAQ

#26

Earlier quoted context omitted.

Well, it does mean that in C. But some folks prefer to play by their own rules.

Actually no, the malloc doesn't allocate any memory it just updates the process's VMA to say that the allocated virtual range is valid. The pages are then faulted in on write. This is where things like OOM killer become very confusing for people. In linux (in sane configurations) allocations are just preorders. EDIT: I can't reply below due to rate limiting: I'd argue that overcommit just makes the difference between…

In the C standard malloc should return null if it can’t fulfill the request. Linux violates this but it usually works out in the end since virtual memory makes true OOM very rare.

Re: Linux Memory Management FAQ

#27

Earlier quoted context omitted.

Well, it does mean that in C. But some folks prefer to play by their own rules.

Actually no, the malloc doesn't allocate any memory it just updates the process's VMA to say that the allocated virtual range is valid. The pages are then faulted in on write. This is where things like OOM killer become very confusing for people. In linux (in sane configurations) allocations are just preorders. EDIT: I can't reply below due to rate limiting: I'd argue that overcommit just makes the difference between…

This depends on the OS. Solaris and Windows both do strict accounting by default, and overcommit is opt-in at a fine-grain API level. Linux is relatively extreme in its embrace of overcommit. So extreme that strict accounting isn't even possible--even if you disable overcommit in Linux, there are too many corner cases in the kernel where a process (including innocent processes) will be shot down under memory pressure. Too many Linux kernel programmers designed their subsystems with the overcommit mentality. That said, I still always disable overcommit as it makes it less likely for innocent processes to be killed when under heavy load.

An example of a split-the-difference approach is macOS, which AFAIU implements overcommit but also dynamically instantiates swap so that overcommit-induced OOM killing won't occur until your disk is full.

Also, it's worth mentioning that on all these systems process limits (see, e.g., setrlimit(2)) can still result in malloc returning NULL.

Re: Linux Memory Management FAQ

#28
post #23

Earlier quoted context omitted.

No, it must be sign-extended from the top bit of the valid set. Otherwise the address is non-canonical.

This is true for x86-64, not true for other architectures such as arm64. Apple uses the high bits to cryptographicly sign the pointer value.

Fascinating. Does this confer some of the benefits of ECC RAM, for pointer data only — without the hardware cost?

Re: Linux Memory Management FAQ

#29

For anybody who's interested I also wrote up a whole bunch of notes on this at https://github.com/lorenzo-stoakes/linux-vm-notes and superceded by far more recent https://github.com/lorenzo-stoakes/linux-mm-notes I have made a few patches into the mm subsystem some simply inspired by researching for the articles.

Thank you, this is great!

Re: Linux Memory Management FAQ

#30

"Virtual addresses are the size of a CPU register. On 32 bit systems each process has 4 gigabytes of virtual address space all to itself, which is often more memory than the system actually has." I guess this is not the most up-to-date document?

On 32-bit systems, 4 GiB is indeed often more memory than the system has (think 512 MiB for some Raspberry Pis). And on 64-bit x86 systems each process has 256 PiB, which is also more memory than the system has.
Post reply on HN