Re: [Mesa-dev] RFC: Memory allocation on Mesa

2020-05-11 Thread Brian Paul

On 05/11/2020 10:13 AM, Jose Fonseca wrote:

Hi,

To give everybody a bit of background context, this email comes from 
https://gitlab.freedesktop.org/mesa/mesa/-/issues/2911 .


The short story is that Gallium components (but not Mesa) used to have 
their malloc/free calls intercepted, to satisfy certain needs: 1) memory 
debugging on Windows, 2) memory accounting on embedded systems.  But 
with the unification of Gallium into Mesa, the gallium vs non-gallium 
division got blurred, leading to some mallocs being intercepted but not 
the respective frees, and vice-versa.



I admit that trying to intercept mallocs/frees for some components and 
not others is error prone.  We could get this going on again, it's 
doable, but it's possible it would keep come causing troubles, for us or 
others, over and over again.



The two needs mentioned above were mostly VMware's needs.  So I've 
reevaluated, and I /think/ that with some trickery we satisfy those two 
needs differently.  (Without wide spread source code changes.)



On the other hand, VMware is probably not the only one to have such 
needs.  In fact Vulkan spec added memory callbacks precisely with the 
same use cases as ours, as seen 
https://www.khronos.org/registry/vulkan/specs/1.2/html/chap10.html#memory-host which 
states:


/Vulkan provides applications the opportunity to perform host memory
allocations on behalf of the Vulkan implementation. If this feature
is not used, the implementation will perform its own memory
allocations. Since most memory allocations are off the critical
path, this is not meant as a performance feature. *Rather, this can
be useful for certain embedded systems, for debugging purposes (e.g.
putting a guard page after all host allocations), or for memory
allocation logging.*/


And I know there were people interested in having Mesa drivers on 
embedded devices on the past (the old Tunsten Graphics having even been 
multiple times hired to do so), and I'm pretty sure they exist again.




Therefore, rather than shying away from memory allocation abstractions 
now, I wonder if now it's not the time to actually double down on them 
and ensure we do so comprehensively throughout the whole mesa, all drivers?

*
*
After all Mesa traditionally always had MALLOC*/CALLOC*/FREE wrappers 
around malloc/free.  As so many other projects do.




More concretely, I'd like to propose that we:

  * ensure all components use MALLOC*/CALLOC*/FREE and never
malloc/calloc/free directly (unless interfacing with a 3rd party
which expects memory to be allocated/freed with malloc/free directly)
  * Perhaps consider renaming MALLOC -> _mesa_malloc etc while we're at it
  * introduce a mechanisms to quickly catch any mistaken use of
malloc/calloc/free, regardless compiler/OS used:
  o #define malloc/free/calloc as malloc_do_not_use/free_do_not_use
to trigger compilation errors, except on files which explicely
opt out of this (source files which need to interface with 3rd
party, or source files which implement the callbacks)
  o Add a cookie to MALLOC/CALLOC/FREE memory to ensure it's not
inadvertently mixed with malloc/calloc/free

The end goal is that we should be able to have a memory allocation 
abstraction which can be used for all the needs above: memory debugging, 
memory accounting, and satisfying Vulkan host memory callbacks.



Some might retort: why not just play some tricks with the linker, and 
intercept all malloc/free calls, without actually having to modify any 
source code?


Yes, that's indeed technically feasible.  And is precisely the sort of 
trick I was planing to resort to satisfy VMware needs without having to 
further modify the source code.  But for these tricks to work, it is 
absolutely /imperative/ that one statically links C++ library and STL.  
The problem being that if one doesn't then there's an imbalance: the 
malloc/free/new/delete calls done in inline code on C++ headers will be 
intercepted, where as malloc/free/new/delete calls done in code from the 
shared object which is not inlined will not, causing havoc.  This is OK 
for us VMware (we do it already for many other reasons, including 
avoiding DLL hell.)  But I doubt it will be palatable for everybody 
else, particularly Linux distros, to have everything statically linked.


So effectively, if one really wants to implement Vulkan host memory 
callbacks, the best way is to explicitly use malloc/free abstractions, 
instead of the malloc/free directly.



