Extremely large (say > 10M) files should not be considered by readahead, because they are very often random-access. On my machine, these include the glibc locale archive and various GNOME icon caches, totalling 160M out of 300M. Files in /var/log should also be dropped (7M) since they are usually appended-to rather than opened. Doing this by manually hacking /.readahead shove 3s of boot time on my system, saving 5s instead of 2s out of 35s without readhead. (Even with this change it is hammering very heavily on the I/O and delaying all other early services such as udev by up to 20s; once readahead is done, boot is impressively fast, but perhaps more parallelism could be squeezed out).
One line patch: diff --git a/src/readahead-common.h b/src/readahead-common.h index 167df31..9547ad2 100644 --- a/src/readahead-common.h +++ b/src/readahead-common.h @@ -27,7 +27,7 @@ #include "macro.h" -#define READAHEAD_FILE_SIZE_MAX (128*1024*1024) +#define READAHEAD_FILE_SIZE_MAX (10*1024*1024) int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st); I didn't have any file between 4 and 100M, so I made the new maximum conservative.
Another idea (for rotational media) is to do two collect passes, one for basic services and one for others. This is quite easy with multiple instances of the readahead services, the first of which stops say after udev-settle finishes. This is useful because /lib/modules is often towards the end of the disk (it is installed late) but needed early.
Created attachment 51778 [details] [review] patch to read /usr last This simple hack: awk 'BEGIN{RS="\x00\x00\x00\x00\x00\x00\x00\x00"} FNR==1 {a = $0; next} !/^\/usr/ { a = a RS $0; next } { b = b $0 RS } END { sub(/\n$/, "", a); printf "%s%s", a, b }' < readahead > /.readahead cuts by 1/2 the time needed to finish udev, and saves 2-3 seconds more of boot time. Attached patch to do the same (untested).
It works! Readahead now saves 10s out of 35s!
(In reply to comment #0) > Extremely large (say > 10M) files should not be considered by readahead, > because they are very often random-access. On my machine, these include the > glibc locale archive and various GNOME icon caches, totalling 160M out of 300M. Note that systemd actually loads only those blocks of a file that have been requested during the previous boot. Normally that should mean that we do not load much more data than necessary. > Files in /var/log should also be dropped (7M) since they are usually > appended-to rather than opened. Ideally we'd just ignore all files opened for writing when collecting readahead information. Unfortunately there's no nice way to detect that in fanotify() afaik.
(In reply to comment #1) > One line patch: > > diff --git a/src/readahead-common.h b/src/readahead-common.h > index 167df31..9547ad2 100644 > --- a/src/readahead-common.h > +++ b/src/readahead-common.h > @@ -27,7 +27,7 @@ > > #include "macro.h" > > -#define READAHEAD_FILE_SIZE_MAX (128*1024*1024) > +#define READAHEAD_FILE_SIZE_MAX (10*1024*1024) > > int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st); > > > I didn't have any file between 4 and 100M, so I made the new maximum > conservative. Thanks, this one I merged.
Since we now merged everything into /usr this patch is kinda obsolete I guess. Also note thatn systemd-readahead-reply now does not run with RT privileges anymore, in order not to starve to death udev plugins like blkid which access the disk directly bypassing the FS and which we hence cannot track via fanotify. This might fix a couple of issues here anyway.
My plan was to flush the readahead cache when some .targets were completed. I still have to implement that though...
Closing for now. Feel free to reopen if there are more patches for readahead.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.