kokoko3k / gopreload

Preloads files needed for given programs.
43 stars 7 forks source link

Run mapandlock only once #1

Closed dglava closed 9 years ago

dglava commented 9 years ago

After a recent gopreload update/reinstall I noticed a lot more output in the logs. At first I was confused, because before the update it was rather minimal; only the initial startup messages were there.

I stumbled upon a discussion on the ArchLinux AUR page, where it turns out that there was a bug which caused mapandlock not to restart after the set period. Now with the fixed behaviour, mapandlock is restarting itself as intended and printing all those messages. If I get that right, mapandlock is reloading all those resources again every time in case they were discarded from the cache for some reason?

As it turns out, the previous "buggy" behaviour worked perfectly fine for me. I use gopreload to "preload" my desktop, making the transition between the display manager and the desktop smoother. Because of that I don't really need mapandlock to run every X amount of time.

Would it be possible to add a config option to make it behave like that? As in: run only once and don't keep mapandlock restarting. My current workaround of setting the LONG_DELAY option to something ridiculously high and redirecting the output to /dev/null don't seem like an elegant solution.

kokoko3k commented 9 years ago

If you are preloading the "mybigarchive" file, and "mybigarchive" has been updated, but his name is still "mybigarchive", mapandlock will not know that, so you'll end up in having some of your ram "locked" by what "mybigarchive" was in the past, but no more. But the kernel is smart, so if a process will ask to read "mybigarchive" it will read the updated one from the disk; in fact, you'll have some useless memory wasted by mapandlock. The point of periodically restarting mapandlock is to reload files that have the same name, but changed content.

tl;dr: It is not a good idea to keep mapandlock always active with "old" content, there is a chance to waste ram.

The LONG_DELAY var is named that way because it HAS to be high. As a side note, keep in mind that reloading all of the files is NOT a time consuming operation: when mapandlock is killed, the memory is just unlocked, but the files are still in the kernel pagecache till some new data will reclaim that memory. That means that killing and immediately reloading mapandlock will just cause the kernel to reload the files from the pagecache and lock them again; is really, really FAST. Check yourself with small delays. I'd stay with your "ridiculously high" workaround, and, if is ok for you, i'd redirect the output of mapandlock to /dev/null in the code, but only when it is restarted after a long delay.

dglava commented 9 years ago

Thanks for clearing that up. I understand now that having mapandlock constantly active, without restarting, is a bad idea. But according to this:

when mapandlock is killed, the memory is just unlocked, but the files are still in the kernel pagecache till some new data will reclaim that memory.

Wouldn't exiting mapandlock (and StartPreload.sh) after the first sleep solve my "problem"? It would have achieved its goal (speeding up loading the desktop) and all the RAM would be available again if needed? If that's the case, could I just use another shell script to kill them after logging in? Of course it would be neater if gopreload had an option to exit automatically after the initial run (after the first sleep?).

if is ok for you, i'd redirect the output of mapandlock to /dev/null in the code, but only when it is restarted after a long delay.

You don't have to do that, because it's a really niche case/issue. I have also gone back to a more normal LONG_DELAY after reading your explanation.

kokoko3k commented 9 years ago

Wouldn't exiting mapandlock (and StartPreload.sh) after the first sleep solve my "problem"?

Yes, but only until another process will use that unlocked memory. Say you have 4GB of ram and watch a 4GB movie, the kernel will use almost all of the unlocked ram to buffer it for future use; that's how it works; that's the point of map-and-LOCK.

Of course it would be neater if gopreload had an option to exit automatically after the initial run (after the first sleep?).

It should be clear now that having startpreload quitting after the first run is pretty useless; it would just "move" the time needed to start your second desktop environment from the time you switch desktop to the time you start the gopreload service; also, there is no gaurantee that the files it preloads will be still in ram when you switch the desktop environment; it entirely depends on the workload.

dglava commented 9 years ago

Yes, but only until another process will use that unlocked memory.

That works for me in this case, because as soon as the desktop is loaded, I don't really care about keeping the pre-loaded stuff in cache permanently. Maybe I didn't explain it properly. Basically what I wanted was: computer starting up -> preload a few things from the desktop environment during boot (taskbar, wallpaper setter, etc) -> during login, the transition is smoother/faster now -> no need to keep it cached at this point any more (make the "locked" RAM available for other things again if needed).

Either way, I manually added a line to kill mapandlock and exit the StartPreload script at the end of the loop and it works now as intended. Sorry if this was a silly demand, but it's resolved now. :smiley: Thanks for creating this neat utility script.