Thanks for the detailed answer.

> I believe are safe to assume (as in "would be surprising for an OS to not
> meet):

I take this as the general guideline for OS implementers to implement
such syscall even though it's not explicitly documented anywhere?

> 2. A call to mprotect will not return before the protection request
> semantically takes hold everywhere within the process. If the mprotect()
> call sets a protection that would cause a fault, any operation on any thread
> that happens after this mprotect() call is required to fault. Similarly, if
> the mprotect() call sets a protection that would prevent a fault, any
> operation on any thread that happens after this mprotect() call is required
> to NOT fault.

I believe this assumption is what I'm missing. The way you state it
does make it more clear that the syscall should be doing this
(intuitively at least....)

>> 1. If thread 2 fault, is it guaranteed that this happens after mprotect on
>> thread 1? (Or in another word that sounds less weird, can it observer all
>> load/stores on thread 1 happens before any operations on thread 2 after the
>> fault?)
>
>
> I think this is a "yes". If thread 2 faults *DUE TO* a protection that is
> first set by an mprotect() done by thread1 (note emphasis on the due to
> part), the expectation is that all stores done by thread1 prior to the
> mprotect() call will be visible to any thread2 operations that execute after
> the fault is triggered, and that all loads done by thread 1 before the
> mprotect() call will NOT observe any stores done by thread2 after the fault
> is triggered.

Yes, the implicit assumption I was making for all three cases are that
only thread 1 is removing read access on the page. No other thread
should be doing it (or otherwise synchronized so that they are only
done in distinct global phases) so if thread 2 faults it has to be
**due to** what thread 1 did.

>> 2. The other way around, if thread 2 didn't fault, is it guaranteed that
>> the load happens before mprotect on thread 1? In another word, is it
>> guaranteed that thread 1 will be able to oberve all memory operation thread
>> 2 has done before the load, right after mprotect returns?
>
>
> I don't think that is provided, simply because there is no ordering implied
> or described between the two in the description above. You did not describe
> how Thread1 knows whether or not thread2 has done the (potentially faulting)
> load yet, and whether or not that load had faulted... If you include the
> fact that thread1 receives some indication about whether or not thread2 has
> done the load operation and about whether or not that load had faulted, you
> will have something to hang some ordering assumptions on.
>
> E.g. if you changed the above to say:
>
>  "if thread 2 performed a load that didn't fault, and thread 1 has received
> an indication that this thread 2 load was completed without faulting, is it
> guaranteed that the load happens before mprotect on thread 1? In another
> word, is it guaranteed that, after both the mprotect() call and establishing
> that the thread 2 load operation did not fault, thread 1 will be able to
> oberve all memory operations thread 2 has done before the load?"
>
> Then the answer would be "yes".

Hmm, the difference here is a little too subtle. Maybe I should
clarify my simplified case better.

2.1 (basically the one I showed with code in the linked stackoverflow
question) Say we have the two threads where the only interested part
is (ins pseudo C code)

```
// thread 1
mprotect(p, 4096, PROT_NONE); // Or replace 4096 by the real
userspace-visible page size
a = *ga;

// thread 2
*ga = 1;
*(volatile int*)p; // no segfault happens
```

Where p started readable and the memory pointed by ga starts as 0.
Long after the two threads execute these two pieces of code
concurrently when the two threads are synchronized by other mean (e.g.
both joined by another thread), is it possible that the outcome be
thread 2 had no fault and thread 1 reads 1?

2.2 Or in a way that's similar to what a GC does (one thread mutating
memory and another thread trying to observe it)

if we have (again in pseudo C code)

```
// thread 1
mprotect(p, 4096, PROT_NONE); // Or replace 4096 by the real
userspace-visible page size
a = *ga;
// Wait for thread 2 to fault

// thread 2
int i;
for (i = 0; 1; i++) {
    *ga = i;
    *(volatile int*)p;
}
```

Now suppose thread 2 can check what `i` is when it faults (and ignore
the possibility of overflow.....) and the "wait for thread 2 to fault"
can be done by synchronizing with the signal handler on thread 2, can
we assert that thread 1 will observe that a == i or a + 1 == i? (i.e.
thread 2 can execute at most one cycle "after" mprotect returns on
thread 1)

>
>>
>> 3. Does transitivity work? i.e. if therer's a thread 3 that's also loading
>> from p, and if thread 2 faults on the load while thread 3 doesn't, can we
>> say that thread 2 faults after the mprotect on thread 1 which is after the
>> load on thread 3 and therefore the load (and fault) on thread 2 happens
>> after the load on thread 3?
>
>
> Same as (2) above. You'd need to describe how threads 1 and 2 observe
> whether or not thread 3's load has happened, and whether or not it has
> faulted. Then, depending on how that information is communicated, you would
> be able to establish some ordering.
>
>>
>> Also link to my question on stackoverflow[1]
>>
>> Thanks,
>>
>> Yichao Yu
>>
>>
>> [1]
>> http://stackoverflow.com/questions/43722456/behavior-of-mprotect-with-multiple-threads
>>
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mechanical-sympathy+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to mechanical-sympathy+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to