So before we put more time on pursuing either the "all" or "nothing" 
approaches, I'd like to get a feel for where people's preferences are.


Jose




I was tinkering with this on Friday.  My initial idea is to use an 
opt-in approach for memory tracking/debugging.  That is, where we care 
about tracking/debugging we use explicit alternates to malloc/free/etc.


malloc/free/MALLOC/CALLOC_STRUCT/etc are used in thousands of places 

Re: [Mesa-dev] RFC: Memory allocation on Mesa

2020-05-11 Thread Tamminen, Eero T
Hi,

On Mon, 2020-05-11 at 16:13 +, Jose Fonseca wrote:
> Some might retort: why not just play some tricks with the linker, and
> intercept all malloc/free calls, without actually having to modify
> any source code?
> 
> Yes, that's indeed technically feasible.  And is precisely the sort
> of trick I was planing to resort to satisfy VMware needs without
> having to further modify the source code.  But for these tricks to
> work, it is absolutely imperative that one statically links C++
> library and STL.  The problem being that if one doesn't then there's
> an imbalance: the malloc/free/new/delete calls done in inline code on
> C++ headers will be intercepted, where as malloc/free/new/delete
> calls done in code from the shared object which is not inlined will
> not, causing havoc.  This is OK for us VMware (we do it already for
> many other reasons, including avoiding DLL hell.)  But I doubt it
> will be palatable for everybody else, particularly Linux distros, to
> have everything statically linked.

Huh?

I've done a lot of resource usage analysis at former job[1], but I've
never had needed anything like that.  malloc etc all reside in a
separate shared library from Mesa, so calls to them always cross
dynamic library boundary and therefore all of them can be caught with
the dynamic linker features (LD_PRELOAD, LD_AUDIT...).

Could you be confusing this with trying to catch some Mesa specific
function, where dynamic linker can catch only calls from application to
Mesa, but not calls within Mesa library itself (as they don't cross
dynamic library boundary)?

Note: at least earlier, new & delete typically called malloc & free (in
addition to calling ctor & dtor), in which case you don't even need to
track them separately.  You see their usage directly from the
allocation callgraph.


- Eero

PS. Your XDot tool was a really nice tool for viewing those call-
graphs. :-)


[1] Linux has several ready-made tools for tracking resource
allocations (several Valgrind tools, ElectricFence, Duma etc), and we
added few more at Nokia, with main one being:
https://github.com/maemo-tools-old/sp-rtrace

(Most memorable thing was early Qt/C++ application version doing
~10(!) allocation frees while it was initializing itself, due to
redundantly creating, localizing and removing one user view.)

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] RFC: Memory allocation on Mesa

2020-05-11 Thread Timur Kristóf
On Mon, 2020-05-11 at 16:13 +, Jose Fonseca wrote:
> Some might retort: why not just play some tricks with the linker, and
> intercept all malloc/free calls, without actually having to modify
> any source code?
> 
> Yes, that's indeed technically feasible.  And is precisely the sort
> of trick I was planing to resort to satisfy VMware needs without
> having to further modify the source code.  But for these tricks to
> work, it is absolutely imperative that one statically links C++
> library and STL.  The problem being that if one doesn't then there's
> an imbalance: the malloc/free/new/delete calls done in inline code on
> C++ headers will be intercepted, where as malloc/free/new/delete
> calls  done in code from the shared object which is not inlined will
> not, causing havoc.

Wouldn't you face the same issue if you chose to wrap all calls to
malloc and free in mesa, instead of relying on the linker? Any
dynamically linked or 3rd party library, including the C++ standard
library, will have no way of knowing about our wrapped malloc and free.

Timur

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] RFC: Memory allocation on Mesa

2020-05-11 Thread Jason Ekstrand
Sorry for the top-post.

Very quick comment:  If part of your objective is to fulfill Vulkan's
requirements, we need a LOT more plumbing than just
MALLOC/CALLOC/FREE.  The Vulkan callbacks aren't set at a global level
when the driver is loaded but are provided to every call that
allocates anything and we're expected to track these sorts of
"domains" that things are allocated from.  The reality, however, is
that the moment you get into the compiler, all bets are off.  This is
also true on other drivers; I don't think anyone has plumbed the
Vulkan allocation callbacks into LLVM. :-)

