Unverified Commit 627cf645 authored by David Howells's avatar David Howells Committed by Christian Brauner
Browse files

netfs: Don't use bh spinlock



All the accessing of the subrequest lists is now done in process context,
possibly in a workqueue, but not now in a BH context, so we don't need the
lock against BH interference when taking the netfs_io_request::lock
spinlock.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/20241216204124.3752367-11-dhowells@redhat.com


cc: Jeff Layton <jlayton@kernel.org>
cc: linux-cachefs@redhat.com
cc: linux-fsdevel@vger.kernel.org
cc: linux-mm@kvack.org
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 31fc366a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -200,12 +200,12 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
		subreq->len	= size;

		atomic_inc(&rreq->nr_outstanding);
		spin_lock_bh(&rreq->lock);
		spin_lock(&rreq->lock);
		list_add_tail(&subreq->rreq_link, &rreq->subrequests);
		subreq->prev_donated = rreq->prev_donated;
		rreq->prev_donated = 0;
		trace_netfs_sreq(subreq, netfs_sreq_trace_added);
		spin_unlock_bh(&rreq->lock);
		spin_unlock(&rreq->lock);

		source = netfs_cache_prepare_read(rreq, subreq, rreq->i_size);
		subreq->source = source;
+2 −2
Original line number Diff line number Diff line
@@ -68,12 +68,12 @@ static int netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
		subreq->len	= size;

		atomic_inc(&rreq->nr_outstanding);
		spin_lock_bh(&rreq->lock);
		spin_lock(&rreq->lock);
		list_add_tail(&subreq->rreq_link, &rreq->subrequests);
		subreq->prev_donated = rreq->prev_donated;
		rreq->prev_donated = 0;
		trace_netfs_sreq(subreq, netfs_sreq_trace_added);
		spin_unlock_bh(&rreq->lock);
		spin_unlock(&rreq->lock);

		netfs_stat(&netfs_n_rh_download);
		if (rreq->netfs_ops->prepare_read) {
+10 −10
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq)
	prev_donated = READ_ONCE(subreq->prev_donated);
	next_donated =  READ_ONCE(subreq->next_donated);
	if (prev_donated || next_donated) {
		spin_lock_bh(&rreq->lock);
		spin_lock(&rreq->lock);
		prev_donated = subreq->prev_donated;
		next_donated =  subreq->next_donated;
		subreq->start -= prev_donated;
@@ -157,7 +157,7 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq)
			next_donated = subreq->next_donated = 0;
		}
		trace_netfs_sreq(subreq, netfs_sreq_trace_add_donations);
		spin_unlock_bh(&rreq->lock);
		spin_unlock(&rreq->lock);
	}

	avail = subreq->transferred;
@@ -186,18 +186,18 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq)
		} else if (fpos < start) {
			excess = fend - subreq->start;

			spin_lock_bh(&rreq->lock);
			spin_lock(&rreq->lock);
			/* If we complete first on a folio split with the
			 * preceding subreq, donate to that subreq - otherwise
			 * we get the responsibility.
			 */
			if (subreq->prev_donated != prev_donated) {
				spin_unlock_bh(&rreq->lock);
				spin_unlock(&rreq->lock);
				goto donation_changed;
			}

			if (list_is_first(&subreq->rreq_link, &rreq->subrequests)) {
				spin_unlock_bh(&rreq->lock);
				spin_unlock(&rreq->lock);
				pr_err("Can't donate prior to front\n");
				goto bad;
			}
@@ -213,7 +213,7 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq)

			if (subreq->consumed >= subreq->len)
				goto remove_subreq_locked;
			spin_unlock_bh(&rreq->lock);
			spin_unlock(&rreq->lock);
		} else {
			pr_err("fpos > start\n");
			goto bad;
@@ -241,11 +241,11 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq)
	/* Donate the remaining downloaded data to one of the neighbouring
	 * subrequests.  Note that we may race with them doing the same thing.
	 */
	spin_lock_bh(&rreq->lock);
	spin_lock(&rreq->lock);

	if (subreq->prev_donated != prev_donated ||
	    subreq->next_donated != next_donated) {
		spin_unlock_bh(&rreq->lock);
		spin_unlock(&rreq->lock);
		cond_resched();
		goto donation_changed;
	}
@@ -296,11 +296,11 @@ static bool netfs_consume_read_data(struct netfs_io_subrequest *subreq)
	goto remove_subreq_locked;

remove_subreq:
	spin_lock_bh(&rreq->lock);
	spin_lock(&rreq->lock);
remove_subreq_locked:
	subreq->consumed = subreq->len;
	list_del(&subreq->rreq_link);
	spin_unlock_bh(&rreq->lock);
	spin_unlock(&rreq->lock);
	netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_consumed);
	return true;

+4 −4
Original line number Diff line number Diff line
@@ -142,12 +142,12 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
			__clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
			subreq->retry_count++;

			spin_lock_bh(&rreq->lock);
			spin_lock(&rreq->lock);
			list_add_tail(&subreq->rreq_link, &rreq->subrequests);
			subreq->prev_donated += rreq->prev_donated;
			rreq->prev_donated = 0;
			trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
			spin_unlock_bh(&rreq->lock);
			spin_unlock(&rreq->lock);

			BUG_ON(!len);

@@ -217,9 +217,9 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
		__clear_bit(NETFS_SREQ_FAILED, &subreq->flags);
		__clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
	}
	spin_lock_bh(&rreq->lock);
	spin_lock(&rreq->lock);
	list_splice_tail_init(&queue, &rreq->subrequests);
	spin_unlock_bh(&rreq->lock);
	spin_unlock(&rreq->lock);
}

/*
+2 −2
Original line number Diff line number Diff line
@@ -238,14 +238,14 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)

		cancel:
			/* Remove if completely consumed. */
			spin_lock_bh(&wreq->lock);
			spin_lock(&wreq->lock);

			remove = front;
			list_del_init(&front->rreq_link);
			front = list_first_entry_or_null(&stream->subrequests,
							 struct netfs_io_subrequest, rreq_link);
			stream->front = front;
			spin_unlock_bh(&wreq->lock);
			spin_unlock(&wreq->lock);
			netfs_put_subrequest(remove, false,
					     notes & SAW_FAILURE ?
					     netfs_sreq_trace_put_cancel :
Loading