1/* 2 * Copyright © 2014 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifdef ENABLE_SHADER_CACHE 25 26#include <assert.h> 27#include <inttypes.h> 28#include <stdbool.h> 29#include <stddef.h> 30#include <stdlib.h> 31#include <sys/types.h> 32#include <sys/stat.h> 33#include <dirent.h> 34#include <fcntl.h> 35 36#include "util/compress.h" 37#include "util/crc32.h" 38 39struct cache_entry_file_data { 40 uint32_t crc32; 41 uint32_t uncompressed_size; 42}; 43 44#if DETECT_OS_WINDOWS 45/* TODO: implement disk cache support on windows */ 46 47#else 48 49#include <dirent.h> 50#include <errno.h> 51#include <pwd.h> 52#include <stdio.h> 53#include <string.h> 54#include <sys/file.h> 55#include <sys/mman.h> 56#include <sys/types.h> 57#include <sys/stat.h> 58#include <unistd.h> 59 60#include "util/blob.h" 61#include "util/crc32.h" 62#include "util/debug.h" 63#include "util/disk_cache.h" 64#include "util/disk_cache_os.h" 65#include "util/ralloc.h" 66#include "util/rand_xor.h" 67 68/* Create a directory named 'path' if it does not already exist. 69 * 70 * Returns: 0 if path already exists as a directory or if created. 71 * -1 in all other cases. 72 */ 73static int 74mkdir_if_needed(const char *path) 75{ 76 struct stat sb; 77 78 /* If the path exists already, then our work is done if it's a 79 * directory, but it's an error if it is not. 80 */ 81 if (stat(path, &sb) == 0) { 82 if (S_ISDIR(sb.st_mode)) { 83 return 0; 84 } else { 85 fprintf(stderr, "Cannot use %s for shader cache (not a directory)" 86 "---disabling.\n", path); 87 return -1; 88 } 89 } 90 91 int ret = mkdir(path, 0755); 92 if (ret == 0 || (ret == -1 && errno == EEXIST)) 93 return 0; 94 95 fprintf(stderr, "Failed to create %s for shader cache (%s)---disabling.\n", 96 path, strerror(errno)); 97 98 return -1; 99} 100 101/* Concatenate an existing path and a new name to form a new path. If the new 102 * path does not exist as a directory, create it then return the resulting 103 * name of the new path (ralloc'ed off of 'ctx'). 104 * 105 * Returns NULL on any error, such as: 106 * 107 * <path> does not exist or is not a directory 108 * <path>/<name> exists but is not a directory 109 * <path>/<name> cannot be created as a directory 110 */ 111static char * 112concatenate_and_mkdir(void *ctx, const char *path, const char *name) 113{ 114 char *new_path; 115 struct stat sb; 116 117 if (stat(path, &sb) != 0 || ! S_ISDIR(sb.st_mode)) 118 return NULL; 119 120 new_path = ralloc_asprintf(ctx, "%s/%s", path, name); 121 122 if (mkdir_if_needed(new_path) == 0) 123 return new_path; 124 else 125 return NULL; 126} 127 128struct lru_file { 129 struct list_head node; 130 char *lru_name; 131 size_t lru_file_size; 132 time_t lru_atime; 133}; 134 135static void 136free_lru_file_list(struct list_head *lru_file_list) 137{ 138 struct lru_file *e, *next; 139 LIST_FOR_EACH_ENTRY_SAFE(e, next, lru_file_list, node) { 140 free(e->lru_name); 141 free(e); 142 } 143 free(lru_file_list); 144} 145 146/* Given a directory path and predicate function, create a linked list of entrys 147 * with the oldest access time in that directory for which the predicate 148 * returns true. 149 * 150 * Returns: A malloc'ed linkd list for the paths of chosen files, (or 151 * NULL on any error). The caller should free the linked list via 152 * free_lru_file_list() when finished. 153 */ 154static struct list_head * 155choose_lru_file_matching(const char *dir_path, 156 bool (*predicate)(const char *dir_path, 157 const struct stat *, 158 const char *, const size_t)) 159{ 160 DIR *dir; 161 struct dirent *dir_ent; 162 163 dir = opendir(dir_path); 164 if (dir == NULL) 165 return NULL; 166 167 /* First count the number of files in the directory */ 168 unsigned total_file_count = 0; 169 while ((dir_ent = readdir(dir)) != NULL) { 170 if (dir_ent->d_type == DT_REG) { /* If the entry is a regular file */ 171 total_file_count++; 172 } 173 } 174 175 /* Reset to the start of the directory */ 176 rewinddir(dir); 177 178 /* Collect 10% of files in this directory for removal. Note: This should work 179 * out to only be around 0.04% of total cache items. 180 */ 181 unsigned lru_file_count = total_file_count > 10 ? total_file_count / 10 : 1; 182 struct list_head *lru_file_list = malloc(sizeof(struct list_head)); 183 list_inithead(lru_file_list); 184 185 unsigned processed_files = 0; 186 while (1) { 187 dir_ent = readdir(dir); 188 if (dir_ent == NULL) 189 break; 190 191 struct stat sb; 192 if (fstatat(dirfd(dir), dir_ent->d_name, &sb, 0) == 0) { 193 struct lru_file *entry = NULL; 194 if (!list_is_empty(lru_file_list)) 195 entry = list_first_entry(lru_file_list, struct lru_file, node); 196 197 if (!entry|| sb.st_atime < entry->lru_atime) { 198 size_t len = strlen(dir_ent->d_name); 199 if (!predicate(dir_path, &sb, dir_ent->d_name, len)) 200 continue; 201 202 bool new_entry = false; 203 if (processed_files < lru_file_count) { 204 entry = calloc(1, sizeof(struct lru_file)); 205 new_entry = true; 206 } 207 processed_files++; 208 209 char *tmp = realloc(entry->lru_name, len + 1); 210 if (tmp) { 211 /* Find location to insert new lru item. We want to keep the 212 * list ordering from most recently used to least recently used. 213 * This allows us to just evict the head item from the list as 214 * we process the directory and find older entrys. 215 */ 216 struct list_head *list_node = lru_file_list; 217 struct lru_file *e; 218 LIST_FOR_EACH_ENTRY(e, lru_file_list, node) { 219 if (sb.st_atime < entry->lru_atime) { 220 list_node = &e->node; 221 break; 222 } 223 } 224 225 if (new_entry) { 226 list_addtail(&entry->node, list_node); 227 } else { 228 if (list_node != lru_file_list) { 229 list_del(lru_file_list); 230 list_addtail(lru_file_list, list_node); 231 } 232 } 233 234 entry->lru_name = tmp; 235 memcpy(entry->lru_name, dir_ent->d_name, len + 1); 236 entry->lru_atime = sb.st_atime; 237 entry->lru_file_size = sb.st_blocks * 512; 238 } 239 } 240 } 241 } 242 243 if (list_is_empty(lru_file_list)) { 244 closedir(dir); 245 free(lru_file_list); 246 return NULL; 247 } 248 249 /* Create the full path for the file list we found */ 250 struct lru_file *e; 251 LIST_FOR_EACH_ENTRY(e, lru_file_list, node) { 252 char *filename = e->lru_name; 253 if (asprintf(&e->lru_name, "%s/%s", dir_path, filename) < 0) 254 e->lru_name = NULL; 255 256 free(filename); 257 } 258 259 closedir(dir); 260 261 return lru_file_list; 262} 263 264/* Is entry a regular file, and not having a name with a trailing 265 * ".tmp" 266 */ 267static bool 268is_regular_non_tmp_file(const char *path, const struct stat *sb, 269 const char *d_name, const size_t len) 270{ 271 if (!S_ISREG(sb->st_mode)) 272 return false; 273 274 if (len >= 4 && strcmp(&d_name[len-4], ".tmp") == 0) 275 return false; 276 277 return true; 278} 279 280/* Returns the size of the deleted file, (or 0 on any error). */ 281static size_t 282unlink_lru_file_from_directory(const char *path) 283{ 284 struct list_head *lru_file_list = 285 choose_lru_file_matching(path, is_regular_non_tmp_file); 286 if (lru_file_list == NULL) 287 return 0; 288 289 assert(!list_is_empty(lru_file_list)); 290 291 size_t total_unlinked_size = 0; 292 struct lru_file *e; 293 LIST_FOR_EACH_ENTRY(e, lru_file_list, node) { 294 if (unlink(e->lru_name) == 0) 295 total_unlinked_size += e->lru_file_size; 296 } 297 free_lru_file_list(lru_file_list); 298 299 return total_unlinked_size; 300} 301 302/* Is entry a directory with a two-character name, (and not the 303 * special name of ".."). We also return false if the dir is empty. 304 */ 305static bool 306is_two_character_sub_directory(const char *path, const struct stat *sb, 307 const char *d_name, const size_t len) 308{ 309 if (!S_ISDIR(sb->st_mode)) 310 return false; 311 312 if (len != 2) 313 return false; 314 315 if (strcmp(d_name, "..") == 0) 316 return false; 317 318 char *subdir; 319 if (asprintf(&subdir, "%s/%s", path, d_name) == -1) 320 return false; 321 DIR *dir = opendir(subdir); 322 free(subdir); 323 324 if (dir == NULL) 325 return false; 326 327 unsigned subdir_entries = 0; 328 struct dirent *d; 329 while ((d = readdir(dir)) != NULL) { 330 if(++subdir_entries > 2) 331 break; 332 } 333 closedir(dir); 334 335 /* If dir only contains '.' and '..' it must be empty */ 336 if (subdir_entries <= 2) 337 return false; 338 339 return true; 340} 341 342/* Create the directory that will be needed for the cache file for \key. 343 * 344 * Obviously, the implementation here must closely match 345 * _get_cache_file above. 346*/ 347static void 348make_cache_file_directory(struct disk_cache *cache, const cache_key key) 349{ 350 char *dir; 351 char buf[41]; 352 353 _mesa_sha1_format(buf, key); 354 if (asprintf(&dir, "%s/%c%c", cache->path, buf[0], buf[1]) == -1) 355 return; 356 357 mkdir_if_needed(dir); 358 free(dir); 359} 360 361static ssize_t 362read_all(int fd, void *buf, size_t count) 363{ 364 char *in = buf; 365 ssize_t read_ret; 366 size_t done; 367 368 for (done = 0; done < count; done += read_ret) { 369 read_ret = read(fd, in + done, count - done); 370 if (read_ret == -1 || read_ret == 0) 371 return -1; 372 } 373 return done; 374} 375 376static ssize_t 377write_all(int fd, const void *buf, size_t count) 378{ 379 const char *out = buf; 380 ssize_t written; 381 size_t done; 382 383 for (done = 0; done < count; done += written) { 384 written = write(fd, out + done, count - done); 385 if (written == -1) 386 return -1; 387 } 388 return done; 389} 390 391/* Evict least recently used cache item */ 392void 393disk_cache_evict_lru_item(struct disk_cache *cache) 394{ 395 char *dir_path; 396 397 /* With a reasonably-sized, full cache, (and with keys generated 398 * from a cryptographic hash), we can choose two random hex digits 399 * and reasonably expect the directory to exist with a file in it. 400 * Provides pseudo-LRU eviction to reduce checking all cache files. 401 */ 402 uint64_t rand64 = rand_xorshift128plus(cache->seed_xorshift128plus); 403 if (asprintf(&dir_path, "%s/%02" PRIx64 , cache->path, rand64 & 0xff) < 0) 404 return; 405 406 size_t size = unlink_lru_file_from_directory(dir_path); 407 408 free(dir_path); 409 410 if (size) { 411 p_atomic_add(cache->size, - (uint64_t)size); 412 return; 413 } 414 415 /* In the case where the random choice of directory didn't find 416 * something, we choose the least recently accessed from the 417 * existing directories. 418 * 419 * Really, the only reason this code exists is to allow the unit 420 * tests to work, (which use an artificially-small cache to be able 421 * to force a single cached item to be evicted). 422 */ 423 struct list_head *lru_file_list = 424 choose_lru_file_matching(cache->path, is_two_character_sub_directory); 425 if (lru_file_list == NULL) 426 return; 427 428 assert(!list_is_empty(lru_file_list)); 429 430 struct lru_file *lru_file_dir = 431 list_first_entry(lru_file_list, struct lru_file, node); 432 433 size = unlink_lru_file_from_directory(lru_file_dir->lru_name); 434 435 free_lru_file_list(lru_file_list); 436 437 if (size) 438 p_atomic_add(cache->size, - (uint64_t)size); 439} 440 441void 442disk_cache_evict_item(struct disk_cache *cache, char *filename) 443{ 444 struct stat sb; 445 if (stat(filename, &sb) == -1) { 446 free(filename); 447 return; 448 } 449 450 unlink(filename); 451 free(filename); 452 453 if (sb.st_blocks) 454 p_atomic_add(cache->size, - (uint64_t)sb.st_blocks * 512); 455} 456 457static void * 458parse_and_validate_cache_item(struct disk_cache *cache, void *cache_item, 459 size_t cache_item_size, size_t *size) 460{ 461 uint8_t *uncompressed_data = NULL; 462 463 struct blob_reader ci_blob_reader; 464 blob_reader_init(&ci_blob_reader, cache_item, cache_item_size); 465 466 size_t header_size = cache->driver_keys_blob_size; 467 const void *keys_blob = blob_read_bytes(&ci_blob_reader, header_size); 468 if (ci_blob_reader.overrun) 469 goto fail; 470 471 /* Check for extremely unlikely hash collisions */ 472 if (memcmp(cache->driver_keys_blob, keys_blob, header_size) != 0) { 473 assert(!"Mesa cache keys mismatch!"); 474 goto fail; 475 } 476 477 uint32_t md_type = blob_read_uint32(&ci_blob_reader); 478 if (ci_blob_reader.overrun) 479 goto fail; 480 481 if (md_type == CACHE_ITEM_TYPE_GLSL) { 482 uint32_t num_keys = blob_read_uint32(&ci_blob_reader); 483 if (ci_blob_reader.overrun) 484 goto fail; 485 486 /* The cache item metadata is currently just used for distributing 487 * precompiled shaders, they are not used by Mesa so just skip them for 488 * now. 489 * TODO: pass the metadata back to the caller and do some basic 490 * validation. 491 */ 492 const void UNUSED *metadata = 493 blob_read_bytes(&ci_blob_reader, num_keys * sizeof(cache_key)); 494 if (ci_blob_reader.overrun) 495 goto fail; 496 } 497 498 /* Load the CRC that was created when the file was written. */ 499 struct cache_entry_file_data *cf_data = 500 (struct cache_entry_file_data *) 501 blob_read_bytes(&ci_blob_reader, sizeof(struct cache_entry_file_data)); 502 if (ci_blob_reader.overrun) 503 goto fail; 504 505 size_t cache_data_size = ci_blob_reader.end - ci_blob_reader.current; 506 const uint8_t *data = (uint8_t *) blob_read_bytes(&ci_blob_reader, cache_data_size); 507 508 /* Check the data for corruption */ 509 if (cf_data->crc32 != util_hash_crc32(data, cache_data_size)) 510 goto fail; 511 512 /* Uncompress the cache data */ 513 uncompressed_data = malloc(cf_data->uncompressed_size); 514 if (!util_compress_inflate(data, cache_data_size, uncompressed_data, 515 cf_data->uncompressed_size)) 516 goto fail; 517 518 if (size) 519 *size = cf_data->uncompressed_size; 520 521 return uncompressed_data; 522 523 fail: 524 if (uncompressed_data) 525 free(uncompressed_data); 526 527 return NULL; 528} 529 530void * 531disk_cache_load_item(struct disk_cache *cache, char *filename, size_t *size) 532{ 533 uint8_t *data = NULL; 534 535 int fd = open(filename, O_RDONLY | O_CLOEXEC); 536 if (fd == -1) 537 goto fail; 538 539 struct stat sb; 540 if (fstat(fd, &sb) == -1) 541 goto fail; 542 543 data = malloc(sb.st_size); 544 if (data == NULL) 545 goto fail; 546 547 /* Read entire file into memory */ 548 int ret = read_all(fd, data, sb.st_size); 549 if (ret == -1) 550 goto fail; 551 552 uint8_t *uncompressed_data = 553 parse_and_validate_cache_item(cache, data, sb.st_size, size); 554 if (!uncompressed_data) 555 goto fail; 556 557 free(data); 558 free(filename); 559 close(fd); 560 561 return uncompressed_data; 562 563 fail: 564 if (data) 565 free(data); 566 if (filename) 567 free(filename); 568 if (fd != -1) 569 close(fd); 570 571 return NULL; 572} 573 574/* Return a filename within the cache's directory corresponding to 'key'. 575 * 576 * Returns NULL if out of memory. 577 */ 578char * 579disk_cache_get_cache_filename(struct disk_cache *cache, const cache_key key) 580{ 581 char buf[41]; 582 char *filename; 583 584 if (cache->path_init_failed) 585 return NULL; 586 587 _mesa_sha1_format(buf, key); 588 if (asprintf(&filename, "%s/%c%c/%s", cache->path, buf[0], 589 buf[1], buf + 2) == -1) 590 return NULL; 591 592 return filename; 593} 594 595static bool 596create_cache_item_header_and_blob(struct disk_cache_put_job *dc_job, 597 struct blob *cache_blob) 598{ 599 600 /* Compress the cache item data */ 601 size_t max_buf = util_compress_max_compressed_len(dc_job->size); 602 void *compressed_data = malloc(max_buf); 603 if (compressed_data == NULL) 604 return false; 605 606 size_t compressed_size = 607 util_compress_deflate(dc_job->data, dc_job->size, 608 compressed_data, max_buf); 609 if (compressed_size == 0) 610 goto fail; 611 612 /* Copy the driver_keys_blob, this can be used find information about the 613 * mesa version that produced the entry or deal with hash collisions, 614 * should that ever become a real problem. 615 */ 616 if (!blob_write_bytes(cache_blob, dc_job->cache->driver_keys_blob, 617 dc_job->cache->driver_keys_blob_size)) 618 goto fail; 619 620 /* Write the cache item metadata. This data can be used to deal with 621 * hash collisions, as well as providing useful information to 3rd party 622 * tools reading the cache files. 623 */ 624 if (!blob_write_uint32(cache_blob, dc_job->cache_item_metadata.type)) 625 goto fail; 626 627 if (dc_job->cache_item_metadata.type == CACHE_ITEM_TYPE_GLSL) { 628 if (!blob_write_uint32(cache_blob, dc_job->cache_item_metadata.num_keys)) 629 goto fail; 630 631 size_t metadata_keys_size = 632 dc_job->cache_item_metadata.num_keys * sizeof(cache_key); 633 if (!blob_write_bytes(cache_blob, dc_job->cache_item_metadata.keys[0], 634 metadata_keys_size)) 635 goto fail; 636 } 637 638 /* Create CRC of the compressed data. We will read this when restoring the 639 * cache and use it to check for corruption. 640 */ 641 struct cache_entry_file_data cf_data; 642 cf_data.crc32 = util_hash_crc32(compressed_data, compressed_size); 643 cf_data.uncompressed_size = dc_job->size; 644 645 if (!blob_write_bytes(cache_blob, &cf_data, sizeof(cf_data))) 646 goto fail; 647 648 /* Finally copy the compressed cache blob */ 649 if (!blob_write_bytes(cache_blob, compressed_data, compressed_size)) 650 goto fail; 651 652 free(compressed_data); 653 return true; 654 655 fail: 656 free(compressed_data); 657 return false; 658} 659 660void 661disk_cache_write_item_to_disk(struct disk_cache_put_job *dc_job, 662 char *filename) 663{ 664 int fd = -1, fd_final = -1; 665 struct blob cache_blob; 666 blob_init(&cache_blob); 667 668 /* Write to a temporary file to allow for an atomic rename to the 669 * final destination filename, (to prevent any readers from seeing 670 * a partially written file). 671 */ 672 char *filename_tmp = NULL; 673 if (asprintf(&filename_tmp, "%s.tmp", filename) == -1) 674 goto done; 675 676 fd = open(filename_tmp, O_WRONLY | O_CLOEXEC | O_CREAT, 0644); 677 678 /* Make the two-character subdirectory within the cache as needed. */ 679 if (fd == -1) { 680 if (errno != ENOENT) 681 goto done; 682 683 make_cache_file_directory(dc_job->cache, dc_job->key); 684 685 fd = open(filename_tmp, O_WRONLY | O_CLOEXEC | O_CREAT, 0644); 686 if (fd == -1) 687 goto done; 688 } 689 690 /* With the temporary file open, we take an exclusive flock on 691 * it. If the flock fails, then another process still has the file 692 * open with the flock held. So just let that file be responsible 693 * for writing the file. 694 */ 695#ifdef HAVE_FLOCK 696 int err = flock(fd, LOCK_EX | LOCK_NB); 697#else 698 struct flock lock = { 699 .l_start = 0, 700 .l_len = 0, /* entire file */ 701 .l_type = F_WRLCK, 702 .l_whence = SEEK_SET 703 }; 704 int err = fcntl(fd, F_SETLK, &lock); 705#endif 706 if (err == -1) 707 goto done; 708 709 /* Now that we have the lock on the open temporary file, we can 710 * check to see if the destination file already exists. If so, 711 * another process won the race between when we saw that the file 712 * didn't exist and now. In this case, we don't do anything more, 713 * (to ensure the size accounting of the cache doesn't get off). 714 */ 715 fd_final = open(filename, O_RDONLY | O_CLOEXEC); 716 if (fd_final != -1) { 717 unlink(filename_tmp); 718 goto done; 719 } 720 721 /* OK, we're now on the hook to write out a file that we know is 722 * not in the cache, and is also not being written out to the cache 723 * by some other process. 724 */ 725 if (!create_cache_item_header_and_blob(dc_job, &cache_blob)) { 726 unlink(filename_tmp); 727 goto done; 728 } 729 730 /* Now, finally, write out the contents to the temporary file, then 731 * rename them atomically to the destination filename, and also 732 * perform an atomic increment of the total cache size. 733 */ 734 int ret = write_all(fd, cache_blob.data, cache_blob.size); 735 if (ret == -1) { 736 unlink(filename_tmp); 737 goto done; 738 } 739 740 ret = rename(filename_tmp, filename); 741 if (ret == -1) { 742 unlink(filename_tmp); 743 goto done; 744 } 745 746 struct stat sb; 747 if (stat(filename, &sb) == -1) { 748 /* Something went wrong remove the file */ 749 unlink(filename); 750 goto done; 751 } 752 753 p_atomic_add(dc_job->cache->size, sb.st_blocks * 512); 754 755 done: 756 if (fd_final != -1) 757 close(fd_final); 758 /* This close finally releases the flock, (now that the final file 759 * has been renamed into place and the size has been added). 760 */ 761 if (fd != -1) 762 close(fd); 763 free(filename_tmp); 764 blob_finish(&cache_blob); 765} 766 767/* Determine path for cache based on the first defined name as follows: 768 * 769 * $MESA_GLSL_CACHE_DIR 770 * $XDG_CACHE_HOME/mesa_shader_cache 771 * <pwd.pw_dir>/.cache/mesa_shader_cache 772 */ 773char * 774disk_cache_generate_cache_dir(void *mem_ctx, const char *gpu_name, 775 const char *driver_id) 776{ 777 char *cache_dir_name = CACHE_DIR_NAME; 778 if (env_var_as_boolean("MESA_DISK_CACHE_SINGLE_FILE", false)) 779 cache_dir_name = CACHE_DIR_NAME_SF; 780 781 char *path = getenv("MESA_GLSL_CACHE_DIR"); 782 if (path) { 783 if (mkdir_if_needed(path) == -1) 784 return NULL; 785 786 path = concatenate_and_mkdir(mem_ctx, path, cache_dir_name); 787 if (!path) 788 return NULL; 789 } 790 791 if (path == NULL) { 792 char *xdg_cache_home = getenv("XDG_CACHE_HOME"); 793 794 if (xdg_cache_home) { 795 if (mkdir_if_needed(xdg_cache_home) == -1) 796 return NULL; 797 798 path = concatenate_and_mkdir(mem_ctx, xdg_cache_home, cache_dir_name); 799 if (!path) 800 return NULL; 801 } 802 } 803 804 if (!path) { 805 char *buf; 806 size_t buf_size; 807 struct passwd pwd, *result; 808 809 buf_size = sysconf(_SC_GETPW_R_SIZE_MAX); 810 if (buf_size == -1) 811 buf_size = 512; 812 813 /* Loop until buf_size is large enough to query the directory */ 814 while (1) { 815 buf = ralloc_size(mem_ctx, buf_size); 816 817 getpwuid_r(getuid(), &pwd, buf, buf_size, &result); 818 if (result) 819 break; 820 821 if (errno == ERANGE) { 822 ralloc_free(buf); 823 buf = NULL; 824 buf_size *= 2; 825 } else { 826 return NULL; 827 } 828 } 829 830 path = concatenate_and_mkdir(mem_ctx, pwd.pw_dir, ".cache"); 831 if (!path) 832 return NULL; 833 834 path = concatenate_and_mkdir(mem_ctx, path, cache_dir_name); 835 if (!path) 836 return NULL; 837 } 838 839 if (env_var_as_boolean("MESA_DISK_CACHE_SINGLE_FILE", false)) { 840 path = concatenate_and_mkdir(mem_ctx, path, driver_id); 841 if (!path) 842 return NULL; 843 844 path = concatenate_and_mkdir(mem_ctx, path, gpu_name); 845 if (!path) 846 return NULL; 847 } 848 849 return path; 850} 851 852bool 853disk_cache_enabled() 854{ 855 /* If running as a users other than the real user disable cache */ 856 if (issetugid()) 857 return false; 858 859 /* At user request, disable shader cache entirely. */ 860#ifdef SHADER_CACHE_DISABLE_BY_DEFAULT 861 bool disable_by_default = true; 862#else 863 bool disable_by_default = false; 864#endif 865 if (env_var_as_boolean("MESA_GLSL_CACHE_DISABLE", disable_by_default)) 866 return false; 867 868 return true; 869} 870 871void * 872disk_cache_load_item_foz(struct disk_cache *cache, const cache_key key, 873 size_t *size) 874{ 875 size_t cache_tem_size = 0; 876 void *cache_item = foz_read_entry(&cache->foz_db, key, &cache_tem_size); 877 if (!cache_item) 878 return NULL; 879 880 uint8_t *uncompressed_data = 881 parse_and_validate_cache_item(cache, cache_item, cache_tem_size, size); 882 free(cache_item); 883 884 return uncompressed_data; 885} 886 887bool 888disk_cache_write_item_to_disk_foz(struct disk_cache_put_job *dc_job) 889{ 890 struct blob cache_blob; 891 blob_init(&cache_blob); 892 893 if (!create_cache_item_header_and_blob(dc_job, &cache_blob)) 894 return false; 895 896 bool r = foz_write_entry(&dc_job->cache->foz_db, dc_job->key, 897 cache_blob.data, cache_blob.size); 898 899 blob_finish(&cache_blob); 900 return r; 901} 902 903bool 904disk_cache_load_cache_index(void *mem_ctx, struct disk_cache *cache) 905{ 906 /* Load cache index into a hash map (from fossilise files) */ 907 return foz_prepare(&cache->foz_db, cache->path); 908} 909 910bool 911disk_cache_mmap_cache_index(void *mem_ctx, struct disk_cache *cache, 912 char *path) 913{ 914 int fd = -1; 915 bool mapped = false; 916 917 path = ralloc_asprintf(mem_ctx, "%s/index", cache->path); 918 if (path == NULL) 919 goto path_fail; 920 921 fd = open(path, O_RDWR | O_CREAT | O_CLOEXEC, 0644); 922 if (fd == -1) 923 goto path_fail; 924 925 struct stat sb; 926 if (fstat(fd, &sb) == -1) 927 goto path_fail; 928 929 /* Force the index file to be the expected size. */ 930 size_t size = sizeof(*cache->size) + CACHE_INDEX_MAX_KEYS * CACHE_KEY_SIZE; 931 if (sb.st_size != size) { 932 if (ftruncate(fd, size) == -1) 933 goto path_fail; 934 } 935 936 /* We map this shared so that other processes see updates that we 937 * make. 938 * 939 * Note: We do use atomic addition to ensure that multiple 940 * processes don't scramble the cache size recorded in the 941 * index. But we don't use any locking to prevent multiple 942 * processes from updating the same entry simultaneously. The idea 943 * is that if either result lands entirely in the index, then 944 * that's equivalent to a well-ordered write followed by an 945 * eviction and a write. On the other hand, if the simultaneous 946 * writes result in a corrupt entry, that's not really any 947 * different than both entries being evicted, (since within the 948 * guarantees of the cryptographic hash, a corrupt entry is 949 * unlikely to ever match a real cache key). 950 */ 951 cache->index_mmap = mmap(NULL, size, PROT_READ | PROT_WRITE, 952 MAP_SHARED, fd, 0); 953 if (cache->index_mmap == MAP_FAILED) 954 goto path_fail; 955 cache->index_mmap_size = size; 956 957 cache->size = (uint64_t *) cache->index_mmap; 958 cache->stored_keys = cache->index_mmap + sizeof(uint64_t); 959 mapped = true; 960 961path_fail: 962 if (fd != -1) 963 close(fd); 964 965 return mapped; 966} 967 968void 969disk_cache_destroy_mmap(struct disk_cache *cache) 970{ 971 munmap(cache->index_mmap, cache->index_mmap_size); 972} 973#endif 974 975#endif /* ENABLE_SHADER_CACHE */ 976