Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c891c30a authored by Brian Foster's avatar Brian Foster Committed by Dave Chinner
Browse files

xfs: exclude never-released buffers from buftarg I/O accounting



The upcoming buftarg I/O accounting mechanism maintains a count of
all buffers that have undergone I/O in the current hold-release
cycle.  Certain buffers associated with core infrastructure (e.g.,
the xfs_mount superblock buffer, log buffers) are never released,
however. This means that accounting I/O submission on such buffers
elevates the buftarg count indefinitely and could lead to lockup on
unmount.

Define a new buffer flag to explicitly exclude buffers from buftarg
I/O accounting. Set the flag on the superblock and associated log
buffers.

Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 5539d367
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -815,7 +815,8 @@ xfs_buf_get_uncached(
	struct xfs_buf		*bp;
	struct xfs_buf		*bp;
	DEFINE_SINGLE_BUF_MAP(map, XFS_BUF_DADDR_NULL, numblks);
	DEFINE_SINGLE_BUF_MAP(map, XFS_BUF_DADDR_NULL, numblks);


	bp = _xfs_buf_alloc(target, &map, 1, 0);
	/* flags might contain irrelevant bits, pass only what we care about */
	bp = _xfs_buf_alloc(target, &map, 1, flags & XBF_NO_IOACCT);
	if (unlikely(bp == NULL))
	if (unlikely(bp == NULL))
		goto fail;
		goto fail;


+1 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@ typedef enum {
#define XBF_READ	 (1 << 0) /* buffer intended for reading from device */
#define XBF_READ	 (1 << 0) /* buffer intended for reading from device */
#define XBF_WRITE	 (1 << 1) /* buffer intended for writing to device */
#define XBF_WRITE	 (1 << 1) /* buffer intended for writing to device */
#define XBF_READ_AHEAD	 (1 << 2) /* asynchronous read-ahead */
#define XBF_READ_AHEAD	 (1 << 2) /* asynchronous read-ahead */
#define XBF_NO_IOACCT	 (1 << 3) /* bypass I/O accounting (non-LRU bufs) */
#define XBF_ASYNC	 (1 << 4) /* initiator will not wait for completion */
#define XBF_ASYNC	 (1 << 4) /* initiator will not wait for completion */
#define XBF_DONE	 (1 << 5) /* all pages in the buffer uptodate */
#define XBF_DONE	 (1 << 5) /* all pages in the buffer uptodate */
#define XBF_STALE	 (1 << 6) /* buffer has been staled, do not find it */
#define XBF_STALE	 (1 << 6) /* buffer has been staled, do not find it */
+3 −2
Original line number Original line Diff line number Diff line
@@ -1415,7 +1415,7 @@ xlog_alloc_log(
	 */
	 */
	error = -ENOMEM;
	error = -ENOMEM;
	bp = xfs_buf_alloc(mp->m_logdev_targp, XFS_BUF_DADDR_NULL,
	bp = xfs_buf_alloc(mp->m_logdev_targp, XFS_BUF_DADDR_NULL,
			   BTOBB(log->l_iclog_size), 0);
			   BTOBB(log->l_iclog_size), XBF_NO_IOACCT);
	if (!bp)
	if (!bp)
		goto out_free_log;
		goto out_free_log;


@@ -1454,7 +1454,8 @@ xlog_alloc_log(
		prev_iclog = iclog;
		prev_iclog = iclog;


		bp = xfs_buf_get_uncached(mp->m_logdev_targp,
		bp = xfs_buf_get_uncached(mp->m_logdev_targp,
						BTOBB(log->l_iclog_size), 0);
					  BTOBB(log->l_iclog_size),
					  XBF_NO_IOACCT);
		if (!bp)
		if (!bp)
			goto out_free_iclog;
			goto out_free_iclog;


+6 −4
Original line number Original line Diff line number Diff line
@@ -272,13 +272,15 @@ xfs_readsb(
	buf_ops = NULL;
	buf_ops = NULL;


	/*
	/*
	 * Allocate a (locked) buffer to hold the superblock.
	 * Allocate a (locked) buffer to hold the superblock. This will be kept
	 * This will be kept around at all times to optimize
	 * around at all times to optimize access to the superblock. Therefore,
	 * access to the superblock.
	 * set XBF_NO_IOACCT to make sure it doesn't hold the buftarg count
	 * elevated.
	 */
	 */
reread:
reread:
	error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR,
	error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR,
				   BTOBB(sector_size), 0, &bp, buf_ops);
				      BTOBB(sector_size), XBF_NO_IOACCT, &bp,
				      buf_ops);
	if (error) {
	if (error) {
		if (loud)
		if (loud)
			xfs_warn(mp, "SB validate failed with error %d.", error);
			xfs_warn(mp, "SB validate failed with error %d.", error);