mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

The existing fncache can get large in testing situations. As the bucket array is a fixed size this leads to it degrading to O(n) performance. Use a regular hashmap that can dynamically reallocate its array. Before: ``` $ time perf test "Parsing of PMU event table metrics" 10.3: Parsing of PMU event table metrics : Ok 10.4: Parsing of PMU event table metrics with fake PMUs : Ok real 0m14.132s user 0m17.806s sys 0m0.557s ``` After: ``` $ time perf test "Parsing of PMU event table metrics" 10.3: Parsing of PMU event table metrics : Ok 10.4: Parsing of PMU event table metrics with fake PMUs : Ok real 0m13.287s user 0m13.026s sys 0m0.532s ``` Committer notes: root@number:~# grep -m1 'model name' /proc/cpuinfo model name : AMD Ryzen 9 9950X3D 16-Core Processor root@number:~# Before: root@number:~# time perf test "Parsing of PMU event table metrics" 10.3: Parsing of PMU event table metrics : Ok 10.4: Parsing of PMU event table metrics with fake PMUs : Ok real 0m9.277s user 0m9.979s sys 0m0.055s root@number:~# After: root@number:~# time perf test "Parsing of PMU event table metrics" 10.3: Parsing of PMU event table metrics : Ok 10.4: Parsing of PMU event table metrics with fake PMUs : Ok real 0m9.296s user 0m9.361s sys 0m0.063s root@number:~# Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Tested-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Xu Yang <xu.yang_2@nxp.com> Link: https://lore.kernel.org/r/20250512194622.33258-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
68 lines
1.4 KiB
C
68 lines
1.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* Manage a cache of file names' existence */
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <linux/compiler.h>
|
|
#include "fncache.h"
|
|
#include "hashmap.h"
|
|
|
|
static struct hashmap *fncache;
|
|
|
|
static size_t fncache__hash(long key, void *ctx __maybe_unused)
|
|
{
|
|
return str_hash((const char *)key);
|
|
}
|
|
|
|
static bool fncache__equal(long key1, long key2, void *ctx __maybe_unused)
|
|
{
|
|
return strcmp((const char *)key1, (const char *)key2) == 0;
|
|
}
|
|
|
|
static void fncache__init(void)
|
|
{
|
|
fncache = hashmap__new(fncache__hash, fncache__equal, /*ctx=*/NULL);
|
|
}
|
|
|
|
static struct hashmap *fncache__get(void)
|
|
{
|
|
static pthread_once_t fncache_once = PTHREAD_ONCE_INIT;
|
|
|
|
pthread_once(&fncache_once, fncache__init);
|
|
|
|
return fncache;
|
|
}
|
|
|
|
static bool lookup_fncache(const char *name, bool *res)
|
|
{
|
|
long val;
|
|
|
|
if (!hashmap__find(fncache__get(), name, &val))
|
|
return false;
|
|
|
|
*res = (val != 0);
|
|
return true;
|
|
}
|
|
|
|
static void update_fncache(const char *name, bool res)
|
|
{
|
|
char *old_key = NULL, *key = strdup(name);
|
|
|
|
if (key) {
|
|
hashmap__set(fncache__get(), key, res, &old_key, /*old_value*/NULL);
|
|
free(old_key);
|
|
}
|
|
}
|
|
|
|
/* No LRU, only use when bounded in some other way. */
|
|
bool file_available(const char *name)
|
|
{
|
|
bool res;
|
|
|
|
if (lookup_fncache(name, &res))
|
|
return res;
|
|
res = access(name, R_OK) == 0;
|
|
update_fncache(name, res);
|
|
return res;
|
|
}
|