<bslsk05>
lore.kernel.org: Making sure you're not a bot!
<heat>
thoughts?
<sortie>
heat: I think you're a bot
<heat>
did you make sure?
<sortie>
Alright let's read this
<sortie>
What does pinning a page mean? That it cannot be evicted from physical memory?
<heat>
yes, for DMA etc etc
<heat>
the memory consistency part is the interesting bit
<heat>
i imagine this also heavily affects sortix due to copying every page
<heat>
on fork
<heat>
i feel compelled to say this is ENOTABUG and that fork memory consistency is a lie
<sortie>
I wouldn't say it's a lie, more that it's subject to the same threading memory constraints as everything else, let's read on
<nikolar>
heat: i mean it looks like a very very niche bug to begin with
<heat>
it is
<sortie>
It's an interesting question, I am pondering it, and I generally agree with heat here
<sortie>
POSIX says the usual thing I expected:
<sortie>
> A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, the application shall ensure that the child process only executes async-signal-safe operations until such time as one of the exec functions is successful.
<sortie>
> Any locks held by any thread in the calling process that have been set to be process-shared shall not be held by the child process. For locks held by any thread in the calling process that have not been set to be process-shared, any attempt by the child process to perform any operation on the lock results in undefined behavior (regardless of whether the calling process is single-threaded or multi-threaded).
<heat>
posix is absolutely useless
<heat>
(per usual)
<sortie>
Can you like please stop being like that heat
<heat>
i mean
<sortie>
Any thing I bring it up I gotta hear that
<heat>
i was referring to everything you quoted
<heat>
it tells us nothing of interest
<sortie>
And it's literally saying the stuff here that you want
<heat>
it does not define atomics
simjnd has quit [Ping timeout: 276 seconds]
<heat>
or better, fork() behavior with concurrent atomics
<sortie>
That it does not, and was what I was interested in
<heat>
> any attempt by the child process to perform any operation on the lock results in undefined behavior
<heat>
actually, this just might?
<sortie>
"replica of the calling thread and its entire address space" "For locks held by any thread in the calling process that have not been set to be process-shared, any attempt by the child process to perform any operation on the lock results in undefined behavior" I basically read this as what you can expect, you only get a coherent snapshot of your current thread. If any other thread is mid operation on some memory, you need to obtain those locks, and it's
<sortie>
undefined behavior
<sortie>
heat, also keep noting that I don't consider POSIX the end all arbitrator of truth. It's just a thing that exists. It's generally of interest what it says, but it also has to serve us, operating system vendors and I do violate it from time to time
<sortie>
But that undefined behavior argument is a fair way of saying the semantics that I think we both like
<sortie>
The alternative is stopping all other threads temporarily upon fork, which is unreasonable
GeDaMo has quit [Quit: 0wt 0f v0w3ls.]
<sortie>
My argument here is that a fork() that copies memory - one page at a time, while other threads operate on that memory - is fine, what one might reasonably expect, and even allowed by POSIX. If your forked thread wants to access that memory, it would have to lock that memory, and it can't because it's undefined behavior
<sortie>
And that UB allows making those pages be whatever random memory ordering comes out
<sortie>
This UB in turn gives freedom to implementation. One could use the Linux COW model that's atomic although backed by overcommit, I guess. Or a traditional copy-page-by-page model that never overcommits. Either are theoretically fine solutions for different system applications.
<sortie>
(COW/copy-page-by-page is not intrinsically linked with overcommit, before you inb4 me :P)
<heat>
i was just thinking that :p
<sortie>
Definitely possible to COW without overcommit as long as you make sure the forked process has enough pages reserved
simjnd has joined #osdev
corinne has joined #osdev
<heat>
sortie: i agree that POSIX isnt the arbitrator of truth
<heat>
however, this would be something that should be written down
<heat>
but of course, as per usual standardese, it just handwaves *snapshot*
<sortie>
It's very relevant for application programmers, what promises they can rely on for fork()
<heat>
*snapshot* *UB*
* heat
literally fucking dies
<sortie>
A vague standard is not a bad thing always, heat
<sortie>
It's _good_ for operating systems that we have freedom to implement things in better ways
<heat>
i agree but when you're looking for details it's frustrating :)
<sortie>
It's _bad_ for application programmers that want qualities to rely on
<sortie>
The standard has to strike a good balance between the two
<sortie>
POSIX is usually vague in areas where Unix systems have diverged
<heat>
right. but in the case of atomic usage
<heat>
can you rely on it? no one knows. it's not really UB
<heat>
it's not written down. does snapshot imply you can use atomics? yeah, it does. does any system do "snapshots" like they want to? i would bet no one does
<sortie>
I'd argue that unless the fork has a happens-before relationship with memory accesses in another thread, it's undefined
<heat>
i would agree but POSIX does not mention happens-before ever, i think
<sortie>
And in the other direction too, if another thread writing to memory doesn't have a happens-after-fork-returned relationship, also ub
<heat>
musl locks pedantically do full memory barriers on unlock
<sortie>
You can bet your hat that this fork language predates all the work on memory models
<heat>
anyway i ended up replying in-thread
<heat>
if you want to you can also reply
<heat>
honza will be so confused
<clever>
sortie: factorio uses fork() for async saving
<heat>
why is the isofs guy talking about fork and posix
<clever>
it just forks out an entire child proc, which serializes the state to disk, while the parent keeps running the sim
<sortie>
clever: It works, but only if you go single threaded while invoking fork
<sortie>
Or relying on Linux COW to make fork atomic
<clever>
only one thread survives the forking, but the parent can have more threads
<clever>
there was a qemu fuzzing thing called triforce? that did similar
<heat>
i suppose the parent's threads are stopped from writing to that state
<clever>
it would simulate the guest until it hits a special snapshot signal, and then fork out a child, and re-create all threads in the child
<heat>
until fork returns
<clever>
and then it would simulate the guest a little bit, to fuzz a function
<clever>
then murder the child, and fork out a new one, rewinding all guest state
<clever>
and then fuzz it differently
<sortie>
clever: Read the Linux kernel mailing list email above. The problem is that fork() may copy pages one by one. That means the pages may be in an inconsistent state if the parent wrote to memory while fork() was running. A program like that should stop all the other threads accessing the memory-to-be-written-out while fork is running
<clever>
for factorio, you just need to ensure that no threads are messing with game state, and the child wont deadlock on a mutex that was held in the parent copy of the threads
<clever>
for qemu, the child is meant to be fully functional, so they had to remake all threads
<sortie>
Yep you understood it
<clever>
related to threads, exceptions, and deadlocks
<clever>
my gpu drivers will randomly crash, and the kernel will detect the gpu hang, and hard reset the entire card
<clever>
but all gpu state is lost, so Xorg is told to just give up and reset itself
<clever>
during Xorg de-init, it tries to allocate a replacement framebuffer
<clever>
however, it crashed with a mutex held, and allocating a new FB deadlocks things
nyah has quit [Remote host closed the connection]
nyah has joined #osdev
simjnd has quit [Ping timeout: 252 seconds]
Matt|home has joined #osdev
pog is now known as gog
corinne has quit [Remote host closed the connection]
goliath has joined #osdev
simpl_e has joined #osdev
simjnd has joined #osdev
simjnd has quit [Ping timeout: 276 seconds]
Turn_Left has quit [Read error: Connection reset by peer]
Lucretia has quit [Remote host closed the connection]