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?⒏?