答复: [PATCH v2 2/2] mm: don't use compound_head() in virt_to_head_page()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

> -----邮件原件-----
> 发件人: linux-kernel-owner@xxxxxxxxxxxxxxx [mailto:linux-kernel-
> owner@xxxxxxxxxxxxxxx] 代表 Andrew Morton
> 发送时间: 2015年1月16日 9:17
> 收件人: Joonsoo Kim
> 抄送: Christoph Lameter; Pekka Enberg; David Rientjes; linux-mm@xxxxxxxxx;
> linux-kernel@xxxxxxxxxxxxxxx; Jesper Dangaard Brouer;
> rostedt@xxxxxxxxxxx; Thomas Gleixner
> 主题: Re: [PATCH v2 2/2] mm: don't use compound_head() in
> virt_to_head_page()
> 
> On Thu, 15 Jan 2015 16:40:33 +0900 Joonsoo Kim <iamjoonsoo.kim@xxxxxxx>
> wrote:
> 
> > compound_head() is implemented with assumption that there would be
> > race condition when checking tail flag. This assumption is only true
> > when we try to access arbitrary positioned struct page.
> >
> > The situation that virt_to_head_page() is called is different case.
> > We call virt_to_head_page() only in the range of allocated pages, so
> > there is no race condition on tail flag. In this case, we don't need
> > to handle race condition and we can reduce overhead slightly.
> > This patch implements compound_head_fast() which is similar with
> > compound_head() except tail flag race handling. And then,
> > virt_to_head_page() uses this optimized function to improve performance.
> >
> > I saw 1.8% win in a fast-path loop over kmem_cache_alloc/free,
> > (14.063 ns -> 13.810 ns) if target object is on tail page.
> >
> > ...
> >
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -453,6 +453,13 @@ static inline struct page *compound_head(struct
> page *page)
> >  	return page;
> >  }
> >
> > +static inline struct page *compound_head_fast(struct page *page) {
> > +	if (unlikely(PageTail(page)))
> > +		return page->first_page;
> > +	return page;
> > +}
> 
> Can we please have some code comments which let people know when they
> should and shouldn't use compound_head_fast()?  I shouldn't have to say
> this :(
> 
> >  /*
> >   * The atomic page->_mapcount, starts from -1: so that transitions
> >   * both from it and to it can be tracked, using atomic_inc_and_test
> > @@ -531,7 +538,8 @@ static inline void get_page(struct page *page)
> > static inline struct page *virt_to_head_page(const void *x)  {
> >  	struct page *page = virt_to_page(x);
> > -	return compound_head(page);
> > +
> > +	return compound_head_fast(page);
> 
> And perhaps some explanation here as to why virt_to_head_page() can
> safely use compound_head_fast().  There's an assumption here that nobody
> will be dismantling the compound page while virt_to_head_page() is in
> progress, yes?  And this assumption also holds for the calling code, because
> otherwise the virt_to_head_page() return value is kinda meaningless.

So any other places that call compound_head() could be replaced with compound_head_fast()
if we are sure that there is no race condition on tail flag?

I also think adding code comments is necessary.

Thanks.

> 
> This is tricky stuff - let's spell it out carefully.
> --
> 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/
?韬{.n???檩jg???a?旃???)钋???骅w+h?璀?y/i?⒏??⒎???Щ??m???)钋???痂?^??觥??ザ?v???O璁?f??i?⒏?



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]