* Evict the oldest eligible dbuf from the dbuf cache. */
| 665 | * Evict the oldest eligible dbuf from the dbuf cache. |
| 666 | */ |
| 667 | static void |
| 668 | dbuf_evict_one(void) |
| 669 | { |
| 670 | int idx = multilist_get_random_index(dbuf_caches[DB_DBUF_CACHE].cache); |
| 671 | multilist_sublist_t *mls = multilist_sublist_lock( |
| 672 | dbuf_caches[DB_DBUF_CACHE].cache, idx); |
| 673 | |
| 674 | ASSERT(!MUTEX_HELD(&dbuf_evict_lock)); |
| 675 | |
| 676 | dmu_buf_impl_t *db = multilist_sublist_tail(mls); |
| 677 | while (db != NULL && mutex_tryenter(&db->db_mtx) == 0) { |
| 678 | db = multilist_sublist_prev(mls, db); |
| 679 | } |
| 680 | |
| 681 | DTRACE_PROBE2(dbuf__evict__one, dmu_buf_impl_t *, db, |
| 682 | multilist_sublist_t *, mls); |
| 683 | |
| 684 | if (db != NULL) { |
| 685 | multilist_sublist_remove(mls, db); |
| 686 | multilist_sublist_unlock(mls); |
| 687 | (void) zfs_refcount_remove_many( |
| 688 | &dbuf_caches[DB_DBUF_CACHE].size, db->db.db_size, db); |
| 689 | DBUF_STAT_BUMPDOWN(cache_levels[db->db_level]); |
| 690 | DBUF_STAT_BUMPDOWN(cache_count); |
| 691 | DBUF_STAT_DECR(cache_levels_bytes[db->db_level], |
| 692 | db->db.db_size); |
| 693 | ASSERT3U(db->db_caching_status, ==, DB_DBUF_CACHE); |
| 694 | db->db_caching_status = DB_NO_CACHE; |
| 695 | dbuf_destroy(db); |
| 696 | DBUF_STAT_BUMP(cache_total_evicts); |
| 697 | } else { |
| 698 | multilist_sublist_unlock(mls); |
| 699 | } |
| 700 | } |
| 701 | |
| 702 | /* |
| 703 | * The dbuf evict thread is responsible for aging out dbufs from the |
no test coverage detected