]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: hlua: take the global Lua lock inside a global function
authorWilly Tarreau <w@1wt.eu>
Fri, 20 Aug 2021 13:47:25 +0000 (15:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Aug 2021 15:33:26 +0000 (17:33 +0200)
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.

src/hlua.c

index 7eec25ce9e982b5e66650c44f2491dae9cbb1ca6..8ba8aad957fa02c8813554fa2f9f9b9da6810ad9 100644 (file)
@@ -144,16 +144,29 @@ static char **per_thread_load = NULL;
 
 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; \
@@ -168,7 +181,7 @@ lua_State *hlua_init_state(int thread_id);
        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) \
@@ -1358,7 +1371,7 @@ static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
         * label "resume_execution".
         */
        if (lua->state_id == 0)
-               HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock);
+               lua_take_global_lock();
 
 resume_execution:
 
@@ -1506,7 +1519,7 @@ resume_execution:
 
        /* 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;
 }