diff --git a/mm/Kconfig b/mm/Kconfig index fe6c22bc562c..5c61895faa01 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -736,6 +736,13 @@ config DEVICE_PRIVATE memory; i.e., memory that is only accessible from the device (or group of devices). You likely also want to select HMM_MIRROR. +config MMAP_READAROUND_LIMIT + int "Limit mmap readaround upperbond" + default 0 + help + Inappropriate mmap readaround size can hurt device performance + during the sluggish situation. Add the hard upper-limit for + mmap readaround config FRAME_VECTOR bool diff --git a/mm/filemap.c b/mm/filemap.c index a40325c67251..7fdae5f71937 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2560,6 +2560,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) struct address_space *mapping = file->f_mapping; struct file *fpin = NULL; pgoff_t offset = vmf->pgoff; + unsigned int ra_pages; /* If we don't want any read-ahead, don't bother */ if (vmf->vma_flags & VM_RAND_READ) @@ -2588,10 +2589,20 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) /* * mmap read-around */ + +#if CONFIG_MMAP_READAROUND_LIMIT == 0 + ra_pages = ra->ra_pages; +#else + if (ra->ra_pages > CONFIG_MMAP_READAROUND_LIMIT) + ra_pages = CONFIG_MMAP_READAROUND_LIMIT < 0 ? 0 : CONFIG_MMAP_READAROUND_LIMIT; + else + ra_pages = ra->ra_pages; +#endif + fpin = maybe_unlock_mmap_for_io(vmf, fpin); - ra->start = max_t(long, 0, offset - ra->ra_pages / 2); - ra->size = ra->ra_pages; - ra->async_size = ra->ra_pages / 4; + ra->start = max_t(long, 0, offset - ra_pages / 2); + ra->size = ra_pages; + ra->async_size = ra_pages / 4; ra_submit(ra, mapping, file); return fpin; }