Hi Reid!
Some thoughts
I was looking at lmgr/proc.c, and I see a potential integer overflow - both 
max_total_bkend_mem and result are declared as “int”, so the expression 
“max_total_bkend_mem * 1024 * 1024 - result * 1024 * 1024” could have a problem 
when max_total_bkend_mem is set to 2G or more.
                                                /*
                                                * Account for shared memory 
size and initialize
                                                * max_total_bkend_mem_bytes.
                                                */
                                                
pg_atomic_init_u64(&ProcGlobal->max_total_bkend_mem_bytes,
                                                                                
                                   max_total_bkend_mem * 1024 * 1024 - result * 
1024 * 1024);


As more of a style thing (and definitely not an error), the calling code might 
look smoother if the memory check and error handling were moved into a helper 
function, say “backend_malloc”.  For example, the following calling code

                /* Do not exceed maximum allowed memory allocation */
                if 
(exceeds_max_total_bkend_mem(Slab_CONTEXT_HDRSZ(chunksPerBlock)))
                {
                                MemoryContextStats(TopMemoryContext);
                                ereport(ERROR,
                                                                
(errcode(ERRCODE_OUT_OF_MEMORY),
                                                                errmsg("out of 
memory - exceeds max_total_backend_memory"),
                                                                
errdetail("Failed while creating memory context \"%s\".",
                                                                                
                   name)));
                }

                slab = (SlabContext *) 
malloc(Slab_CONTEXT_HDRSZ(chunksPerBlock));
              if (slab == NULL)
                          ….
Could become a single line:
    Slab = (SlabContext *) backend_malloc(Slab_CONTEXT_HDRSZ(chunksPerBlock);

Note this is a change in error handling as backend_malloc() throws memory 
errors. I think this change is already happening, as the error throws you’ve 
already added are potentially visible to callers (to be verified). It also 
could result in less informative error messages without the specifics of “while 
creating memory context”.  Still, it pulls repeated code into a single wrapper 
and might be worth considering.

I do appreciate the changes in updating the global memory counter. My 
recollection is the original version updated stats with every allocation, and 
there was something that looked like a spinlock around the update.  (My memory 
may be wrong …). The new approach eliminates contention, both by having fewer 
updates and by using atomic ops.  Excellent.

 I also have some thoughts about simplifying the atomic update logic you are 
currently using. I need to think about it a bit more and will get back to you 
later on that.


  *   John Morris




Reply via email to