MINOR: hlua: take the global Lua lock inside a global function
Some users are facing huge CPU usage or even watchdog panics due to
the Lua global lock when many threads compete on it, but they have
no way to see that in the usual dumps. We take the lock at 2 or 3
places only, thus it's trivial to move it to a global function so
that stack dumps will now explicitly show it, increasing the change
that it rings a bell and someone suggests switch to lua-load-per-thread:
Current executing Lua from a stream analyser -- stack traceback:
loop.lua:1: in function line 1
call trace(27):
| 0x5ff157 [48 83 c4 10 5b 5d 41 5c]: wdt_handler+0xf7/0x104
| 0x7fe37fe82690 [48 c7 c0 0f 00 00 00 0f]: libpthread:+0x13690
| 0x614340 [66 48 0f 7e c9 48 01 c2]: main+0x1e8a40
| 0x607b85 [48 83 c4 08 48 89 df 31]: main+0x1dc285
| 0x6070bc [48 8b 44 24 20 48 8b 14]: main+0x1db7bc
| 0x607d37 [41 89 c4 89 44 24 1c 83]: lua_resume+0xc7/0x214
| 0x464ad6 [83 f8 06 0f 87 f1 01 00]: main+0x391d6
| 0x4691a7 [83 f8 06 0f 87 03 20 fc]: main+0x3d8a7
| 0x51dacb [85 c0 74 61 48 8b 5d 20]: sample_process+0x4b/0xf7
| 0x51e55c [48 85 c0 74 3f 64 48 63]: sample_fetch_as_type+0x3c/0x9b
| 0x525613 [48 89 c6 48 85 c0 0f 84]: sess_build_logline+0x2443/0x3cae
| 0x4af0be [4c 63 e8 4c 03 6d 10 4c]: http_apply_redirect_rule+0xbfe/0xdf8
| 0x4af523 [83 f8 01 19 c0 83 e0 03]: main+0x83c23
| 0x4b2326 [83 f8 07 0f 87 99 00 00]: http_process_req_common+0xf6/0x15f6
| 0x4d5b30 [85 c0 0f 85 9f f5 ff ff]: process_stream+0x2010/0x4e18
It also allows "perf top" to directly show the time spent on this lock.
This may be backported to some stable versions as it improves the
overall debuggability.
(cherry picked from commit 1e7bef17df84527d7ae3bb9ee665e3cdf3e017cf)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/hlua.c b/src/hlua.c
index 075477d..83fded6 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -143,16 +143,29 @@
lua_State *hlua_init_state(int thread_id);
+/* This function takes the Lua global lock. Keep this function's visibility
+ * global so that it can appear in stack dumps and performance profiles!
+ */
+void lua_take_global_lock()
+{
+ HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock);
+}
+
+static inline void lua_drop_global_lock()
+{
+ HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock);
+}
+
#define SET_SAFE_LJMP_L(__L, __HLUA) \
({ \
int ret; \
if ((__HLUA)->state_id == 0) \
- HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock); \
+ lua_take_global_lock(); \
if (setjmp(safe_ljmp_env) != 0) { \
lua_atpanic(__L, hlua_panic_safe); \
ret = 0; \
if ((__HLUA)->state_id == 0) \
- HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock); \
+ lua_drop_global_lock(); \
} else { \
lua_atpanic(__L, hlua_panic_ljmp); \
ret = 1; \
@@ -167,7 +180,7 @@
do { \
lua_atpanic(__L, hlua_panic_safe); \
if ((__HLUA)->state_id == 0) \
- HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock); \
+ lua_drop_global_lock(); \
} while(0)
#define SET_SAFE_LJMP(__HLUA) \
@@ -1274,7 +1287,7 @@
* label "resume_execution".
*/
if (lua->state_id == 0)
- HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock);
+ lua_take_global_lock();
resume_execution:
@@ -1419,7 +1432,7 @@
/* This is the main exit point, remove the Lua lock. */
if (lua->state_id == 0)
- HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock);
+ lua_drop_global_lock();
return ret;
}