Skip to content

lua-lsm: fix unregister and module lifetime handling#16

Open
chenzongyao200127 wants to merge 5 commits into
openanolis:lua-lsmfrom
chenzongyao200127:lua-lsm-unregister-lifetime-fixes
Open

lua-lsm: fix unregister and module lifetime handling#16
chenzongyao200127 wants to merge 5 commits into
openanolis:lua-lsmfrom
chenzongyao200127:lua-lsm-unregister-lifetime-fixes

Conversation

@chenzongyao200127
Copy link
Copy Markdown
Collaborator

Lua-LSM module unregister has to coordinate several lifetimes at once: the global module list protected by modules_ss SRCU, per-VM loaded module references, shared dictionaries cached in Lua userdata, and the contexts where VM teardown is allowed to run.

This series keeps those pieces ordered so unregister no longer frees state that can still be reached from an existing Lua VM, and so lazy unload can finish modules once the last VM-local reference is gone.

The series contains these commits:

  • lua-lsm: wait for SRCU readers before freeing module
  • lua-lsm: fix shared dict lifetime on unregister
  • lua-lsm: avoid leaking shared dict refs on userdata failure
  • lua-lsm: avoid Lua teardown from task_call_func
  • lua-lsm: finalize drained modules after lazy unload

Main fixes:

  • Wait for modules_ss SRCU readers before freeing an unregistered module.
  • Keep shared dictionaries refcounted while Lua userdata can still access them.
  • Tombstone shared dictionaries at unregister so new lookups fail cleanly.
  • Avoid taking shared-dict references before userdata exists to release them.
  • Stop running Lua VM teardown through task_call_func(), which can execute under task/runqueue locks.
  • Let non-current task VMs purge unloading modules lazily on their next Lua-LSM entry.
  • Queue final teardown for zombie modules once lazy purge drains nloaded to zero.

Please use Rebase and merge, or another merge mode that preserves the individual commits. Please do not squash this PR, since each commit has its own kernel-style subject and message.

Validation:

  • ./scripts/checkpatch.pl --git origin/lua-lsm..lua-lsm-unregister-lifetime-fixes
  • git diff --check origin/lua-lsm..lua-lsm-unregister-lifetime-fixes

Signed-off-by: Zongyao Chen ZongYao.Chen@linux.alibaba.com

Lua-LSM publishes module pointers under modules_ss SRCU. The unregister
path removes a module from the list before freeing it, but readers that
already entered the SRCU read-side critical section may still hold the
old pointer.

Wait for an SRCU grace period after unlinking the module and before
freeing its storage.

Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
shared[name] caches a Lua userdata that can outlive module unregister.
The userdata used to hold a raw kvcache_dict pointer, while unregister
freed the backing shared dict before every loaded VM was purged.

If unregister left the module busy, later shared-dict access could
dereference freed memory.

Store a refcounted shared-dict wrapper in the userdata, tombstone shared
dicts when unregister starts, and drop the module list reference only
once unregister can finish.

Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
newshdict() allocates Lua userdata and can raise a Lua allocation error
before any userdata exists to run the shared-dict __gc method.

Allocate the userdata slot before taking the per-userdata shared-dict
reference. Once the userdata exists, store the referenced shdict in it
so later GC can drop the reference even if the following table update
fails.

Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
task_call_func() may run callbacks under pi_lock and, for runnable
tasks, the runqueue lock. The unregister path used it to remove modules
from other tasks' Lua VMs, which updates Lua tables and can run a full
Lua GC.

Stop doing remote task VM teardown from task_call_func(). Unregister now
purges only the current task and per-cpu Lua VMs directly; other task
VMs purge unloading modules lazily when they next enter Lua-LSM. Modules
that still have loaded VMs remain zombie and unregister returns -EBUSY
until the remaining VMs have purged them.

Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Lazy unload can drop a module's last VM-local reference after
unregister() has already returned -EBUSY. In that case the module
used to stay on the unloading list until another unregister() retried
the final teardown.

Queue a worker when lazy purge or task teardown drains nloaded to zero.
The worker detaches the drained zombie under modules_mutex, waits for
the modules_ss SRCU grace period, and then frees the module outside
the mutex. Also skip purge attempts once nloaded is already zero and
make lua_modules_free() explicitly rely on the caller's existing SRCU
read-side protection.

Signed-off-by: Zongyao Chen <ZongYao.Chen@linux.alibaba.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant