Re: [PATCH v2] libselinux: improve performance with pcre matches
Inseob Kim <[email protected]> Fri, 24 Jul 2026 09:52:38 +0900
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CA+QFDK=u3Rejm4mESPiHmJD4QZKdHQuFL3A-idzJ7Oyun4FxXw@mail.gmail.com> |
On Fri, Jul 24, 2026 at 12:44 AM Stephen Smalley <[email protected]> wrote: > > On Thu, Jul 23, 2026 at 4:58 AM Inseob Kim <[email protected]> wrote: > > > > From: Carlo Marcelo Arenas Belón <[email protected]> > > > > Since 30b3e9d2 (libselinux: Workaround for heap overhead of pcre, > > 2023-01-12), performance of PCRE2 matches has been affected due to > > excesive recreation of the match_data in an attempt to reduce memory > > spelling /excessive/ > > > utilization; instead of a workaround, it would be better to address > > the problem and maybe even improve performance in the process. > > > > The issue is that currently the structure that holds PCRE state has > > both a pcre2_code (which is per pattern) and a pcre2_match_data (which > > is per match), forcing us to add a mutex to prevent multiple matches to > > step on each other. > > > > Lets remove the match_data and the mutex and instead allocate one once > > in a thread independent way that could be used and reused, by extending > > our pthread interface to not only store TLS variables but also retrieve > > them, and then use one of those. > > > > Since we are not interested on the capture groups (if any) lets only > > allocate 1 pair which is all that will be needed and change the logic > > so that a return of 0 (which means the pattern matched but there were > > not enough capture spots) is also considered a match. > > > > This will ensure that the memory use would be bound to the number of > > concurrent matches instead of the number of patterns and therefore > > reduce the impact that recent changes on the way that the frames used > > for matching are allocated might had brough since 10.41 was released. > > should this be "have brought"? And is 10.41 the pcre version? > > > > > For cases where threads are not available, just keep it working in slow > > mode as done before the workaround was reverted. > > > > Signed-off-by: Carlo Marcelo Arenas Belón <[email protected]> > > Signed-off-by: Inseob Kim <[email protected]> > > --- > > v2: > > - Fix the dual destructor antipattern by separating the thread-exit > > destructor (match_data_thread_free) from the library-unload key cleanup > > (match_data_key_destroy, annotated with __attribute__((destructor))). > > This won't free the data on dlclose() of libselinux, right? Not sure if we care. You're correct, it will leak on dlclose(). And I believe we don't care. Freeing that memory would require maintaining a global list of active threads, which is infeasible. And dynamically unloading libselinux is extremely rare anyway. > > > - Eliminate the data race on match_data_key_initialized by using pthread_once > > (via __selinux_once) for safe, race-free initialization of match_data_key. > > - Remove redundant match_data_initialized thread-local variable, making > > lookups purely based on __selinux_getspecific(). > > ---