mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
util/mesa-db-multipart: Open one cache part at a time
Open one cache DB part at a time for a multi-part cache to reduce number of FDs used by the cache. Previously multi-part DB cache instance was consuming 100 FDs, now it's 2 and cache files are opened when cache is read or written instead of opening them at the init time. Fixes:fd9f7b748e("util/mesa-db: Introduce multipart mesa-db cache") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11776 Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Acked-by: Timothy Arceri <tarceri@itsqueeze.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30988> (cherry picked from commit2a9378a0f9)
This commit is contained in:
parent
823397fe55
commit
64bc227b49
3 changed files with 106 additions and 44 deletions
|
|
@ -544,7 +544,7 @@
|
||||||
"description": "util/mesa-db-multipart: Open one cache part at a time",
|
"description": "util/mesa-db-multipart: Open one cache part at a time",
|
||||||
"nominated": true,
|
"nominated": true,
|
||||||
"nomination_type": 1,
|
"nomination_type": 1,
|
||||||
"resolution": 0,
|
"resolution": 1,
|
||||||
"main_sha": null,
|
"main_sha": null,
|
||||||
"because_sha": "fd9f7b748e2e2fa57b39bb800305d2fb3d665079",
|
"because_sha": "fd9f7b748e2e2fa57b39bb800305d2fb3d665079",
|
||||||
"notes": null
|
"notes": null
|
||||||
|
|
|
||||||
|
|
@ -18,67 +18,109 @@ mesa_cache_db_multipart_open(struct mesa_cache_db_multipart *db,
|
||||||
#if DETECT_OS_WINDOWS
|
#if DETECT_OS_WINDOWS
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
char *part_path = NULL;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
db->num_parts = debug_get_num_option("MESA_DISK_CACHE_DATABASE_NUM_PARTS", 50);
|
db->num_parts = debug_get_num_option("MESA_DISK_CACHE_DATABASE_NUM_PARTS", 50);
|
||||||
|
db->cache_path = cache_path;
|
||||||
db->parts = calloc(db->num_parts, sizeof(*db->parts));
|
db->parts = calloc(db->num_parts, sizeof(*db->parts));
|
||||||
if (!db->parts)
|
if (!db->parts)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < db->num_parts; i++) {
|
simple_mtx_init(&db->lock, mtx_plain);
|
||||||
bool db_opened = false;
|
|
||||||
|
|
||||||
if (asprintf(&part_path, "%s/part%u", cache_path, i) == -1)
|
|
||||||
goto close_db;
|
|
||||||
|
|
||||||
if (mkdir(part_path, 0755) == -1 && errno != EEXIST)
|
|
||||||
goto free_path;
|
|
||||||
|
|
||||||
/* DB opening may fail only in a case of a severe problem,
|
|
||||||
* like IO error.
|
|
||||||
*/
|
|
||||||
db_opened = mesa_cache_db_open(&db->parts[i], part_path);
|
|
||||||
if (!db_opened)
|
|
||||||
goto free_path;
|
|
||||||
|
|
||||||
free(part_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove old pre multi-part cache */
|
|
||||||
mesa_db_wipe_path(cache_path);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
mesa_cache_db_multipart_init_part_locked(struct mesa_cache_db_multipart *db,
|
||||||
|
unsigned int part)
|
||||||
|
{
|
||||||
|
#if DETECT_OS_WINDOWS
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
struct mesa_cache_db *db_part;
|
||||||
|
bool db_opened = false;
|
||||||
|
char *part_path = NULL;
|
||||||
|
|
||||||
|
if (db->parts[part])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (asprintf(&part_path, "%s/part%u", db->cache_path, part) == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mkdir(part_path, 0755) == -1 && errno != EEXIST)
|
||||||
|
goto free_path;
|
||||||
|
|
||||||
|
db_part = calloc(1, sizeof(*db_part));
|
||||||
|
if (!db_part)
|
||||||
|
goto free_path;
|
||||||
|
|
||||||
|
/* DB opening may fail only in a case of a severe problem,
|
||||||
|
* like IO error.
|
||||||
|
*/
|
||||||
|
db_opened = mesa_cache_db_open(db_part, part_path);
|
||||||
|
if (!db_opened) {
|
||||||
|
free(db_part);
|
||||||
|
goto free_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db->max_cache_size)
|
||||||
|
mesa_cache_db_set_size_limit(db_part, db->max_cache_size / db->num_parts);
|
||||||
|
|
||||||
|
/* remove old pre multi-part cache */
|
||||||
|
mesa_db_wipe_path(db->cache_path);
|
||||||
|
|
||||||
|
__sync_synchronize();
|
||||||
|
|
||||||
|
db->parts[part] = db_part;
|
||||||
|
|
||||||
free_path:
|
free_path:
|
||||||
free(part_path);
|
free(part_path);
|
||||||
close_db:
|
|
||||||
while (i--)
|
|
||||||
mesa_cache_db_close(&db->parts[i]);
|
|
||||||
|
|
||||||
free(db->parts);
|
return db_opened;
|
||||||
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
mesa_cache_db_multipart_init_part(struct mesa_cache_db_multipart *db,
|
||||||
|
unsigned int part)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
if (db->parts[part])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
simple_mtx_lock(&db->lock);
|
||||||
|
ret = mesa_cache_db_multipart_init_part_locked(db, part);
|
||||||
|
simple_mtx_unlock(&db->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mesa_cache_db_multipart_close(struct mesa_cache_db_multipart *db)
|
mesa_cache_db_multipart_close(struct mesa_cache_db_multipart *db)
|
||||||
{
|
{
|
||||||
while (db->num_parts--)
|
while (db->num_parts--) {
|
||||||
mesa_cache_db_close(&db->parts[db->num_parts]);
|
if (db->parts[db->num_parts]) {
|
||||||
|
mesa_cache_db_close(db->parts[db->num_parts]);
|
||||||
|
free(db->parts[db->num_parts]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(db->parts);
|
free(db->parts);
|
||||||
|
simple_mtx_destroy(&db->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mesa_cache_db_multipart_set_size_limit(struct mesa_cache_db_multipart *db,
|
mesa_cache_db_multipart_set_size_limit(struct mesa_cache_db_multipart *db,
|
||||||
uint64_t max_cache_size)
|
uint64_t max_cache_size)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < db->num_parts; i++)
|
for (unsigned int part = 0; part < db->num_parts; part++) {
|
||||||
mesa_cache_db_set_size_limit(&db->parts[i],
|
if (db->parts[part])
|
||||||
max_cache_size / db->num_parts);
|
mesa_cache_db_set_size_limit(db->parts[part],
|
||||||
|
max_cache_size / db->num_parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
db->max_cache_size = max_cache_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|
@ -91,7 +133,10 @@ mesa_cache_db_multipart_read_entry(struct mesa_cache_db_multipart *db,
|
||||||
for (unsigned int i = 0; i < db->num_parts; i++) {
|
for (unsigned int i = 0; i < db->num_parts; i++) {
|
||||||
unsigned int part = (last_read_part + i) % db->num_parts;
|
unsigned int part = (last_read_part + i) % db->num_parts;
|
||||||
|
|
||||||
void *cache_item = mesa_cache_db_read_entry(&db->parts[part],
|
if (!mesa_cache_db_multipart_init_part(db, part))
|
||||||
|
break;
|
||||||
|
|
||||||
|
void *cache_item = mesa_cache_db_read_entry(db->parts[part],
|
||||||
cache_key_160bit, size);
|
cache_key_160bit, size);
|
||||||
if (cache_item) {
|
if (cache_item) {
|
||||||
/* Likely that the next entry lookup will hit the same DB part. */
|
/* Likely that the next entry lookup will hit the same DB part. */
|
||||||
|
|
@ -110,7 +155,10 @@ mesa_cache_db_multipart_select_victim_part(struct mesa_cache_db_multipart *db)
|
||||||
unsigned victim = 0;
|
unsigned victim = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < db->num_parts; i++) {
|
for (unsigned int i = 0; i < db->num_parts; i++) {
|
||||||
score = mesa_cache_db_eviction_score(&db->parts[i]);
|
if (!mesa_cache_db_multipart_init_part(db, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
score = mesa_cache_db_eviction_score(db->parts[i]);
|
||||||
if (score > best_score) {
|
if (score > best_score) {
|
||||||
best_score = score;
|
best_score = score;
|
||||||
victim = i;
|
victim = i;
|
||||||
|
|
@ -131,8 +179,11 @@ mesa_cache_db_multipart_entry_write(struct mesa_cache_db_multipart *db,
|
||||||
for (unsigned int i = 0; i < db->num_parts; i++) {
|
for (unsigned int i = 0; i < db->num_parts; i++) {
|
||||||
unsigned int part = (last_written_part + i) % db->num_parts;
|
unsigned int part = (last_written_part + i) % db->num_parts;
|
||||||
|
|
||||||
|
if (!mesa_cache_db_multipart_init_part(db, part))
|
||||||
|
break;
|
||||||
|
|
||||||
/* Note that each DB part has own locking. */
|
/* Note that each DB part has own locking. */
|
||||||
if (mesa_cache_db_has_space(&db->parts[part], blob_size)) {
|
if (mesa_cache_db_has_space(db->parts[part], blob_size)) {
|
||||||
wpart = part;
|
wpart = part;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -145,9 +196,12 @@ mesa_cache_db_multipart_entry_write(struct mesa_cache_db_multipart *db,
|
||||||
if (wpart < 0)
|
if (wpart < 0)
|
||||||
wpart = mesa_cache_db_multipart_select_victim_part(db);
|
wpart = mesa_cache_db_multipart_select_victim_part(db);
|
||||||
|
|
||||||
|
if (!mesa_cache_db_multipart_init_part(db, wpart))
|
||||||
|
return false;
|
||||||
|
|
||||||
db->last_written_part = wpart;
|
db->last_written_part = wpart;
|
||||||
|
|
||||||
return mesa_cache_db_entry_write(&db->parts[wpart], cache_key_160bit,
|
return mesa_cache_db_entry_write(db->parts[wpart], cache_key_160bit,
|
||||||
blob, blob_size);
|
blob, blob_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,6 +209,10 @@ void
|
||||||
mesa_cache_db_multipart_entry_remove(struct mesa_cache_db_multipart *db,
|
mesa_cache_db_multipart_entry_remove(struct mesa_cache_db_multipart *db,
|
||||||
const uint8_t *cache_key_160bit)
|
const uint8_t *cache_key_160bit)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < db->num_parts; i++)
|
for (unsigned int i = 0; i < db->num_parts; i++) {
|
||||||
mesa_cache_db_entry_remove(&db->parts[i], cache_key_160bit);
|
if (!mesa_cache_db_multipart_init_part(db, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mesa_cache_db_entry_remove(db->parts[i], cache_key_160bit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,16 @@
|
||||||
#define MESA_CACHE_DB_MULTIPART_H
|
#define MESA_CACHE_DB_MULTIPART_H
|
||||||
|
|
||||||
#include "mesa_cache_db.h"
|
#include "mesa_cache_db.h"
|
||||||
|
#include "simple_mtx.h"
|
||||||
|
|
||||||
struct mesa_cache_db_multipart {
|
struct mesa_cache_db_multipart {
|
||||||
struct mesa_cache_db *parts;
|
struct mesa_cache_db **parts;
|
||||||
unsigned int num_parts;
|
unsigned int num_parts;
|
||||||
volatile unsigned int last_read_part;
|
volatile unsigned int last_read_part;
|
||||||
volatile unsigned int last_written_part;
|
volatile unsigned int last_written_part;
|
||||||
|
const char *cache_path;
|
||||||
|
uint64_t max_cache_size;
|
||||||
|
simple_mtx_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue