Skip to content

Commit

Permalink
Illumos 4897 - Space accounting mismatch in L2ARC/zpool
Browse files Browse the repository at this point in the history
4897 Space accounting mismatch in L2ARC/zpool

Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: Boris Protopopov <[email protected]>
Approved by: Dan McDonald <[email protected]>

From the illumos issue tracker:

	L2ARC vdev space usage statistics are calculated as the delta
	between the maximum and minimum vdev offset ever written to
	by the L2ARC fill thread, but do not inform the user of how
	much space in between these two offsets is actually taken up by
	cached buffers. This fix changes that so that vdev space usage
	stats on L2ARC devices accurately track the volume of buffers
	stored on them, allowing users to see the exact L2ARC usage in
	"zpool iostat -v".

References:
  https://www.illumos.org/issues/4897
  illumos/illumos-gate@3038a2b

Ported by: Tim Chase <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes openzfs#2555
  • Loading branch information
Saso Kiselkov authored and ryao committed Nov 29, 2014
1 parent 14af841 commit 0db8675
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions module/zfs/arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/

/*
Expand Down Expand Up @@ -1697,6 +1697,8 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
ARCSTAT_INCR(arcstat_l2_asize, -l2hdr->b_asize);
vdev_space_update(l2hdr->b_dev->l2ad_vdev,
-l2hdr->b_asize, 0, 0);
kmem_cache_free(l2arc_hdr_cache, l2hdr);
arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS);
if (hdr->b_state == arc_l2c_only)
Expand Down Expand Up @@ -3762,6 +3764,8 @@ arc_release(arc_buf_t *buf, void *tag)

if (l2hdr) {
ARCSTAT_INCR(arcstat_l2_asize, -l2hdr->b_asize);
vdev_space_update(l2hdr->b_dev->l2ad_vdev,
-l2hdr->b_asize, 0, 0);
kmem_cache_free(l2arc_hdr_cache, l2hdr);
arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS);
ARCSTAT_INCR(arcstat_l2_size, -buf_size);
Expand Down Expand Up @@ -4604,6 +4608,7 @@ l2arc_write_done(zio_t *zio)
arc_buf_hdr_t *head, *ab, *ab_prev;
l2arc_buf_hdr_t *abl2;
kmutex_t *hash_lock;
int64_t bytes_dropped = 0;

cb = zio->io_private;
ASSERT(cb != NULL);
Expand Down Expand Up @@ -4651,6 +4656,7 @@ l2arc_write_done(zio_t *zio)
*/
list_remove(buflist, ab);
ARCSTAT_INCR(arcstat_l2_asize, -abl2->b_asize);
bytes_dropped += abl2->b_asize;
ab->b_l2hdr = NULL;
kmem_cache_free(l2arc_hdr_cache, abl2);
arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS);
Expand All @@ -4670,6 +4676,8 @@ l2arc_write_done(zio_t *zio)
kmem_cache_free(hdr_cache, head);
mutex_exit(&l2arc_buflist_mtx);

vdev_space_update(dev->l2ad_vdev, -bytes_dropped, 0, 0);

l2arc_do_free_on_write();

kmem_free(cb, sizeof (l2arc_write_callback_t));
Expand Down Expand Up @@ -4808,6 +4816,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
arc_buf_hdr_t *ab, *ab_prev;
kmutex_t *hash_lock;
uint64_t taddr;
int64_t bytes_evicted = 0;

buflist = dev->l2ad_buflist;

Expand Down Expand Up @@ -4906,6 +4915,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
if (ab->b_l2hdr != NULL) {
abl2 = ab->b_l2hdr;
ARCSTAT_INCR(arcstat_l2_asize, -abl2->b_asize);
bytes_evicted += abl2->b_asize;
ab->b_l2hdr = NULL;
kmem_cache_free(l2arc_hdr_cache, abl2);
arc_space_return(L2HDR_SIZE, ARC_SPACE_L2HDRS);
Expand All @@ -4923,7 +4933,7 @@ l2arc_evict(l2arc_dev_t *dev, uint64_t distance, boolean_t all)
}
mutex_exit(&l2arc_buflist_mtx);

vdev_space_update(dev->l2ad_vdev, -(taddr - dev->l2ad_evict), 0, 0);
vdev_space_update(dev->l2ad_vdev, -bytes_evicted, 0, 0);
dev->l2ad_evict = taddr;
}

Expand Down Expand Up @@ -5171,15 +5181,13 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz,
ARCSTAT_INCR(arcstat_l2_write_bytes, write_asize);
ARCSTAT_INCR(arcstat_l2_size, write_sz);
ARCSTAT_INCR(arcstat_l2_asize, write_asize);
vdev_space_update(dev->l2ad_vdev, write_psize, 0, 0);
vdev_space_update(dev->l2ad_vdev, write_asize, 0, 0);

/*
* Bump device hand to the device start if it is approaching the end.
* l2arc_evict() will already have evicted ahead for this case.
*/
if (dev->l2ad_hand >= (dev->l2ad_end - target_sz)) {
vdev_space_update(dev->l2ad_vdev,
dev->l2ad_end - dev->l2ad_hand, 0, 0);
dev->l2ad_hand = dev->l2ad_start;
dev->l2ad_evict = dev->l2ad_start;
dev->l2ad_first = B_FALSE;
Expand Down

0 comments on commit 0db8675

Please sign in to comment.