Re: [PATCH 1/1] dix: Hold the input_lock() when accessing the miEventQueue through checkForInput

2016-09-19 Thread Keith Packard
Jeremy Huddleston Sequoia  writes:

> Thoughts?

Sounds like a plan. For functions which aren't called frequently, just
grabbing the input_lock would be fine, I was mostly concerned with the
dispatch loop.

-- 
-keith


signature.asc
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 1/1] dix: Hold the input_lock() when accessing the miEventQueue through checkForInput

2016-09-19 Thread Jeremy Huddleston Sequoia

> On Sep 19, 2016, at 09:52, Keith Packard  wrote:
> 
> Jeremy Huddleston Sequoia  writes:
> 
>> Yeah, I made the change mainly to shutup the analyzer while I was
>> looking for other races.  I decided to propose it in case we want to
>> be strict here.
> 
> Thanks. Keeping our request processing overhead low seems important
> enough to me that we should skip this patch, although perhaps adding a
> comment before the test noting that we are intentionally not holding the
> input lock.
> 
> Is there some way we can annotate the code to silence the analyzer in
> these cases?

The annotation is at a per-function level.  We can basically say "if you notice 
data races in this funciton, don't bother reporting them".  I'm doing this for 
a similar case where we want to limit overhead on the fastpath in 
darwinEvents.c.  In the code below, TSan would normally complain about the read 
of mieqInitialized without holding the mieqInitializedMutex, but we know it's 
actually safe in this case.

We could add something like _X_NOTSAN to Xfuncproto.h to cover this and then 
break out the actual comparisons into an inline function with that attribute.  
Breaking that out into separate inline functions allows us to surgically apply 
no_sanitize_thread. 

Thoughts?


static BOOL mieqInitialized;
static pthread_mutex_t mieqInitializedMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t mieqInitializedCond = PTHREAD_COND_INITIALIZER;

#ifdef __has_feature
# if __has_feature(thread_sanitizer)
#  define __tsan_ignore __attribute__((no_sanitize_thread))
# else
#  define __tsan_ignore /**/
# endif
#else
# define __tsan_ignore /**/
#endif

__tsan_ignore
extern inline void
wait_for_mieq_init(void)
{
if (!mieqInitialized) {
pthread_mutex_lock(&mieqInitializedMutex);
while (!mieqInitialized) {
pthread_cond_wait(&mieqInitializedCond, &mieqInitializedMutex);
}
pthread_mutex_unlock(&mieqInitializedMutex);
}
}

__tsan_ignore
static inline void
signal_mieq_init(void)
{
pthread_mutex_lock(&mieqInitializedMutex);
mieqInitialized = TRUE;
pthread_cond_broadcast(&mieqInitializedCond);
pthread_mutex_unlock(&mieqInitializedMutex);
}



smime.p7s
Description: S/MIME cryptographic signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 1/1] dix: Hold the input_lock() when accessing the miEventQueue through checkForInput

2016-09-19 Thread Keith Packard
Jeremy Huddleston Sequoia  writes:

> Yeah, I made the change mainly to shutup the analyzer while I was
> looking for other races.  I decided to propose it in case we want to
> be strict here.

Thanks. Keeping our request processing overhead low seems important
enough to me that we should skip this patch, although perhaps adding a
comment before the test noting that we are intentionally not holding the
input lock.

Is there some way we can annotate the code to silence the analyzer in
these cases?

-- 
-keith


signature.asc
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 1/1] dix: Hold the input_lock() when accessing the miEventQueue through checkForInput

2016-09-19 Thread Jeremy Huddleston Sequoia

> On Sep 19, 2016, at 08:30, Keith Packard  wrote:
> 
> Jeremy Huddleston Sequoia  writes:
> 
>> ==
>> WARNING: ThreadSanitizer: data race (pid=4943)
>>  Read of size 4 at 0x00010c4e3854 by thread T8:
>>#0 WaitForSomething WaitFor.c:237 (X11.bin+0x00010049216c)
>>#1 Dispatch dispatch.c:413 (X11.bin+0x000100352ed9)
>>#2 dix_main main.c:287 (X11.bin+0x00010036e894)
>>#3 server_thread quartzStartup.c:66 (X11.bin+0x000100039e63)
>> 
>>  Previous write of size 4 at 0x00010c4e3854 by thread T12 (mutexes: write 
>> M856, write M1976):
>>#0 mieqEnqueue mieq.c:263 (X11.bin+0x000100448d14)
>>#1 DarwinSendDDXEvent darwinEvents.c:641 (X11.bin+0x000100033613)
>>#2 DarwinProcessFDAdditionQueue_thread darwinEvents.c:338 
>> (X11.bin+0x000100032039)
> 
> I'm not sure I want to resolve this "bug" -- the event queue has been
> designed to be safe in a lockless threaded environment as it was originally
> designed to directly map a kernel address which would be modified at
> interrupt time. Is there an actual issue with the design?

