On Tue, May 06, 2014 at 10:34:49PM +0200, Peter Zijlstra wrote: > On Thu, May 01, 2014 at 09:44:39AM +0100, Mel Gorman wrote: > > +void set_pfnblock_flags_group(struct page *page, unsigned long flags, > > + unsigned long end_bitidx, > > + unsigned long nr_flag_bits, > > + unsigned long mask) > > { > > struct zone *zone; > > unsigned long *bitmap; > > + unsigned long pfn, bitidx, word_bitidx; > > + unsigned long old_word, new_word; > > + > > + BUILD_BUG_ON(NR_PAGEBLOCK_BITS != 4); > > > > zone = page_zone(page); > > pfn = page_to_pfn(page); > > bitmap = get_pageblock_bitmap(zone, pfn); > > bitidx = pfn_to_bitidx(zone, pfn); > > + word_bitidx = bitidx / BITS_PER_LONG; > > + bitidx &= (BITS_PER_LONG-1); > > + > > VM_BUG_ON_PAGE(!zone_spans_pfn(zone, pfn), page); > > > > + bitidx += end_bitidx; > > + mask <<= (BITS_PER_LONG - bitidx - 1); > > + flags <<= (BITS_PER_LONG - bitidx - 1); > > + > > + do { > > + old_word = ACCESS_ONCE(bitmap[word_bitidx]); > > + new_word = (old_word & ~mask) | flags; > > + } while (cmpxchg(&bitmap[word_bitidx], old_word, new_word) != old_word); > > } > > You could write it like: > > word = ACCESS_ONCE(bitmap[word_bitidx]); > for (;;) { > old_word = cmpxchg(&bitmap[word_bitidx], word, (word & ~mask) | flags); > if (word == old_word); > break; > word = old_word; > } > > It has a slightly tighter loop by avoiding the read being included. Thanks, I'll use that. -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html