--Jason

On Mon, May 11, 2020 at 11:13 AM Jose Fonseca  wrote:
>
> Hi,
>
> To give everybody a bit of background context, this email comes from 
> https://gitlab.freedesktop.org/mesa/mesa/-/issues/2911 .
>
> The short story is that Gallium components (but not Mesa) used to have their 
> malloc/free calls intercepted, to satisfy certain needs: 1) memory debugging 
> on Windows, 2) memory accounting on embedded systems.  But with the 
> unification of Gallium into Mesa, the gallium vs non-gallium division got 
> blurred, leading to some mallocs being intercepted but not the respective 
> frees, and vice-versa.
>
>
> I admit that trying to intercept mallocs/frees for some components and not 
> others is error prone.  We could get this going on again, it's doable, but 
> it's possible it would keep come causing troubles, for us or others, over and 
> over again.
>
>
> The two needs mentioned above were mostly VMware's needs.  So I've 
> reevaluated, and I think that with some trickery we satisfy those two needs 
> differently.  (Without wide spread source code changes.)
>
>
> On the other hand, VMware is probably not the only one to have such needs.  
> In fact Vulkan spec added memory callbacks precisely with the same use cases 
> as ours, as seen 
> https://www.khronos.org/registry/vulkan/specs/1.2/html/chap10.html#memory-host
>  which states:
>
> Vulkan provides applications the opportunity to perform host memory 
> allocations on behalf of the Vulkan implementation. If this feature is not 
> used, the implementation will perform its own memory allocations. Since most 
> memory allocations are off the critical path, this is not meant as a 
> performance feature. Rather, this can be useful for certain embedded systems, 
> for debugging purposes (e.g. putting a guard page after all host 
> allocations), or for memory allocation logging.
>
>
> And I know there were people interested in having Mesa drivers on embedded 
> devices on the past (the old Tunsten Graphics having even been multiple times 
> hired to do so), and I'm pretty sure they exist again.
>
>
>
> Therefore, rather than shying away from memory allocation abstractions now, I 
> wonder if now it's not the time to actually double down on them and ensure we 
> do so comprehensively throughout the whole mesa, all drivers?
>
> After all Mesa traditionally always had MALLOC*/CALLOC*/FREE wrappers around 
> malloc/free.  As so many other projects do.
>
>
>
> More concretely, I'd like to propose that we:
>
> ensure all components use MALLOC*/CALLOC*/FREE and never malloc/calloc/free 
> directly (unless interfacing with a 3rd party which expects memory to be 
> allocated/freed with malloc/free directly)
> Perhaps consider renaming MALLOC -> _mesa_malloc etc while we're at it
> introduce a mechanisms to quickly catch any mistaken use of 
> malloc/calloc/free, regardless compiler/OS used:
>
> #define malloc/free/calloc as malloc_do_not_use/free_do_not_use to trigger 
> compilation errors, except on files which explicely opt out of this (source 
> files which need to interface with 3rd party, or source files which implement 
> the callbacks)
> Add a cookie to MALLOC/CALLOC/FREE memory to ensure it's not inadvertently 
> mixed with malloc/calloc/free
>
> The end goal is that we should be able to have a memory allocation 
> abstraction which can be used for all the needs above: memory debugging, 
> memory accounting, and satisfying Vulkan host memory callbacks.
>
>
> Some might retort: why not just play some tricks with the linker, and 
> intercept all malloc/free calls, without actually having to modify any source 
> code?
>
> Yes, that's indeed technically feasible.  And is precisely the sort of trick 
> I was planing to resort to satisfy VMware needs without having to further 
> modify the source code.  But for these tricks to work, it is absolutely 
> imperative that one statically links C++ library and STL.  The problem being 
> that if one doesn't then there's an imbalance: the malloc/free/new/delete 
> calls done in inline code on C++ headers will be intercepted, where as 
> malloc/free/new/delete calls done in code from the shared object which is not 
> inlined will not, causing havoc.  This is OK for us VMware (we do it already 
> for many other reasons, including avoiding DLL hell.)  But I doubt it will be 
> palatable for everybody else, particularly Linux distros, to 

