Live data from Hacker News

Async hazard: MMAP is blocking IO

huonw.github.io

111–119 of 119 posts

Re: Async hazard: MMAP is blocking IO

#111
post #79
post #77

Earlier quoted context omitted.

> changes in the page table block the whole process, doesn't matter what combination of concurrency models you're using. I don't think that's necessarily true --- adding a mapping doesn't need to stop other threads that share a page table unless they're also modifying the page table. I don't think the TLB would cache an unmapped entry, but even if it did, the page fault handler will check, see that it's fine and resu…

And even if other threads are contending for the page table lock, the kernel doesn’t hold that lock for the entire duration of the I/O. Only for the tiny fraction of that duration where the kernel is spending CPU time doing bookkeeping. For the rest of the time, during which the system is just waiting for the disk, the thread that triggered the page-in is still blocked, but other threads can do whatever they want, in…

> From what I’ve read on LWN, contention on the page table lock (mmap_sem / mmap_lock) has been a real and perennial issue for Linux, especially on servers with huge numbers of CPUs; but it’s a far smaller effect than what this post is talking about.

...and either way, that's kernel lock contention, not blocking IO.

Re: Async hazard: MMAP is blocking IO

#112
post #49
post #41

Earlier quoted context omitted.

Making it work asynchronously would require the compiler to split the memory access into two parts, a non-blocking IO dispatch and a blocking access to the mapped address. The OS would need to support that, however, and the language would need to keep track of what is a materialised array and what’s not.

as i understand, mmap is only efficient because it can leverage hardware support for trapping into the kernel when a page needs to be loaded to satisfy an access attempt. i think adding software indirection to every access in the mapped region would be really slow. i think a better answer would be to impose more structure on the planned memory access, then maybe given some constraints (like say, "this loop is embarra…

Normal syscalls also "leverage hardware support for trapping into the kernel". Mmap is usually used because it is a simple way to do 0-copy disk I/O.

Re: Async hazard: MMAP is blocking IO

#113
post #74

Earlier quoted context omitted.

Do you have info about current (production) implementations that increase the number of workers? In https://tokio.rs/blog/2020-04-preemption#a-note-on-blocking (2020), there's reference to .NET doing this, and an explicit suggestion that Go, Erlang and Java do not, as well as discussion of why Tokio did not.

Yes, it is .NET as Tokio blog post references. Unfortunately, it does not appear to look into .NET's implementation with sufficient detail and as a result gets its details somewhat wrong. Starting with .NET 6, there are two mechanisms that determine active ThreadPool's active thread count: hill-climbing algorithm and blocking detection. Hill-climbing is the mechanism that both Tokio blog post and the articles it refe…

Thanks for the up-to-date info.

> .NET 6

(I’m under the impression that this was released in 2021, whereas the linked Tokio post is from 2020. Hopefully that frames the Tokio post’s more accurately.)

Re: Async hazard: MMAP is blocking IO

#114
post #94

Earlier quoted context omitted.

Absolutely: if the user page you read into experiences an uncorrectable ECC error in strlen(), you get SIGBUS. Friends don't let friends write code to attempt recovery from hardware failures.

ECC errors of a magnitudes lower chance to happen than broken file system

Depends on who you buy hardware from :)

How about swap then: the user page you read() into might get swapped out, and an I/O error might occur when strlen() faults it back in. I can't remember if you get SEGV or BUS in that case... but it's certainly fatal.

Re: Async hazard: MMAP is blocking IO

#115
post #67

While the general point the article is making is correct there are some issues. - (minor issue) async example is artificially limited to 1 thread (the article states that). The issue is comparing 8 OS threads no async to 1 thread async is fundamentally not very useful as long as you didn't pin all threads to the same physical core.. So in general you should compare something async with num_cpus threads vs. num_cpus*X…

(Author here) > The singled thread async "traditional IO" example is NOT single threaded The threads backing the single-threaded IO are an implementation detail of fulfilling the `.read().await` calls. The key is that there's a single coordinator thread that's issuing all the work, with the user-space runtime multiplexing tasks on that thread. I thought the fact that the "start a request and come back when it is fini…

yes no of the issues are affecting the outcome of the blog about memory mapped files

> The threads backing the single-threaded IO are an implementation detail of fulfilling the `.read().await` calls.

IMHO it's not just an implementation detail, it's a very relevant design aspect for anything related to blocking and benchmarks. Through yes it doesn't matter to much for this blog.

Re: Async hazard: MMAP is blocking IO

#116
post #74

Earlier quoted context omitted.

Do you have info about current (production) implementations that increase the number of workers? In https://tokio.rs/blog/2020-04-preemption#a-note-on-blocking (2020), there's reference to .NET doing this, and an explicit suggestion that Go, Erlang and Java do not, as well as discussion of why Tokio did not.

Yes, it is .NET as Tokio blog post references. Unfortunately, it does not appear to look into .NET's implementation with sufficient detail and as a result gets its details somewhat wrong. Starting with .NET 6, there are two mechanisms that determine active ThreadPool's active thread count: hill-climbing algorithm and blocking detection. Hill-climbing is the mechanism that both Tokio blog post and the articles it refe…

UPD: Ouch, messed up the Rust lib import path on Unix systems in the demo. Now fixed.

Re: Async hazard: MMAP is blocking IO

#117
post #66

Earlier quoted context omitted.

Your definition of blocking is a bit different from my own. Synchronous is not always blocking. If the data is there, ready to go, there is no "blocking." If you consider all memory reads to be "blocking", then everything must be "blocking". The executable code must, after all, be read by the processor. In an extreme case, the entire executable could be paged out to disk! This interpretation is not what most people m…

you don't yield to your cooperative-multitasking runtime during reading from it, which is obviously what everyone in this thread means, and it's not helpful to start telling them "you're using the word blocking wrong" apropos of nothing

Why would it yield when reading from local memory? Are there any cooperative environments that do that? Seems like an unusual expectation.

Re: Async hazard: MMAP is blocking IO

#118
I used to really like mmap for a wide range of uses (having noticed its performance in the BLAST DNA/protein search command) but over time I've come to consider it a true expert tool with deep subtlety, like a palantir.

Re: Async hazard: MMAP is blocking IO

#119
post #49

Earlier quoted context omitted.

as i understand, mmap is only efficient because it can leverage hardware support for trapping into the kernel when a page needs to be loaded to satisfy an access attempt. i think adding software indirection to every access in the mapped region would be really slow. i think a better answer would be to impose more structure on the planned memory access, then maybe given some constraints (like say, "this loop is embarra…

Normal syscalls also "leverage hardware support for trapping into the kernel". Mmap is usually used because it is a simple way to do 0-copy disk I/O.

i can't think of any other syscall that makes use of tlb caches and page fault machinery to enter the kernel as needed in response to ordinary user space memory access.
Post reply on HN