All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ioannis Angelakopoulos <iangelak@fb.com>
To: <linux-btrfs@vger.kernel.org>, <kernel-team@fb.com>
Subject: [PATCH 1/1] btrfs: Annotate the reservation space wait event with lockdep
Date: Fri, 12 Aug 2022 11:17:56 -0700	[thread overview]
Message-ID: <20220812181754.1535281-2-iangelak@fb.com> (raw)
In-Reply-To: <20220812181754.1535281-1-iangelak@fb.com>

Add a lockdep annotation for the reservation space wait event.

This wait event is special in the sense that its condition modification and
waitqueue signaling are protected by the space_info->lock spinlock.

However, that is not the case with flush_space() in fs/btrfs/space-info.c
which is usually part of the execution context that leads to the signaling
of the reservation space waitqueue. This function is not protected by the
space_info->lock thus we place our annotation in flush_space().

Since, flush_space() operates differently depending on the flushing state,
we use a multilevel lockdep map where each subclass/level corresponds to
each flushing state.

Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
---
 fs/btrfs/ctree.h      |  9 +++++++++
 fs/btrfs/disk-io.c    |  1 +
 fs/btrfs/space-info.c | 25 +++++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 44837545eef8..9925b79cebf1 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1104,6 +1104,7 @@ struct btrfs_fs_info {
 	struct lockdep_map btrfs_state_change_map[4];
 	struct lockdep_map btrfs_trans_pending_ordered_map;
 	struct lockdep_map btrfs_ordered_extent_map;
+	struct lockdep_map btrfs_reservation_space_map;
 
 #ifdef CONFIG_BTRFS_FS_REF_VERIFY
 	spinlock_t ref_verify_lock;
@@ -1194,6 +1195,14 @@ enum btrfs_lockdep_trans_states {
 	BTRFS_LOCKDEP_TRANS_COMPLETED,
 };
 
+enum btrfs_reservation_space_states {
+	BTRFS_LOCKDEP_FLUSH_DELAYED_ITEMS,
+	BTRFS_LOCKDEP_FLUSH_DELALLOC_FULL,
+	BTRFS_LOCKDEP_FLUSH_DELAYED_REFS,
+	BTRFS_LOCKDEP_ALLOC_CHUNK_FORCE,
+	BTRFS_LOCKDEP_RUN_DELAYED_IPUTS,
+};
+
 /*
  * Lockdep annotation for wait events.
  *
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6268dafeeb2d..a107b6954a8b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2996,6 +2996,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
 	btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters);
 	btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered);
 	btrfs_lockdep_init_map(fs_info, btrfs_ordered_extent);
+	btrfs_lockdep_init_map(fs_info, btrfs_reservation_space);
 	btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start,
 				     BTRFS_LOCKDEP_TRANS_COMMIT_START);
 	btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked,
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
index 477e57ace48d..96631d1a9d82 100644
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -702,7 +702,10 @@ static void flush_space(struct btrfs_fs_info *fs_info,
 			ret = PTR_ERR(trans);
 			break;
 		}
+		btrfs_lockdep_acquire_nested(fs_info, btrfs_reservation_space,
+					     BTRFS_LOCKDEP_FLUSH_DELAYED_ITEMS);
 		ret = btrfs_run_delayed_items_nr(trans, nr);
+		btrfs_lockdep_release(fs_info, btrfs_reservation_space);
 		btrfs_end_transaction(trans);
 		break;
 	case FLUSH_DELALLOC:
@@ -710,8 +713,11 @@ static void flush_space(struct btrfs_fs_info *fs_info,
 	case FLUSH_DELALLOC_FULL:
 		if (state == FLUSH_DELALLOC_FULL)
 			num_bytes = U64_MAX;
+		btrfs_lockdep_acquire_nested(fs_info, btrfs_reservation_space,
+					     BTRFS_LOCKDEP_FLUSH_DELALLOC_FULL);
 		shrink_delalloc(fs_info, space_info, num_bytes,
 				state != FLUSH_DELALLOC, for_preempt);
+		btrfs_lockdep_release(fs_info, btrfs_reservation_space);
 		break;
 	case FLUSH_DELAYED_REFS_NR:
 	case FLUSH_DELAYED_REFS:
@@ -720,11 +726,14 @@ static void flush_space(struct btrfs_fs_info *fs_info,
 			ret = PTR_ERR(trans);
 			break;
 		}
+		btrfs_lockdep_acquire_nested(fs_info, btrfs_reservation_space,
+					     BTRFS_LOCKDEP_FLUSH_DELAYED_REFS);
 		if (state == FLUSH_DELAYED_REFS_NR)
 			nr = calc_reclaim_items_nr(fs_info, num_bytes);
 		else
 			nr = 0;
 		btrfs_run_delayed_refs(trans, nr);
+		btrfs_lockdep_release(fs_info, btrfs_reservation_space);
 		btrfs_end_transaction(trans);
 		break;
 	case ALLOC_CHUNK:
@@ -746,10 +755,13 @@ static void flush_space(struct btrfs_fs_info *fs_info,
 			ret = PTR_ERR(trans);
 			break;
 		}
+		btrfs_lockdep_acquire_nested(fs_info, btrfs_reservation_space,
+					     BTRFS_LOCKDEP_ALLOC_CHUNK_FORCE);
 		ret = btrfs_chunk_alloc(trans,
 				btrfs_get_alloc_profile(fs_info, space_info->flags),
 				(state == ALLOC_CHUNK) ? CHUNK_ALLOC_NO_FORCE :
 					CHUNK_ALLOC_FORCE);
+		btrfs_lockdep_release(fs_info, btrfs_reservation_space);
 		btrfs_end_transaction(trans);
 
 		/*
@@ -777,8 +789,11 @@ static void flush_space(struct btrfs_fs_info *fs_info,
 		 * bunch of pinned space, so make sure we run the iputs before
 		 * we do our pinned bytes check below.
 		 */
+		btrfs_lockdep_acquire_nested(fs_info, btrfs_reservation_space,
+					     BTRFS_LOCKDEP_RUN_DELAYED_IPUTS);
 		btrfs_run_delayed_iputs(fs_info);
 		btrfs_wait_on_delayed_iputs(fs_info);
+		btrfs_lockdep_release(fs_info, btrfs_reservation_space);
 		break;
 	case COMMIT_TRANS:
 		ASSERT(current->journal_info == NULL);
@@ -1444,6 +1459,16 @@ static void wait_reserve_ticket(struct btrfs_fs_info *fs_info,
 	DEFINE_WAIT(wait);
 	int ret = 0;
 
+#ifdef CONFIG_LOCKDEP
+	int state = BTRFS_LOCKDEP_FLUSH_DELAYED_ITEMS;
+
+	while (state <= BTRFS_LOCKDEP_RUN_DELAYED_IPUTS) {
+		btrfs_might_wait_for_event_nested(fs_info, btrfs_reservation_space,
+						  state);
+		state++;
+	}
+#endif
+
 	spin_lock(&space_info->lock);
 	while (ticket->bytes > 0 && ticket->error == 0) {
 		ret = prepare_to_wait_event(&ticket->wait, &wait, TASK_KILLABLE);
-- 
2.30.2


  reply	other threads:[~2022-08-12 18:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-12 18:17 [PATCH 0/1] btrfs: Add a lockdep annotation for the reservation space wait event Ioannis Angelakopoulos
2022-08-12 18:17 ` Ioannis Angelakopoulos [this message]
2022-08-13  6:15   ` [PATCH 1/1] btrfs: Annotate the reservation space wait event with lockdep kernel test robot
2022-08-13  6:46   ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220812181754.1535281-2-iangelak@fb.com \
    --to=iangelak@fb.com \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.