[Linux-cachefs] [RFC PATCH 1/7] cifs: Transition from ->readpages() to ->readahead()
David Howells
dhowells at redhat.com
Tue Jan 25 14:57:03 UTC 2022
Matthew Wilcox <willy at infradead.org> wrote:
> On Tue, Jan 25, 2022 at 01:57:44PM +0000, David Howells wrote:
> > + while (readahead_count(ractl) - ractl->_batch_count) {
>
> You do understand that prefixing a structure member with an '_' means
> "Don't use this", right? If I could get the compiler to prevent you, I
> would.
Yes, I know. However, as previously discussed, I think that your
implementation of readahead batching doesn't work right - hence the need to
apply compensation to the values returned by the accessor functions.
Btw, I end up doing this:
for (i = 0; i < nr_pages; i++)
if (!readahead_folio(ractl))
BUG();
in patch 5. I want to create a batch, but I don't want to be given the array
of addresses of the folios as I'm going to use an xarray-class iterator.
Further, _batch_count at this point is some value related to just the last
folio and not the batch as a whole:-/
(Also, the above won't work if any folios retrieved are larger than a page)
Note that cifs_readahead() is removed in patch 7 and readahead functionality
is offloaded to netfslib, so I'm not sure it's worth spending much time on
fixing.
[I should mention that netfs_readahead() also does:
while (readahead_folio(ractl))
;
which could probably be replaced with something better that doesn't keep
taking and dropping the RCU readlock.]
Would you object if I added a function like:
static inline
unsigned int readahead_commit_batch(struct readahead_control *rac)
{
BUG_ON(rac->_batch_count > rac->_nr_pages);
rac->_nr_pages -= rac->_batch_count;
rac->_index += rac->_batch_count;
rac->_batch_count = 0;
}
It could then be called from both __readahead_folio() and __readahead_batch().
For __readahead_folio(), the duplicate setting of _batch_count should be
optimised away on the path where a folio is returned. I could then call this
from the loop in cifs before going round again.
I'd also like to consider adding something like:
static inline
void readahead_set_batch(struct readahead_control *rac)
{
unsigned int i = 0;
struct page *page;
XA_STATE(xas, &rac->mapping->i_pages, 0);
BUG_ON(rac->_batch_count > rac->_nr_pages);
rac->_nr_pages -= rac->_batch_count;
rac->_index += rac->_batch_count;
rac->_batch_count = 0;
xas_set(&xas, rac->_index);
rcu_read_lock();
xas_for_each(&xas, page, rac->_index + rac->_nr_pages - 1) {
if (xas_retry(&xas, page))
continue;
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(PageTail(page), page);
rac->_batch_count += thp_nr_pages(page);
}
rcu_read_unlock();
}
so that netfslib can use it to load all the pages it is given into a batch
without retrieving the page pointers.
David
More information about the Linux-cachefs
mailing list