On Thu, Jul 6, 2023 at 10:22 AM Christian Göttsche <cgzones@xxxxxxxxxxxxxx> wrote: > > Add support to check for neverallow assertions in parallel. Since the > policy is not modified during those checks there needs to be no > extensive locking. > > The checks are run by semodule(8) if the semanage.conf(5) setting > expand-check is set. > > Implement the parallel procedure via OpenMP, to minimize code changes > and to allow users a simple way to enable or disable the functionality > at build time. Currently the support opt-in. > > Example benchmark: > > Benchmark 1: ./test_load_wip.sh (serial) > Time (mean ± σ): 3.485 s ± 0.019 s [User: 0.003 s, System: 0.002 s] > Range (min … max): 3.455 s … 3.501 s 5 runs > > Benchmark 1: ./test_load_wip.sh (parallel) > Time (mean ± σ): 2.443 s ± 0.035 s [User: 0.004 s, System: 0.001 s] > Range (min … max): 2.411 s … 2.500 s 5 runs > > Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> Needs a "-fopenmp" when building. I am not seeing very much change (1.8 sec originally, 1.6 sec with this patch). Jim > --- > libsepol/cil/src/cil_binary.c | 60 ++++++++++++++++++++++++++++------- > 1 file changed, 48 insertions(+), 12 deletions(-) > > diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c > index c4ee2380..7f6212e3 100644 > --- a/libsepol/cil/src/cil_binary.c > +++ b/libsepol/cil/src/cil_binary.c > @@ -4828,8 +4828,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct > > rc = check_assertion(pdb, rule); > if (rc == CIL_TRUE) { > - *violation = CIL_TRUE; > - rc = __cil_print_neverallow_failure(db, node); > + #pragma omp critical (output) > + { > + *violation = CIL_TRUE; > + rc = __cil_print_neverallow_failure(db, node); > + } > if (rc != SEPOL_OK) { > goto exit; > } > @@ -4850,8 +4853,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct > rule->xperms = item->data; > rc = check_assertion(pdb, rule); > if (rc == CIL_TRUE) { > - *violation = CIL_TRUE; > - rc = __cil_print_neverallow_failure(db, node); > + #pragma omp critical (output) > + { > + *violation = CIL_TRUE; > + rc = __cil_print_neverallow_failure(db, node); > + } > if (rc != SEPOL_OK) { > goto exit; > } > @@ -4876,18 +4882,48 @@ exit: > > static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation) > { > - int rc = SEPOL_OK; > - struct cil_list_item *item; > + int rc_sync = SEPOL_OK; > + > + #pragma omp parallel > + { > + > + #pragma omp single > + { > + > + struct cil_list_item *item; > + cil_list_for_each(item, neverallows) { > + > + struct cil_tree_node *node = item->data; > + int rc_test; > + > + #pragma omp task default(none) firstprivate(node, db, pdb, violation) shared(rc_sync) untied > + { > + int rc_task = cil_check_neverallow( > + db, > + pdb, > + node, > + violation); > + > + if (rc_task != SEPOL_OK) { > + #pragma omp atomic write > + rc_sync = rc_task; > + } > + } > + > + #pragma omp atomic read > + rc_test = rc_sync; > + > + if (rc_test != SEPOL_OK) > + break; > + > + } > > - cil_list_for_each(item, neverallows) { > - rc = cil_check_neverallow(db, pdb, item->data, violation); > - if (rc != SEPOL_OK) { > - goto exit; > } > + > + #pragma omp taskwait > } > > -exit: > - return rc; > + return rc_sync; > } > > static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) > -- > 2.40.1 >