[Mesa-dev] RFC: Memory allocation on Mesa

2020-05-11 Thread Jose Fonseca
Hi,

To give everybody a bit of background context, this email comes from 
https://gitlab.freedesktop.org/mesa/mesa/-/issues/2911 .

The short story is that Gallium components (but not Mesa) used to have their 
malloc/free calls intercepted, to satisfy certain needs: 1) memory debugging on 
Windows, 2) memory accounting on embedded systems.  But with the unification of 
Gallium into Mesa, the gallium vs non-gallium division got blurred, leading to 
some mallocs being intercepted but not the respective frees, and vice-versa.


I admit that trying to intercept mallocs/frees for some components and not 
others is error prone.  We could get this going on again, it's doable, but it's 
possible it would keep come causing troubles, for us or others, over and over 
again.


The two needs mentioned above were mostly VMware's needs.  So I've reevaluated, 
and I think that with some trickery we satisfy those two needs differently.  
(Without wide spread source code changes.)


On the other hand, VMware is probably not the only one to have such needs.  In 
fact Vulkan spec added memory callbacks precisely with the same use cases as 
ours, as seen 
https://www.khronos.org/registry/vulkan/specs/1.2/html/chap10.html#memory-host 
which states:

Vulkan provides applications the opportunity to perform host memory allocations 
on behalf of the Vulkan implementation. If this feature is not used, the 
implementation will perform its own memory allocations. Since most memory 
allocations are off the critical path, this is not meant as a performance 
feature. Rather, this can be useful for certain embedded systems, for debugging 
purposes (e.g. putting a guard page after all host allocations), or for memory 
allocation logging.

And I know there were people interested in having Mesa drivers on embedded 
devices on the past (the old Tunsten Graphics having even been multiple times 
hired to do so), and I'm pretty sure they exist again.



Therefore, rather than shying away from memory allocation abstractions now, I 
wonder if now it's not the time to actually double down on them and ensure we 
do so comprehensively throughout the whole mesa, all drivers?

After all Mesa traditionally always had MALLOC*/CALLOC*/FREE wrappers around 
malloc/free.  As so many other projects do.



More concretely, I'd like to propose that we:

  *   ensure all components use MALLOC*/CALLOC*/FREE and never 
malloc/calloc/free directly (unless interfacing with a 3rd party which expects 
memory to be allocated/freed with malloc/free directly)
  *   Perhaps consider renaming MALLOC -> _mesa_malloc etc while we're at it
  *   introduce a mechanisms to quickly catch any mistaken use of 
malloc/calloc/free, regardless compiler/OS used:
 *   #define malloc/free/calloc as malloc_do_not_use/free_do_not_use to 
trigger compilation errors, except on files which explicely opt out of this 
(source files which need to interface with 3rd party, or source files which 
implement the callbacks)
 *   Add a cookie to MALLOC/CALLOC/FREE memory to ensure it's not 
inadvertently mixed with malloc/calloc/free

The end goal is that we should be able to have a memory allocation abstraction 
which can be used for all the needs above: memory debugging, memory accounting, 
and satisfying Vulkan host memory callbacks.


Some might retort: why not just play some tricks with the linker, and intercept 
all malloc/free calls, without actually having to modify any source code?

Yes, that's indeed technically feasible.  And is precisely the sort of trick I 
was planing to resort to satisfy VMware needs without having to further modify 
the source code.  But for these tricks to work, it is absolutely imperative 
that one statically links C++ library and STL.  The problem being that if one 
doesn't then there's an imbalance: the malloc/free/new/delete calls done in 
inline code on C++ headers will be intercepted, where as malloc/free/new/delete 
calls done in code from the shared object which is not inlined will not, 
causing havoc.  This is OK for us VMware (we do it already for many other 
reasons, including avoiding DLL hell.)  But I doubt it will be palatable for 
everybody else, particularly Linux distros, to have everything statically 
linked.

So effectively, if one really wants to implement Vulkan host memory callbacks, 
the best way is to explicitly use malloc/free abstractions, instead of the 
malloc/free directly.


So before we put more time on pursuing either the "all" or "nothing" 
approaches, I'd like to get a feel for where people's preferences are.

Jose

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev