Hello,

On (03/30/16 16:12), Minchan Kim wrote:
[..]
> +static void objidx_to_page_and_offset(struct size_class *class,
> +                             struct page *first_page,
> +                             unsigned long obj_idx,
> +                             struct page **obj_page,
> +                             unsigned long *offset_in_page)
>  {
> -     unsigned long obj;
> +     int i;
> +     unsigned long offset;
> +     struct page *cursor;
> +     int nr_page;
>  
> -     if (!page) {
> -             VM_BUG_ON(obj_idx);
> -             return NULL;
> -     }
> +     offset = obj_idx * class->size;

so we already know the `offset' before we call objidx_to_page_and_offset(),
thus we can drop `struct size_class *class' and `obj_idx', and pass
`long obj_offset'  (which is `obj_idx * class->size') instead, right?

we also _may be_ can return `cursor' from the function.

static struct page *objidx_to_page_and_offset(struct page *first_page,
                                        unsigned long obj_offset,
                                        unsigned long *offset_in_page);

this can save ~20 instructions, which is not so terrible for a hot path
like obj_malloc(). what do you think?

well, seems that `unsigned long *offset_in_page' can be calculated
outside of this function too, it's basically

        *offset_in_page = (obj_idx * class->size) & ~PAGE_MASK;

so we don't need to supply it to this function, nor modify it there.
which can save ~40 instructions on my system. does this sound silly?

        -ss

> +     cursor = first_page;
> +     nr_page = offset >> PAGE_SHIFT;
>  
> -     obj = page_to_pfn(page) << OBJ_INDEX_BITS;
> -     obj |= ((obj_idx) & OBJ_INDEX_MASK);
> -     obj <<= OBJ_TAG_BITS;
> +     *offset_in_page = offset & ~PAGE_MASK;
> +
> +     for (i = 0; i < nr_page; i++)
> +             cursor = get_next_page(cursor);
>  
> -     return (void *)obj;
> +     *obj_page = cursor;
>  }

        -ss

Reply via email to