On Thu, Sep 05, 2019 at 11:23:47AM -0700, Matthew Wilcox wrote: > + xas_for_each_conflict(&xas, old) { > + if (!xa_is_value(old)) > + break; > + exceptional++; > + if (shadowp) > + *shadowp = old; > + } > + if (old) { > xas_set_err(&xas, -EEXIST); > - xas_store(&xas, page); > + break; Of course, one cannot see one's own bugs until one has posted them publically. This will exit the loop with the lock held. > + } > + xas_create_range(&xas); > if (xas_error(&xas)) > goto unlock; > The stanza should read: if (old) xas_set_err(&xas, -EEXIST); xas_create_range(&xas); if (xas_error(&xas)) goto unlock; just like the corresponding stanza in mm/shmem.c. (while the xa_state is in an error condition, the xas_create_range() function will return without doing anything).