/* $NetBSD: uvm_readahead.c,v 1.16 2023/09/23 18:21:12 ad Exp $ */
/*-
* Copyright (c)2003, 2005, 2009 YAMAMOTO Takashi,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* uvm_object read-ahead
*
* TODO:
* - tune.
* - handle multiple streams.
* - find a better way to deal with PGO_LOCKED pager requests.
* (currently just ignored)
* - consider the amount of memory in the system.
* - consider the speed of the underlying device.
* - consider filesystem block size / block layout.
*/
/*
* Don't issue read-ahead if the last page of the range is already cached.
* The assumption is that since the access is sequential, the intermediate
* pages would have similar LRU stats, and hence likely to be still in cache
* too. This speeds up I/O using cache, since it avoids lookups and temporary
* allocations done by full pgo_get.
*/
struct vm_page *pg = uvm_pagelookup(uobj, trunc_page(endoff - 1));
if (pg != NULL) {
DPRINTF(("%s: off=%" PRIu64 ", sz=%zu already cached\n",
__func__, off, sz));
return endoff;
}
off = trunc_page(off);
while (off < endoff) {
const size_t chunksize = RA_IOCHUNK;
int error;
size_t donebytes;
int npages;
int orignpages;
size_t bytelen;
ra = ra_allocctx();
if (ra != NULL) {
ra->ra_flags = 0;
}
return ra;
}
/*
* uvm_ra_freectx: free a context.
*/
void
uvm_ra_freectx(struct uvm_ractx *ra)
{
KASSERT(ra != NULL);
ra_freectx(ra);
}
/*
* uvm_ra_request: update a read-ahead context and start i/o if appropriate.
*
* => called when [reqoff, reqoff+reqsize) is requested.
* => object must be locked by caller, will return locked.
*/
/*
* a request with UVM_ADV_NORMAL hint. (ie. no hint)
*
* we keep a sliding window in order to determine:
* - if the previous read-ahead was successful or not.
* - how many bytes to read-ahead.
*/
/*
* if it's the first request for this context,
* initialize context and return.
*/