Yeah, I made the change mainly to shutup the analyzer while I was looking for 
other races.  I decided to propose it in case we want to be strict here.

I don't see an absolute need to do this.  The code looks perfectly safe to me 
without this change because the data is only read and compared.  There could be 
issues with reads being nonatomic and getting back some meaningless value, but 
the outcome of that failure would just be an extra unneeded call into 
ProcessInputEvents(), which is perfectly safe.



smime.p7s
Description: S/MIME cryptographic signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH 1/1] dix: Hold the input_lock() when accessing the miEventQueue through checkForInput

2016-09-19 Thread Keith Packard
Jeremy Huddleston Sequoia  writes:

> ==
> WARNING: ThreadSanitizer: data race (pid=4943)
>   Read of size 4 at 0x00010c4e3854 by thread T8:
> #0 WaitForSomething WaitFor.c:237 (X11.bin+0x00010049216c)
> #1 Dispatch dispatch.c:413 (X11.bin+0x000100352ed9)
> #2 dix_main main.c:287 (X11.bin+0x00010036e894)
> #3 server_thread quartzStartup.c:66 (X11.bin+0x000100039e63)
>
>   Previous write of size 4 at 0x00010c4e3854 by thread T12 (mutexes: write 
> M856, write M1976):
> #0 mieqEnqueue mieq.c:263 (X11.bin+0x000100448d14)
> #1 DarwinSendDDXEvent darwinEvents.c:641 (X11.bin+0x000100033613)
> #2 DarwinProcessFDAdditionQueue_thread darwinEvents.c:338 
> (X11.bin+0x000100032039)

I'm not sure I want to resolve this "bug" -- the event queue has been
designed to be safe in a lockless threaded environment as it was originally
designed to directly map a kernel address which would be modified at
interrupt time. Is there an actual issue with the design?

-- 
-keith


signature.asc
Description: PGP signature
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

[PATCH 1/1] dix: Hold the input_lock() when accessing the miEventQueue through checkForInput

2016-09-19 Thread Jeremy Huddleston Sequoia
==
WARNING: ThreadSanitizer: data race (pid=4943)
  Read of size 4 at 0x00010c4e3854 by thread T8:
#0 WaitForSomething WaitFor.c:237 (X11.bin+0x00010049216c)
#1 Dispatch dispatch.c:413 (X11.bin+0x000100352ed9)
#2 dix_main main.c:287 (X11.bin+0x00010036e894)
#3 server_thread quartzStartup.c:66 (X11.bin+0x000100039e63)

  Previous write of size 4 at 0x00010c4e3854 by thread T12 (mutexes: write 
M856, write M1976):
#0 mieqEnqueue mieq.c:263 (X11.bin+0x000100448d14)
#1 DarwinSendDDXEvent darwinEvents.c:641 (X11.bin+0x000100033613)
#2 DarwinProcessFDAdditionQueue_thread darwinEvents.c:338 
(X11.bin+0x000100032039)

  Location is global 'miEventQueue' at 0x00010c4e3850 (X11.bin+0x0001005ab854)

  Mutex M856 (0x00010c4c8c80) created at:
#0 pthread_mutex_lock :144 
(libclang_rt.tsan_osx_dynamic.dylib+0x000321fe)
#1 DarwinListenOnOpenFD darwinEvents.c:300 (X11.bin+0x000100031607)
#2 socket_handoff bundle-main.c:288 (X11.bin+0x00012b40)
#3 __do_request_fd_handoff_socket_block_invoke bundle-main.c:379 
(X11.bin+0x000129ba)
#4 __tsan::invoke_and_release_block(void*) :144 
(libclang_rt.tsan_osx_dynamic.dylib+0x0005d97b)
#5 _dispatch_client_callout :33 (libdispatch.dylib+0x20ef)

  Mutex M1976 (0x00010c4e3d68) created at:
