Skip to content

Commit

Permalink
Evict meta data from ghost lists + l2arc headers
Browse files Browse the repository at this point in the history
When the meta limit is exceeded the ARC evicts some meta data
buffers from the mfu+mru lists.  Unfortunately, for meta data
heavy workloads it's possible for these buffers to accumulate
on the ghost lists if arc_c doesn't exceed arc_size.

To handle this case arc_adjust_meta() has been entended to
explicitly evict meta data buffers from the ghost lists in
proportion to what was evicted from the mfu+mru lists.

If this is insufficient we request that the VFS release
some inodes and dentries.  This will result in the release
of some dnodes which are counted as 'other' metadata.

Signed-off-by: Brian Behlendorf <[email protected]>
  • Loading branch information
behlendorf committed Aug 9, 2013
1 parent 68121a0 commit fadd0c4
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2104,8 +2104,9 @@ arc_do_user_evicts(void)
void
arc_adjust_meta(int64_t adjustment, boolean_t may_prune)
{
int64_t delta;
int64_t delta, tmp = adjustment;

/* Evict MRU+MFU meta data to ghost lists */
if (adjustment > 0 && arc_mru->arcs_lsize[ARC_BUFC_METADATA] > 0) {
delta = MIN(arc_mru->arcs_lsize[ARC_BUFC_METADATA], adjustment);
arc_evict(arc_mru, 0, delta, FALSE, ARC_BUFC_METADATA);
Expand All @@ -2115,9 +2116,24 @@ arc_adjust_meta(int64_t adjustment, boolean_t may_prune)
if (adjustment > 0 && arc_mfu->arcs_lsize[ARC_BUFC_METADATA] > 0) {
delta = MIN(arc_mfu->arcs_lsize[ARC_BUFC_METADATA], adjustment);
arc_evict(arc_mfu, 0, delta, FALSE, ARC_BUFC_METADATA);
}

/* Evict ghost MRU+MFU meta data */
adjustment = tmp;

if (adjustment > 0 && arc_mru_ghost->arcs_size > 0) {
delta = MIN(arc_mru_ghost->arcs_size, adjustment);
arc_evict_ghost(arc_mru_ghost, 0, delta, ARC_BUFC_METADATA);
adjustment -= delta;
}

if (adjustment > 0 && arc_mfu_ghost->arcs_size > 0) {
delta = MIN(arc_mfu_ghost->arcs_size, adjustment);
arc_evict_ghost(arc_mfu_ghost, 0, delta, ARC_BUFC_METADATA);
adjustment -= delta;
}

/* Request the VFS release some meta data */
if (may_prune && (adjustment > 0) && (arc_meta_used > arc_meta_limit))
arc_do_user_prune(zfs_arc_meta_prune);
}
Expand Down

0 comments on commit fadd0c4

Please sign in to comment.