On Tue, 31 Mar 2015, Andrew Morton wrote:
> This patch doesn't really do anything. I guess nailing down the
> interface helps a bit.
Right.
> to modules. And it isn't completely obvious, because the return
> semantics are weird.
Ok.
> What's the reason for returning a partial result when ENOMEM? Some
> callers will throw away the partial result and simply fail out. If a
> caller attempts to go ahead and use the partial result then great, but
> you can bet that nobody will actually runtime test this situation, so
> the interface is an invitation for us to release partially-tested code
> into the wild.
Just rely on the fact that small allocations never fail? The caller get
all the requested objects if the function returns?
> Instead of the above, did you consider doing
>
> int __weak kmem_cache_alloc_array(struct kmem_cache *s, gfp_t flags, size_t nr,
>
> ?
>
> This way we save a level of function call and all that wrapper code in
> the allocators simply disappears.
I think we will need the auxiliary function in the common code later
because that allows the allocations to only do the allocations that
can be optimized and for the rest just fall back to the generic
implementations. There may be situations in which the optimizations wont
work. For SLUB this may be the case f.e. if debug options are enabled.
> > --- linux.orig/mm/slab.c 2015-03-30 08:48:12.923927793 -0500
> > +++ linux/mm/slab.c 2015-03-30 08:49:08.398137844 -0500
> > @@ -3401,6 +3401,17 @@ void *kmem_cache_alloc(struct kmem_cache
> > }
> > EXPORT_SYMBOL(kmem_cache_alloc);
> >
> > +void kmem_cache_free_array(struct kmem_cache *s, size_t size, void **p) {
> > + __kmem_cache_free_array(s, size, p);
> > +}
>
> Coding style is weird.
Ok. Will fix.
On Thu, 2 Apr 2015 09:25:37 -0500 (CDT) Christoph Lameter <[email protected]> wrote:
> > What's the reason for returning a partial result when ENOMEM? Some
> > callers will throw away the partial result and simply fail out. If a
> > caller attempts to go ahead and use the partial result then great, but
> > you can bet that nobody will actually runtime test this situation, so
> > the interface is an invitation for us to release partially-tested code
> > into the wild.
>
> Just rely on the fact that small allocations never fail? The caller get
> all the requested objects if the function returns?
I'd suggest the latter: either the callee successfully allocates all
the requested objects or it fails.
> > Instead of the above, did you consider doing
> >
> > int __weak kmem_cache_alloc_array(struct kmem_cache *s, gfp_t flags, size_t nr,
> >
> > ?
> >
> > This way we save a level of function call and all that wrapper code in
> > the allocators simply disappears.
>
> I think we will need the auxiliary function in the common code later
> because that allows the allocations to only do the allocations that
> can be optimized and for the rest just fall back to the generic
> implementations. There may be situations in which the optimizations wont
> work. For SLUB this may be the case f.e. if debug options are enabled.
hm, OK. The per-allocator wrappers could be made static inline in .h
if that makes sense.
With the current code, gcc should be able to convert the call into a
tailcall.
<checks>
nope.
kmem_cache_free_array:
pushq %rbp #
movq %rsp, %rbp #,
call __kmem_cache_free_array #
leave
ret
stupid gcc.
On Thu, 2 Apr 2015, Andrew Morton wrote:
> hm, OK. The per-allocator wrappers could be made static inline in .h
> if that makes sense.
The allocators will add code to the "per-allocator wrappers". Inlining
that would be bad. Basicalkly the "wrapper" is the skeleon to which
optimizations can be added while keeping the call to the generic
implementaiton if the allocator has to punt for some reason.