Re: How to signal kernel that shared library is not in use by any process anymore ?
Hi Lior thanks for your time and code example. Shachar Shemesh explained to me couple of simple things I forgotten. You can find his replies in this thread but the bottom line : I do not need to signal kernel.Kernel memory manager will discover that pages are not active ( each page have active bit) so it will use it whenever get free page request is received. And the second option is to look mapped memory for this loib /proc/pid/mapsand issue munmap () call. simple and easy. Thanks to given it a thought.Lev 08.01.2019, 05:52, "Lior Okman" : On Fri, Dec 21, 2018 at 4:21 PM Lev Olshvangwrote:Hi All,I have an executable (C++) which is the exclusive user of the some shared library that it uses only during the initialization phase.I would like to free memory used by this shared library, because I am running on embedded system.How can I achieve this?I know that dlopen() will load shared library, and hope that following dlclose() will free this lib memory. According to the dlclose (2) man page: "The function dlclose() decrements the reference count on the dynamically loaded shared object referred to by handle. If the reference count drops to zero, then the object is unloaded. All shared objects that were automatically loaded when dlopen() was invoked on the object referred to by handle are recursively closed in the same manner. A successful return from dlclose() does not guarantee that the symbols associated with handle are removed from the caller's address space. In addition to references resulting from explicit dlopen() calls, a shared object may have been implicitly loaded (and reference counted) because of dependencies in other shared objects. Only when all references have been released can the shared object be removed from the address space." 1. Still I do not know what method should be used to make dynamic linker look again into executable and resolve symbols of the newly appeared symbols ? If you are using the dlopen/dlclose functions, you are responsible for symbol resolution for symbols provided by your shared object. After you get a handle from dlopen(), you need to call dlsym() in order to get a pointer to your symbol. You can then call that symbol when you need it. 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol resolution until dlopen() will load the library? When you use dlopen() your compilation shouldn't need to resolve any symbols from your dlopen()-ed libraries. 3. Whether to compile and link executable with this library or leave unresolved symbols? You shouldn't have any unresolved symbols, nor should you link to your library during compilation. I guess the best thing is to show an example: Given the following library source (printint.c) : #include void printint(int num) { printf("Called with num=%d \n", num);} Create a shared object from it using gcc -shared -o libprintint.so printint.c Now consider the following test program (main.c) which uses printint with dlopen (removed most of the error handling for clarity here):---#include typedef void printint(int num); int main(int argc, char *argv[]) { void *handle = NULL; handle = dlopen("./libprintint.so", RTLD_LAZY); if (handle == NULL ) { // use dlerror to find out what went wrong return -1; } printint *sym = NULL; sym = (printint*)dlsym(handle, "printint"); if (sym == NULL ) { // use dlerror to find out what went wrong return -1; } sym(argc); dlclose(handle); return 0;}-- You compile this program like this: gcc main.c -ldl -o a.out You can verify that the program doesn't dynamically link to libprintint.so by running "ldd ./a.out". When you run it with libprintit.so in the same directory it will load the shared library and call the correct function. Waiting for your advises,Lev.___Linux-il mailing listLinux-il@cs.huji.ac.ilhttp://mailman.cs.huji.ac.il/mailman/listinfo/linux-il,___Kernelnewbies mailing listkernelnewb...@kernelnewbies.orghttps://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
On 05/01/2019 10:36, Lev Olshvang wrote: Since I knew that mmap needs file descriptor I assumed ( and did not checked man page) that munmap need file descriptor. That's not true either, actually. Mmap absolutely does not need a file descriptor. It only needs one if you want it to be a memory mapping of a file. Shachar ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
Shachar , you are 100%/ right ! Since I knew that mmap needs file descriptor I assumed ( and did not checked man page) that munmap need file descriptor. Great !!Thanks, Thanks, Thanks! 04.01.2019, 22:30, "Shachar Shemesh" : On 27/12/2018 15:34, Lev Olshvang wrote:Can you elaborate why I can not write new system call to unmap this memory regions, which I see in /proc/self/maps by force ?Why would you need a system call to do this? Well, obviously, you'd need a system call to do this, but why can't that system call be "munmap"? Especially since you already pointed out that you know which pages you want unmapped. This is especially true, and this is also something that people seem to miss, considering that it wasn't the kernel that mapped those pages in to begin with. Those pages were mapped by the dynamic linker. It typically resides in /lib/ld-linux.so.2 or something (/lib64/ld-linux-x86-64.so.2 for more modern platforms), and is 100% a user space function. So I'm still not sure why you insist on unmapping, but even if you do, I don't see why you'd need a new system call to do it. Shachar,___Linux-il mailing listLinux-il@cs.huji.ac.ilhttp://mailman.cs.huji.ac.il/mailman/listinfo/linux-il___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
On 27/12/2018 15:34, Lev Olshvang wrote: Can you elaborate why I can not write new system call to unmap this memory regions, which I see in /proc/self/maps by force ? Why would you need a system call to do this? Well, obviously, you'd need a system call to do this, but why can't that system call be "munmap"? Especially since you already pointed out that you know which pages you want unmapped. This is especially true, and this is also something that people seem to miss, considering that it wasn't the kernel that mapped those pages in to begin with. Those pages were mapped by the dynamic linker. It typically resides in /lib/ld-linux.so.2 or something (/lib64/ld-linux-x86-64.so.2 for more modern platforms), and is 100% a user space function. So I'm still not sure why you insist on unmapping, but even if you do, I don't see why you'd need a new system call to do it. Shachar ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
Shahar, Thank you very much.I am going to use your advise ( actually I am advising on this to other team but I will ping them until they change static mapping to dynamic in their build system) I will update the list on the results but your are absolutely correct that memory manager will do it.Every kernel text book (as I remember now) says the same. As you said text segment will be clean and memory manager will reuse pages sometime, I just not sure when it will happen, is it just last recently used page or other method, not such important. Still I have one concern with a data section of this library. I think data pages can be dirty, perhaps C++ make even use more data page dirty versus C. Can you elaborate why I can not write new system call to unmap this memory regions, which I see in /proc/self/maps by force ? Thank you again.I am relying on your and other Linux souls expertise who helped me on this issue. Lev 21.12.2018, 20:18, "Shachar Shemesh" : On 21/12/2018 16:20, Lev Olshvang wrote: Hi All, I have an executable (C++) which is the exclusive user of the some shared library that it uses only during the initialization phase. I would like to free memory used by this shared library, because I am running on embedded system. How can I achieve this? I know that dlopen() will load shared library, and hope that following dlclose() will free this lib memory. 1. Still I do not know what method should be used to make dynamic linker look again into executable and resolve symbols of the newly appeared symbols ? 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol resolution until dlopen() will load the library? 3. Whether to compile and link executable with this library or leave unresolved symbols? What you are asking for, as asked, is not possible. If you explain your use case better, we might better understand what you're trying to do. With that said, I think you should just link the library. All the text segments of the library (i.e. - code) will be loaded with a read only shared mapping. This means that if they are not used, they will be unmapped the first time memory becomes constrained. If you do not use them later on, they will simply not be loaded to memory. They will still be mapped, but will not load your embedded system's memory in any significant way. Shachar ,___Linux-il mailing listLinux-il@cs.huji.ac.ilhttp://mailman.cs.huji.ac.il/mailman/listinfo/linux-il___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
Hello Greg, Thanks for you your reply. It help me to better express my question From the application I can access /proc/self/maps and see which memory is mapped for my library I do not intend to use after application passes init phase. I would like to unmap this memory region, but since I do not have file descriptor for this so I can not do this. Only kernel can unmap this memory for me, I am willing to pass library name or address to system cal, but IMHO such system call does not exist. Should I rely on memory manager which will use reuse this pages because they will never page faulted back ? I am afraid that since this is C++ lib, some pages are modified and will not be considered clean ? Thanks again for your precious time. Perhaps somebody from the list can respond too. Thank you all Lev 21.12.2018, 18:31, "Greg KH" : > On Fri, Dec 21, 2018 at 05:20:36PM +0300, Lev Olshvang wrote: >> Hi All, >> >> I have an executable (C++) which is the exclusive user of the some shared >> library that it uses only during the initialization phase. >> >> I would like to free memory used by this shared library, because I am >> running on embedded system. >> >> How can I achieve this? >> >> I know that dlopen() will load shared library, and hope that following >> dlclose() will free this lib memory. > > That right there is how you "achieve" this, call dlclose() and all will > be fine. If your system needs the memory that was being used, it will > reclaim it from the memory that was previously being used by the library > at this point in time. > > Nothing else needs to be done. > > Have you tested this and found it not to work properly? > >> 1. Still I do not know what method should be used to make dynamic linker >> look again into executable and resolve symbols of the newly appeared symbols >> ? > > What "newly appeared symbols"? > > If you need to load the library again, call dlopen(). > >> 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol >> resolution until dlopen() will load the library? > > It will not happen until you tell it to, right? > >> 3. Whether to compile and link executable with this library or leave >> unresolved symbols? > > It sounds like you don't really know what type of problem you are trying > to solve here. > > Back up, what is the real issue you are having with the kernel at this > point in time? > > thanks, > > greg k-h ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
On 23/12/2018 09:49, Lev Olshvang wrote: Boker tov, Thanks for all of your replies that helped me to understand what question I really wanted to ask. So this is a question. I have C++ program which calls many services of third party library. This library is needed only on initialization phase of my program. Linker has resolved symbols of this library and now it is bound to executable and in a run tine this lib will be mapped will have use count > 0 while executable is in use. I would like to unmap it to release memory, but i do not know how to do it in user space. As an alternative I know that by using dynamic loader calls dlopen() .. dlclose() I can achieve the desired effect The problem that I need to add a lot of dlfind() calls, and I looked for a way dynamic loader can do it. I am not that lazy, but since the code is C++, function names are mangled and I was tring to avoid this by looking as a subject of this mail said, way to ask kernel to unmap this lib I wish we have __init attribute in a user land ! First, yes, it will have a use count of more than zero. So what? All the pages are clean, and have a file that has a copy. The kernel will gladly remove them from memory despite being mapped (unless you mlock them, that is). If, as you say, they are not used after init, then nothing will fault them and cause them to come back. I am not that lazy, It's not about being lazy. It's about opening yourself up for introducing bugs. I wouldn't do that. Assuming you're still not convinced, here's what I would do: Write your own library (liblevinit.so). Put all the calls that need to go into that other library into liblevinit.so. dlopen and dlsym lev init, call the trigger function, and then dlclose it. You now have to manage only one symbol, and Like I said above, I don't think that is necessary. If you want to be paranoid about it, however, that's what I'd do. Shachar ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
Boker tov, Thanks for all of your replies that helped me to understand what question I really wanted to ask. So this is a question. I have C++ program which calls many services of third party library.This library is needed only on initialization phase of my program. Linker has resolved symbols of this library and now it is bound to executable and in a run tinethis lib will be mapped will have use count > 0 while executable is in use.I would like to unmap it to release memory, but i do not know how to do it in user space. As an alternative I know that by using dynamic loader calls dlopen() .. dlclose() I can achieve the desired effect The problem that I need to add a lot of dlfind() calls, and I looked for a way dynamic loader can do it.I am not that lazy, but since the code is C++, function names are mangled and I was tring to avoid thisby looking as a subject of this mail said, way to ask kernel to unmap this lib I wish we have __init attribute in a user land ! Many Many Thanks again, Lev. 21.12.2018, 20:18, "Shachar Shemesh" : On 21/12/2018 16:20, Lev Olshvang wrote: Hi All, I have an executable (C++) which is the exclusive user of the some shared library that it uses only during the initialization phase. I would like to free memory used by this shared library, because I am running on embedded system. How can I achieve this? I know that dlopen() will load shared library, and hope that following dlclose() will free this lib memory. 1. Still I do not know what method should be used to make dynamic linker look again into executable and resolve symbols of the newly appeared symbols ? 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol resolution until dlopen() will load the library? 3. Whether to compile and link executable with this library or leave unresolved symbols? What you are asking for, as asked, is not possible. If you explain your use case better, we might better understand what you're trying to do. With that said, I think you should just link the library. All the text segments of the library (i.e. - code) will be loaded with a read only shared mapping. This means that if they are not used, they will be unmapped the first time memory becomes constrained. If you do not use them later on, they will simply not be loaded to memory. They will still be mapped, but will not load your embedded system's memory in any significant way. Shachar ,___Linux-il mailing listLinux-il@cs.huji.ac.ilhttp://mailman.cs.huji.ac.il/mailman/listinfo/linux-il___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
Also if we are speaking Linux, the OS in general have very aggressive caching policy. Everything is remains in cache until it it fills up or it cleaned up externally. AFAIK there's no negative effects on performance. That is not touching the programming that I know little about. BR Evgeniy. On Fri, 21 Dec 2018, 18:18 Shachar Shemesh On 21/12/2018 16:20, Lev Olshvang wrote: > > > Hi All, > > I have an executable (C++) which is the exclusive user of the some shared > library that it uses only during the initialization phase. > > I would like to free memory used by this shared library, because I am running > on embedded system. > > How can I achieve this? > > I know that dlopen() will load shared library, and hope that following > dlclose() will free this lib memory. > > 1. Still I do not know what method should be used to make dynamic linker > look again into executable and resolve symbols of the newly appeared symbols ? > 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol > resolution until dlopen() will load the library? > 3. Whether to compile and link executable with this library or leave > unresolved symbols? > > What you are asking for, as asked, is not possible. If you explain your > use case better, we might better understand what you're trying to do. > > > With that said, I think you should just link the library. > > > All the text segments of the library (i.e. - code) will be loaded with a > read only shared mapping. This means that if they are not used, they will > be unmapped the first time memory becomes constrained. If you do not use > them later on, they will simply not be loaded to memory. They will still be > mapped, but will not load your embedded system's memory in any significant > way. > > > Shachar > > ___ > Linux-il mailing list > Linux-il@cs.huji.ac.il > http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il > ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
On 21/12/2018 16:20, Lev Olshvang wrote: Hi All, I have an executable (C++) which is the exclusive user of the some shared library that it uses only during the initialization phase. I would like to free memory used by this shared library, because I am running on embedded system. How can I achieve this? I know that dlopen() will load shared library, and hope that following dlclose() will free this lib memory. 1. Still I do not know what method should be used to make dynamic linker look again into executable and resolve symbols of the newly appeared symbols ? 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol resolution until dlopen() will load the library? 3. Whether to compile and link executable with this library or leave unresolved symbols? What you are asking for, as asked, is not possible. If you explain your use case better, we might better understand what you're trying to do. With that said, I think you should just link the library. All the text segments of the library (i.e. - code) will be loaded with a read only shared mapping. This means that if they are not used, they will be unmapped the first time memory becomes constrained. If you do not use them later on, they will simply not be loaded to memory. They will still be mapped, but will not load your embedded system's memory in any significant way. Shachar ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
Re: How to signal kernel that shared library is not in use by any process anymore ?
On Fri, Dec 21, 2018 at 4:21 PM Lev Olshvang wrote: > > Hi All, > > I have an executable (C++) which is the exclusive user of the some shared > library that it uses only during the initialization phase. > > I would like to free memory used by this shared library, because I am > running on embedded system. > > How can I achieve this? > > I know that dlopen() will load shared library, and hope that following > dlclose() will free this lib memory. > According to the dlclose (2) man page: "The function dlclose() decrements the reference count on the dynamically loaded shared object referred to by handle. If the reference count drops to zero, then the object is unloaded. All shared objects that were automatically loaded when dlopen() was invoked on the object referred to by handle are recursively closed in the same manner. A successful return from dlclose() does not guarantee that the symbols associated with handle are removed from the caller's address space. In addition to references resulting from explicit dlopen() calls, a shared object may have been implicitly loaded (and reference counted) because of dependencies in other shared objects. Only when all references have been released can the shared object be removed from the address space." > 1. Still I do not know what method should be used to make dynamic linker > look again into executable and resolve symbols of the newly appeared > symbols ? > If you are using the dlopen/dlclose functions, you are responsible for symbol resolution for symbols provided by your shared object. After you get a handle from dlopen(), you need to call dlsym() in order to get a pointer to your symbol. You can then call that symbol when you need it. > 2. And how to tell the dynamic linker ld-linux.so to postpone the symbol > resolution until dlopen() will load the library? > When you use dlopen() your compilation shouldn't need to resolve any symbols from your dlopen()-ed libraries. > 3. Whether to compile and link executable with this library or leave > unresolved symbols? > You shouldn't have any unresolved symbols, nor should you link to your library during compilation. I guess the best thing is to show an example: Given the following library source (printint.c) : #include void printint(int num) { printf("Called with num=%d \n", num); } Create a shared object from it using gcc -shared -o libprintint.so printint.c Now consider the following test program (main.c) which uses printint with dlopen (removed most of the error handling for clarity here): --- #include typedef void printint(int num); int main(int argc, char *argv[]) { void *handle = NULL; handle = dlopen("./libprintint.so", RTLD_LAZY); if (handle == NULL ) { // use dlerror to find out what went wrong return -1; } printint *sym = NULL; sym = (printint*)dlsym(handle, "printint"); if (sym == NULL ) { // use dlerror to find out what went wrong return -1; } sym(argc); dlclose(handle); return 0; } -- You compile this program like this: gcc main.c -ldl -o a.out You can verify that the program doesn't dynamically link to libprintint.so by running "ldd ./a.out". When you run it with libprintit.so in the same directory it will load the shared library and call the correct function. > Waiting for your advises, > Lev. > > ___ > Linux-il mailing list > Linux-il@cs.huji.ac.il > http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il > ___ Linux-il mailing list Linux-il@cs.huji.ac.il http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il