Re: [PATCH 3/4] zsmalloc use zs_handle instead of void *

From: Konrad Rzeszutek Wilk
Date: Thu May 10 2012 - 13:39:46 EST


On Thu, May 10, 2012 at 01:24:36PM -0400, Nitin Gupta wrote:
> On 5/10/12 12:44 PM, Greg Kroah-Hartman wrote:
> >On Thu, May 10, 2012 at 12:29:41PM -0400, Nitin Gupta wrote:
> >>On 5/10/12 11:19 AM, Greg Kroah-Hartman wrote:
> >>>On Thu, May 10, 2012 at 10:11:27AM -0500, Seth Jennings wrote:
> >>>>On 05/10/2012 09:47 AM, Nitin Gupta wrote:
> >>>>
> >>>>>On 5/10/12 10:02 AM, Konrad Rzeszutek Wilk wrote:
> >>>>>>struct zs {
> >>>>>> void *ptr;
> >>>>>>};
> >>>>>>
> >>>>>>And pass that structure around?
> >>>>>>
> >>>>>
> >>>>>A minor problem is that we store this handle value in a radix tree node.
> >>>>>If we wrap it as a struct, then we will not be able to store it directly
> >>>>>in the node -- the node will have to point to a 'struct zs'. This will
> >>>>>unnecessarily waste sizeof(void *) for every object stored.
> >>>>
> >>>>
> >>>>I don't think so. You can use the fact that for a struct zs var,&var
> >>>>and&var->ptr are the same.
> >>>>
> >>>>For the structure above:
> >>>>
> >>>>void * zs_to_void(struct zs *p) { return p->ptr; }
> >>>>struct zs * void_to_zs(void *p) { return (struct zs *)p; }
> >>>
> >>>Do like what the rest of the kernel does and pass around *ptr and use
> >>>container_of to get 'struct zs'. Yes, they resolve to the same pointer
> >>>right now, but you shouldn't "expect" to to be the same.
> >>>
> >>>
> >>
> >>I think we can just use unsigned long as zs handle type since all we
> >>have to do is tell the user that the returned value is not a
> >>pointer. This will be less pretty than a typedef but still better
> >>than a single entry struct + container_of stuff.
> >
> >But then you are casting the thing all around just as much as you were
> >with the void *, right?
> >
> >Making this a "real" structure ensures type safety and lets the compiler
> >find the problems you accidentally create at times :)
> >
>
> If we return a 'struct zs' from zs_malloc then I cannot see how we
> are solving the original problem of storing the handle directly in a
> radix node. If we pass a struct zs we will require pointing radix
> node to this struct, wasting sizeof(void *) for every object. If
> we pass unsigned long, then this problem is solved and it also makes
> it clear that the passed value is not a pointer.

It is the same size: sizeof(struct zs) == sizeof(void *).
When you return the 'struct zs' it will be as if you are returning
a void * pointer.

>
> Its true that making it a real struct would prevent accidental casts
> to void * but due to the above problem, I think we have to stick
> with unsigned long.
>
> Thanks,
> Nitin
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/