On Tue, Aug 11, 2015 at 04:51:22PM +0000, Wilcox, Matthew R wrote: > The race that you're not seeing is page fault vs page fault. Two > threads each attempt to store a byte to different locations on the > same page. With a read-mutex to exclude truncates, each thread > calls ->get_block. One of the threads gets back a buffer marked > as BH_New and calls memset() to clear the page. The other thread > gets back a buffer which isn't marked as BH_New and simply inserts > the mapping, returning to userspace, which stores the byte ... > just in time for the other thread's memset() to write a zero over > the top of it. So, this is not a truncate race that the XFS MMAPLOCK solves. However, that doesn't mean that the DAX code needs to add locking to solve it. The race here is caused by block initialisation being unserialised after a ->get_block call allocates the block (which the filesystem serialises via internal locking). Hence two simultaneous ->get_block calls to the same block is guaranteed to have the DAX block initialisation race with the second ->get_block call that says the block is already allocated. IOWs, the way to handle this is to have the ->get_block call handle the block zeroing for new blocks instead of doing it after the fact in the generic DAX code where there is no fine-grained serialisation object available. By calling dax_clear_blocks() in the ->get_block callback, the filesystem can ensure that the second racing call will only make progress once the block has been fully initialised by the first call. IMO the fix is - again - to move the functionality into the filesystem where we already have the necessary exclusion in place to avoid this race condition entirely. Cheers, Dave. -- Dave Chinner david@xxxxxxxxxxxxx -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>