#0 pthread_mutex_init :144 
(libclang_rt.tsan_osx_dynamic.dylib+0x000253c3)
#1 input_lock inputthread.c:103 (X11.bin+0x00010049fd10)
#2 TimerSet WaitFor.c:343 (X11.bin+0x0001004926c2)
#3 RootlessQueueRedisplay rootlessScreen.c:594 (X11.bin+0x000100065d7f)
#4 RootlessInstallColormap rootlessScreen.c:514 (X11.bin+0x000100069f1a)
#5 miSpriteInstallColormap misprite.c:562 (X11.bin+0x000100467095)
#6 miCreateDefColormap micmap.c:270 (X11.bin+0x000100440399)
#7 DarwinScreenInit darwin.c:285 (X11.bin+0x0001000303bb)
#8 AddScreen dispatch.c:3908 (X11.bin+0x00010036c417)
#9 InitOutput darwin.c:671 (X11.bin+0x00010002fdeb)
#10 dix_main main.c:197 (X11.bin+0x00010036e228)
#11 server_thread quartzStartup.c:66 (X11.bin+0x000100039e63)

  Thread T8 (tid=4198779, running) created by main thread at:
#0 pthread_create :144 
(libclang_rt.tsan_osx_dynamic.dylib+0x00024490)
#1 create_thread quartzStartup.c:78 (X11.bin+0x000100039dad)
#2 QuartzInitServer quartzStartup.c:95 (X11.bin+0x000100039c16)
#3 X11ApplicationMain X11Application.m:1238 (X11.bin+0x00010001cde4)
#4 X11ControllerMain X11Controller.m:984 (X11.bin+0x00010002a642)
#5 server_main quartzStartup.c:136 (X11.bin+0x00010003a03b)
#6 do_start_x11_server bundle-main.c:436 (X11.bin+0x00012eb5)
#7 _Xstart_x11_server mach_startupServer.c:189 (X11.bin+0x00014e99)
#8 mach_startup_server mach_startupServer.c:399 (X11.bin+0x00015734)
#9 mach_msg_server mach_msg.c:563 (libsystem_kernel.dylib+0x00012186)
#10 start :29 (libdyld.dylib+0x5254)

  Thread T12 (tid=4198797, running) created by thread T8 at:
#0 pthread_create :144 
(libclang_rt.tsan_osx_dynamic.dylib+0x00024490)
#1 create_thread darwinEvents.c:121 (X11.bin+0x000100031ecf)
#2 DarwinEQInit darwinEvents.c:365 (X11.bin+0x000100031860)
#3 InitInput darwin.c:571 (X11.bin+0x00010002ea09)
#4 dix_main main.c:261 (X11.bin+0x00010036e7ce)
#5 server_thread quartzStartup.c:66 (X11.bin+0x000100039e63)

SUMMARY: ThreadSanitizer: data race WaitFor.c:237 in WaitForSomething
==
==
WARNING: ThreadSanitizer: data race (pid=22841)
  Write of size 4 at 0x000105bbd864 by main thread (mutexes: write M1945):
#0 mieqEnqueue mieq.c:263 (X11.bin+0x000100448cf4)
#1 DarwinSendDDXEvent darwinEvents.c:642 (X11.bin+0x000100033693)
#2 -[X11Controller set_window_menu:] X11Controller.m:275 
(X11.bin+0x0001000222fd)
#3 -[X11Application set_window_menu:] X11Application.m:486 
(X11.bin+0x000100018b44)
#4 -[X11Application handleMachMessage:] X11Application.m:177 
(X11.bin+0x000100016678)
#5 __NSFireMachPort :69 (Foundation+0x0009b62b)
#6 X11ControllerMain X11Controller.m:984 (X11.bin+0x00010002a5f2)
#7 server_main quartzStartup.c:136 (X11.bin+0x000100039ffb)
#8 do_start_x11_server bundle-main.c:436 (X11.bin+0x00012e65)
#9 _Xstart_x11_server mach_startupServer.c:189 (X11.bin+0x00014e49)
#10 mach_startup_server mach_startupServer.c:399 (X11.bin+0x000156e4)
#11 mach_msg_server mach_msg.c:563 (libsystem_kernel.dylib+0x00012186)
#12 start :29 (libdyld.dylib+0x5254)

  Previous read of size 4 at 0x000105bbd864 by thread T7:
#0 Dispatch dispatch.c:434 (X11.bin+0x000100352fc8)
#1 dix_main main.c:287 (X11.bin+0x00010036e874)
#2 server_thread quartzStartup.c:66 (X11.bin+0x000100039e23)

  Location is global 'miEventQueue' at 0x000105bbd860 (X11.bin+0x0001005ab864)

  Mutex M1945 (0x000105bbdd78) created at:
#0 pthread_mutex_init :144 
(libclang_rt.tsan_osx_dynamic.dylib+0x000253c3)
#1 input_