Patrick Baggett
2015-Feb-25 16:59 UTC
[Nouveau] [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
On Wed, Feb 25, 2015 at 10:35 AM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:> pthread_mutex_lock had *better* imply a compiler barrier across which > code can't be moved... which is very different from the printf case > where it might have done it due to register pressure or who knows > what. >In the dummy function, register pressure was certainly not an issue, but point taken. Still, a compiler barrier prevents reordering like: x = *a; y = *a; pthread_mutex_lock() This changes the external visibility ordering and is certainly NOT ok. However, I contend that it doesn't stop: const int loaded = *a; x = loaded; pthread_mutex_lock(); y = loaded; Because this doesn't change the external visibility behavior, it just changes whether a value is reloaded. It doesn't break the ordering of a memory barrier at all.> If code like > > x = *a; > pthread_mutex_lock or unlock or __memory_barrier() > y = *a; > > doesn't cause a to get loaded twice, then the compiler's in serious > trouble. Basically functions like pthread_mutex_lock imply that all > memory is changed to the compiler, and thus need to be reloaded. > > Well, I've said before and I might be alone, but I disagree with you. Thecompiler is under no requirement to reload (*a) because a lock was changed. It does, but it doesn't have to. It's fine if you guys don't want to change it. It may never be a problem with gcc. This is the definition of pthread_mutex_lock() in glibc. There aren't any magic hints that this invalidates memory: extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROWNL __nonnull ((1)); THOWNL is attribute((nothrow)). -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20150225/1d46e029/attachment.html>
Ilia Mirkin
2015-Feb-25 17:05 UTC
[Nouveau] [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
On Wed, Feb 25, 2015 at 11:59 AM, Patrick Baggett <baggett.patrick at gmail.com> wrote:>> If code like >> >> x = *a; >> pthread_mutex_lock or unlock or __memory_barrier() >> y = *a; >> >> doesn't cause a to get loaded twice, then the compiler's in serious >> trouble. Basically functions like pthread_mutex_lock imply that all >> memory is changed to the compiler, and thus need to be reloaded. >> > Well, I've said before and I might be alone, but I disagree with you. The > compiler is under no requirement to reload (*a) because a lock was changed. > It does, but it doesn't have to. It's fine if you guys don't want to change > it. It may never be a problem with gcc. > > This is the definition of pthread_mutex_lock() in glibc. There aren't any > magic hints that this invalidates memory: > > extern int pthread_mutex_lock (pthread_mutex_t *__mutex) > __THROWNL __nonnull ((1)); > > THOWNL is attribute((nothrow)).Hm, this is actually a little worrying. Maarten, thoughts? I would have assumed there'd be a __attribute__((some_magic_thing)) in there. -ilia
Maarten Lankhorst
2015-Feb-25 17:13 UTC
[Nouveau] [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
Hey, On 25-02-15 18:05, Ilia Mirkin wrote:> On Wed, Feb 25, 2015 at 11:59 AM, Patrick Baggett > <baggett.patrick at gmail.com> wrote: >>> If code like >>> >>> x = *a; >>> pthread_mutex_lock or unlock or __memory_barrier() >>> y = *a; >>> >>> doesn't cause a to get loaded twice, then the compiler's in serious >>> trouble. Basically functions like pthread_mutex_lock imply that all >>> memory is changed to the compiler, and thus need to be reloaded. >>> >> Well, I've said before and I might be alone, but I disagree with you. The >> compiler is under no requirement to reload (*a) because a lock was changed. >> It does, but it doesn't have to. It's fine if you guys don't want to change >> it. It may never be a problem with gcc. >> >> This is the definition of pthread_mutex_lock() in glibc. There aren't any >> magic hints that this invalidates memory: >> >> extern int pthread_mutex_lock (pthread_mutex_t *__mutex) >> __THROWNL __nonnull ((1)); >> >> THOWNL is attribute((nothrow)). > > Hm, this is actually a little worrying. Maarten, thoughts? I would > have assumed there'd be a __attribute__((some_magic_thing)) in there.In general things don't get optimized across function calls, except in case of inlinable functions. And for compiler attributes it's the opposite,__attribute__((const)) and __attribute((pure)) can be used to indicate some kind of safety to optimize across functions. https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html ~Maarten
Apparently Analagous Threads
- [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
- [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
- [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
- [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.
- [PATCH 2/2] nouveau: Do not add most bo's to the global bo list.