mirror of
https://github.com/torvalds/linux.git
synced 2026-10-25 08:16:03 +01:00
netfs: Add some functions to wrap the all-queued handling
Add some helper functions to wrap the handling of the NETFS_RREQ_ALL_QUEUED flag and to insert the appropriate barriers. Also add an smb_mb__after_atomic() after the set_bit() to make sure stuff after the set_bit() in the same thread doesn't get ordered before. Signed-off-by: David Howells <dhowells@redhat.com> Link: https://patch.msgid.link/20260909072105.1663687-8-dhowells@redhat.com Reviewed-by: Paulo Alcantara <pc@manguebit.org> cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
83e8bcde6d
commit
90ce99b47c
|
|
@ -355,10 +355,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
|
|||
}
|
||||
start += slice;
|
||||
size -= slice;
|
||||
if (size <= 0) {
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
}
|
||||
if (size <= 0)
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
|
||||
if (fq) {
|
||||
/* See if the cache indicated this should be cached. */
|
||||
|
|
@ -378,8 +376,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
|
|||
} while (size > 0);
|
||||
|
||||
if (unlikely(size > 0)) {
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
netfs_wake_collector(rreq);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,10 +84,8 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
|
|||
size -= slice;
|
||||
start += slice;
|
||||
rreq->submitted += slice;
|
||||
if (size <= 0) {
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
}
|
||||
if (size <= 0)
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
|
||||
rreq->netfs_ops->issue_read(subreq);
|
||||
|
||||
|
|
@ -99,8 +97,7 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
|
|||
} while (size > 0);
|
||||
|
||||
if (unlikely(size > 0)) {
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
netfs_wake_collector(rreq);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,6 +343,26 @@ static inline bool netfs_check_subreq_in_progress(const struct netfs_io_subreque
|
|||
return test_bit_acquire(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicate that we've generated and queued all the subrequests we're going to.
|
||||
*/
|
||||
static inline void netfs_all_subreqs_queued(struct netfs_io_request *rreq)
|
||||
{
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
smp_mb__after_atomic();
|
||||
trace_netfs_rreq(rreq, netfs_rreq_trace_all_queued);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query if all subrequests are queued.
|
||||
*/
|
||||
static inline bool netfs_are_all_subreqs_queued(const struct netfs_io_request *rreq)
|
||||
{
|
||||
/* Read lists after ALL_QUEUED. */
|
||||
return test_bit_acquire(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* fscache-cache.c
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,
|
|||
need_collect = true;
|
||||
break;
|
||||
}
|
||||
if (subreq || !test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
|
||||
if (subreq || !netfs_are_all_subreqs_queued(rreq))
|
||||
done = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -491,10 +491,8 @@ bool netfs_read_collection(struct netfs_io_request *rreq)
|
|||
/* We're done when the app thread has finished posting subreqs and the
|
||||
* queue is empty.
|
||||
*/
|
||||
if (!test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
|
||||
if (!netfs_are_all_subreqs_queued(rreq))
|
||||
return false;
|
||||
smp_rmb(); /* Read ALL_QUEUED before subreq lists. */
|
||||
|
||||
if (!list_empty(&stream->subrequests))
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -158,8 +158,7 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
|
|||
return;
|
||||
|
||||
netfs_issue_write(creq, &creq->io_streams[1]);
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &creq->flags);
|
||||
netfs_all_subreqs_queued(creq);
|
||||
trace_netfs_rreq(rreq, netfs_rreq_trace_end_copy_to_cache);
|
||||
if (list_empty_careful(&creq->io_streams[1].subrequests))
|
||||
netfs_wake_collector(creq);
|
||||
|
|
|
|||
|
|
@ -113,14 +113,12 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
|
|||
goto cancel;
|
||||
}
|
||||
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
rreq->netfs_ops->issue_read(subreq);
|
||||
rreq->submitted += subreq->len;
|
||||
break;
|
||||
case NETFS_READ_FROM_CACHE:
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
|
||||
netfs_single_read_cache(rreq, subreq);
|
||||
rreq->submitted += subreq->len;
|
||||
|
|
@ -136,8 +134,7 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
|
|||
return ret;
|
||||
cancel:
|
||||
netfs_cancel_read(subreq, ret);
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
|
||||
netfs_all_subreqs_queued(rreq);
|
||||
netfs_wake_collector(rreq);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,9 +371,8 @@ bool netfs_write_collection(struct netfs_io_request *wreq)
|
|||
/* We're done when the app thread has finished posting subreqs and all
|
||||
* the queues in all the streams are empty.
|
||||
*/
|
||||
if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags))
|
||||
if (!netfs_are_all_subreqs_queued(wreq))
|
||||
return false;
|
||||
smp_rmb(); /* Read ALL_QUEUED before lists. */
|
||||
|
||||
transferred = LONG_MAX;
|
||||
for (s = 0; s < NR_IO_STREAMS; s++) {
|
||||
|
|
|
|||
|
|
@ -520,8 +520,7 @@ static void netfs_end_issue_write(struct netfs_io_request *wreq)
|
|||
{
|
||||
bool needs_poke = true;
|
||||
|
||||
smp_wmb(); /* Write subreq lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
|
||||
netfs_all_subreqs_queued(wreq);
|
||||
|
||||
for (int s = 0; s < NR_IO_STREAMS; s++) {
|
||||
struct netfs_io_stream *stream = &wreq->io_streams[s];
|
||||
|
|
@ -789,8 +788,7 @@ int netfs_writeback_single(struct address_space *mapping,
|
|||
stop:
|
||||
for (int s = 0; s < NR_IO_STREAMS; s++)
|
||||
netfs_issue_write(wreq, &wreq->io_streams[s]);
|
||||
smp_wmb(); /* Write lists before ALL_QUEUED. */
|
||||
set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
|
||||
netfs_all_subreqs_queued(wreq);
|
||||
|
||||
netfs_wake_collector(wreq);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
E_(NETFS_PGPRIV2_COPY_TO_CACHE, "2C")
|
||||
|
||||
#define netfs_rreq_traces \
|
||||
EM(netfs_rreq_trace_all_queued, "ALL-Q ") \
|
||||
EM(netfs_rreq_trace_assess, "ASSESS ") \
|
||||
EM(netfs_rreq_trace_collect, "COLLECT") \
|
||||
EM(netfs_rreq_trace_complete, "COMPLET") \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user